<-- it will contain the leftSide part of the textfield (the bit that was already autocompleted)
function (elem, rs) {
        var rows = [];
        var ix = 0;
        var oldIndex = -1;

        var onMouseOver = function () { this.style.outline = '1px solid #ddd'; }
        var onMouseOut = function () { this.style.outline = '0'; }
        var onMouseDown = function () { p.hide(); p.onmouseselection(this.__hint, p.rs); }

        var p = {
            rs: rs,
            hide: function () {
                elem.style.visibility = 'hidden';
                //rs.hideDropDown();
            },
            refresh: function (token, array) {
                elem.style.visibility = 'hidden';
                ix = 0;
                elem.innerHTML = '';
                var vph = (window.innerHeight || document.documentElement.clientHeight);
                var rect = elem.parentNode.getBoundingClientRect();
                var distanceToTop = rect.top - 6;                        // heuristic give 6px 
                var distanceToBottom = vph - rect.bottom - 6;  // distance from the browser border.

                rows = [];
                for (var i = 0; i < array.length; i++) {

                    if (  (config.caseSensitive && array[i].indexOf(token) !== 0)
                        ||(!config.caseSensitive && array[i].toLowerCase().indexOf(token.toLowerCase()) !== 0)) { continue; }

                    var divRow = document.createElement('div');
                    divRow.className = 'item';
                    //divRow.style.color = config.color;
                    divRow.onmouseover = onMouseOver;
                    divRow.onmouseout = onMouseOut;
                    divRow.onmousedown = onMouseDown;
                    divRow.__hint = array[i];
                    divRow.innerHTML = array[i].substring(0, token.length) + '<b>' + array[i].substring(token.length) + '</b>';
                    rows.push(divRow);
                    elem.appendChild(divRow);
                }
                if (rows.length === 0) {
                    return; // nothing to show.
                }
                if (rows.length === 1 && (   (token.toLowerCase() === rows[0].__hint.toLowerCase() && !config.caseSensitive) 
                                           ||(token === rows[0].__hint && config.caseSensitive))){
                    return; // do not show the dropDown if it has only one element which matches what we have just displayed.
                }

                if (rows.length < 2) return;
                p.highlight(0);

                if (distanceToTop > distanceToBottom * 3) {        // Heuristic (only when the distance to the to top is 4 times more than distance to the bottom
                    elem.style.maxHeight = distanceToTop + 'px';  // we display the dropDown on the top of the input text
                    elem.style.top = '';
                    elem.style.bottom = '100%';
                } else {
                    elem.style.top = '100%';
                    elem.style.bottom = '';
                    elem.style.maxHeight = distanceToBottom + 'px';
                }
                elem.style.visibility = 'visible';
            },
            highlight: function (index) {
                if (oldIndex != -1 && rows[oldIndex]) {
                    rows[oldIndex].className = "item";
                }
                rows[index].className = "item hover"; 
                oldIndex = index;
            },
            move: function (step) { // moves the selection either up or down (unless it's not possible) step is either +1 or -1.
                if (elem.style.visibility === 'hidden') return ''; // nothing to move if there is no dropDown. (this happens if the user hits escape and then down or up)
                if (ix + step === -1 || ix + step === rows.length) return rows[ix].__hint; // NO CIRCULAR SCROLLING. 
                ix += step;
                p.highlight(ix);
                return rows[ix].__hint;//txtShadow.value = uRows[uIndex].__hint ;
            },
            onmouseselection: function () { } // it will be overwritten. 
        };
        return p;
    }