function AutoSuggestControl(oTextbox /*:HTMLInputElement*/, oProvider /*:SuggestionProvider*/, oControl, oMode, which ) {
    this.mode = oMode;
    this.which = which;
    this.control = oControl;
    this.cur = -1; //The currently selected suggestions.
    this.layer = null; //The dropdown list layer.
    this.provider = oProvider; //Suggestion provider for the autosuggest feature.
    this.textbox = oTextbox; //The textbox to capture.
    this.init(); //initialize the control
}
AutoSuggestControl.prototype.autosuggest = function (aSuggestions /*:Array*/, bTypeAhead /*:boolean*/) {
    if (aSuggestions.states.length > 0) //make sure there's at least one suggestion
        this.showSuggestions(aSuggestions);
    else
        this.hideSuggestions();
};
AutoSuggestControl.prototype.createDropDown = function () {
    var oThis = this;
    this.layer = document.getElementById(this.control);
    this.layer.onmousedown =
    this.layer.onmouseup =
    this.layer.onmouseover = function (oEvent) {
        oEvent = oEvent || window.event;
        oTarget = oEvent.target || oEvent.srcElement;
        if (oEvent.type == "mousedown") {
            if(oTarget.nodeName=='DIV'){
            	oThis.textbox.value = oTarget.firstChild.firstChild.nodeValue;
			}else if(oTarget.nodeName=='B'){
				oThis.textbox.value = oTarget.firstChild.nodeValue;
			}else if(oTarget.nodeName=='SPAN'){
				oThis.textbox.value = oTarget.parentNode.firstChild.firstChild.nodeValue;
			}
            oThis.hideSuggestions();
        } else if (oEvent.type == "mouseover") {
            oThis.highlightSuggestion(oTarget);
        } else {
            oThis.textbox.focus();
        }
    };
};
AutoSuggestControl.prototype.handleKeyDown = function (oEvent /*:Event*/) {
    switch(oEvent.keyCode) {
        case 38: this.previousSuggestion(); break; //up arrow
        case 40: this.nextSuggestion();  break; //down arrow
        //case 13: this.hideSuggestions(); break; //enter
        case 13:
        	this.hideSuggestions();
        	break; //enter
        case 27: this.hideSuggestions(); break; //escape
    }
};
AutoSuggestControl.prototype.handleKeyUp = function (oEvent /*:Event*/) {
    var iKeyCode = oEvent.keyCode;
    if (this.textbox.value=="") this.textbox.style.background="#f4c0ac";
    else this.textbox.style.background="white";
    if (iKeyCode == 8 || iKeyCode == 46) { //for backspace (8) and delete (46), shows suggestions without typeahead
        this.provider.requestSuggestions(this, false);
    } else if (iKeyCode < 32 || (iKeyCode >= 33 && iKeyCode < 46) || (iKeyCode >= 112 && iKeyCode <= 123)) { //make sure not to interfere with non-character keys
        //ignore
    } else { //request suggestions from the suggestion provider with typeahead
        this.provider.requestSuggestions(this, true);
    }
};
AutoSuggestControl.prototype.hideSuggestions = function () {
    this.layer.style.visibility = "hidden";
    suggestionsHidden(this.mode);
};
AutoSuggestControl.prototype.highlightSuggestion = function (oSuggestionNode) {
    for (var i=0; i < this.layer.childNodes.length; i++) {
        var oNode = this.layer.childNodes[i];
        if (oNode == oSuggestionNode || oNode == oSuggestionNode.parentNode) {
            oNode.className = "current";
            this.cur = i;
        } else if (oNode.className == "current") {
            oNode.className = "";
        }
    }
};
AutoSuggestControl.prototype.init = function () {
    var oThis = this; //save a reference to this object
    this.textbox.onkeyup = function (oEvent) { //assign the onkeyup event handler
        if (!oEvent) oEvent = window.event; //check for the proper location of the event object
        oThis.handleKeyUp(oEvent); //call the handleKeyUp() method with the event object
    };
    this.textbox.onkeydown = function (oEvent) { //assign onkeydown event handler
        if (!oEvent) oEvent = window.event; //check for the proper location of the event object
        oThis.handleKeyDown(oEvent); //call the handleKeyDown() method with the event object
    };
    this.textbox.onblur = function () { //assign onblur event handler (hides suggestions)
        oThis.hideSuggestions();
    };
    this.createDropDown(); //create the suggestions dropdown
};
AutoSuggestControl.prototype.nextSuggestion = function () {
    var cSuggestionNodes = this.layer.childNodes;
    if (cSuggestionNodes.length > 0 && this.cur < cSuggestionNodes.length-1) {
        var oNode = cSuggestionNodes[++this.cur];
        this.highlightSuggestion(oNode);
        this.textbox.value = (oNode.firstChild.nodeValue) ? oNode.firstChild.nodeValue : oNode.firstChild.firstChild.nodeValue ;
    }
};
AutoSuggestControl.prototype.previousSuggestion = function () {
    var cSuggestionNodes = this.layer.childNodes;
    if (cSuggestionNodes.length > 0 && this.cur > 0) {
        var oNode = cSuggestionNodes[--this.cur];
        this.highlightSuggestion(oNode);
        this.textbox.value = (oNode.firstChild.nodeValue) ? oNode.firstChild.nodeValue : oNode.firstChild.firstChild.nodeValue ;
    }
};
AutoSuggestControl.prototype.showSuggestions = function (aSuggestions /*:Array*/) {
    var oDiv = null;
    this.layer.innerHTML = "";  //clear contents of the layer
    for (var i=0; i < aSuggestions.states.length; i++) {
        oDiv = document.createElement("div");
        oDiv.innerHTML = '<b>' + aSuggestions.states[i] + '</b>';
        this.layer.appendChild(oDiv);
        if(i==10) break;
    }
    this.cur = -1;
    this.layer.style.visibility = "visible";
    suggestionsShow(this.mode);
};


