function editableDropDown(objectId,
			id, 
            source,
            validValues,
            forbiddenValues,
            eddParameters,
            config,
            validator,
            onChangeScript)
{
    this.m_id = id;
    JsUtility.setControlById(id, this);
    JsUtility.setControlByObjectId(objectId, this);
    
    this.registerOnChangeScript(onChangeScript);
    
    this.config(source, validValues, forbiddenValues, eddParameters, config, validator);
    
    this.m_visible = false;
    
    var _this = this;
    JsUtility.attachEvent(window, 'load', function(){_this.m_canToggle = true; _this.attachValidators();}, false);
    
    JsUtility.deleteMeOnUnload(this);
}
editableDropDown.prototype.dispose= function()
{
	if(this.m_input)
		this.m_input.ComboBox = null;
	
	this.disposeDropPanel();
    
    this.m_outerTable = null;
    this.m_textCell = null;
    this.m_dropCell = null;
    this.m_dropButton = null;
    
    this.m_input = null;
    //this.m_value = null;
}
editableDropDown.prototype.disposeDropPanel= function()
{
	if(this.m_dropPanel)
    {
        document.body.removeChild(this.m_dropPanel);
        
        if(this.m_itemsTable)
        {
			this.m_dropPanel.removeChild(this.m_itemsTable);
		
			for(var i = 0 ; i < this.m_itemsTable.rows.length; i++)
			{
				var _item = this.m_itemsTable.rows[i].cells[0];
				
				_item.m_editableDropDown = null;
			}	
		}

		if(this.m_scrollCell)
		{
			if(this.m_scrollArea)
			{
				this.m_scrollCell.removeChild(this.m_scrollArea);

				if(this.m_scrollPlaceHolder)
					this.m_scrollArea.removeChild(this.m_scrollPlaceHolder);
			}
		}
    }

    if(this.m_popUpShim)
		document.body.removeChild(this.m_popUpShim);

	this.m_scrollCell = null;
	this.m_scrollPlaceHolder = null;
	this.m_scrollArea = null;
	this.m_itemsTable = null;
    this.m_dropPanel = null;
    this.m_popUpShim = null;
    this.m_visible = false;
}
editableDropDown.prototype.registerOnChangeScript= function(onChangeScript)
{
	if(typeof(onChangeScript) != "undefined")
    {
		if(typeof(onChangeScript) == "string")
		{
			if(onChangeScript.length > 0)
			{
				var _onChangeScript = onChangeScript;
				this.onchange = function()
				{
					eval(_onChangeScript);
				};
			}
		}
		else if(typeof(onChangeScript) == "function")
			this.onchange = onChangeScript;
    }
}
editableDropDown.prototype.config= function(source, validValues, forbiddenValues, eddParameters, config, validator)
{
    this.m_notFoundItems = new Array();
    this.m_config = config;
        
    this.m_source = source;
    this.m_validValues = validValues;
    this.m_forbiddenValues = forbiddenValues;
    this.m_firstVisible = 0;
    this.m_maxElementLength = this.getMaxLength();
    this.createHashArray();
    
    this.m_dropCount = Math.min(config.dropCount, source.length);
    
    this.DropDownMode = eddParameters.charAt(0) == "1";
    this.Disabled = eddParameters.charAt(1) == "1";
    this.SuggestedMode = eddParameters.charAt(2) == "1";
    this.Required = eddParameters.charAt(3) == "1";
    this.CausesValidation = eddParameters.charAt(4) == "1";
    this.ReadOnly = eddParameters.charAt(5) == "1";
    
    this.configValidator(validator);
    
    this.MinDropPanelWidth = config.minDropPanelWidth;
    this.MaxDropPanelWidth = config.maxDropPanelWidth;

    this.NotAllowedBackgrounColor = config.notAllowedBGColor;
    this.AllowedBackgrounColor = config.allowedBGColor;
    this.NumberFormat = config.numberFormat;
    
    if(config.dropPanelCss)
        this.DropPanelCss = config.dropPanelCss;
    else this.DropPanelCss = null;
    
    if(config.listItemCss)
        this.ListItemCss = config.listItemCss;
    else this.ListItemCss = "";
    
    if(config.listItemCssHover)
        this.ListItemCssHover = config.listItemCssHover;
    else this.ListItemCssHover = "";
    
    if(config.listItemCssSelected)
		this.ListItemCssSelected = config.listItemCssSelected;
    else this.ListItemCssSelected = "";
    
    if(config.listItemCssDisabled)
        this.ListItemCssDisabled = config.listItemCssDisabled;
    else this.ListItemCssDisabled = "";
}
editableDropDown.prototype.configValidator= function(validatorCfg)
{
    this.m_validatorCfg = validatorCfg;

    if(this.CausesValidation)
    {
        var _this = this;
        
        if(validatorCfg.validationGroup != null && validatorCfg.validationGroup.length > 0)
        {
            this.m_validator = new Object();
            this.m_validator.errormessage = "";
            this.m_validator.display = "None";
            this.m_validator.validationGroup = validatorCfg.validationGroup;
            this.m_validator.validateemptytext = true;
            this.m_validator.evaluationfunction = function()
												{
													var _args = new Object(); 
													_this.isDropDownValueAllowed(_this.m_validator, _args); 
													return _args.IsValid;
												};
            this.m_validator.valId = this.m_id;
        }
        else this.m_validator = null;
        
        if(validatorCfg.postbackValidationGroup != null && validatorCfg.validationGroup != validatorCfg.postbackValidationGroup)
        {
            this.m_pbValidator = new Object();
            this.m_pbValidator.errormessage = "";
            this.m_pbValidator.display = "None";
            this.m_pbValidator.validationGroup = validatorCfg.postbackValidationGroup;
            this.m_pbValidator.validateemptytext = true;
            this.m_pbValidator.evaluationfunction = function()
													{
														var _args = new Object(); 
														_this.isDropDownValueAllowed(_this.m_pbValidator, _args); 
														return _args.IsValid;
													};
													
            this.m_pbValidator.valId = this.m_id + "pb";
        }
        else this.m_pbValidator = null;
    }
}
editableDropDown.prototype.attachValidators= function()
{
    if(this.CausesValidation)
    {
        JsUtility.updateValidator(this.m_validator, this.m_id);
        JsUtility.updateValidator(this.m_pbValidator, this.m_id + "pb");
    }
}
editableDropDown.prototype.init= function ()
{
    if(this.m_initialized)
        return;
    
    this.m_outerTable = document.getElementById(this.m_id + "_ot");
    this.m_textCell = document.getElementById(this.m_id + "_tc");
    this.m_dropCell = document.getElementById(this.m_id + "_dc");
    this.m_dropButton = document.getElementById(this.m_id + "_db");
    
    this.m_input = document.getElementById(this.m_id + "_txt");
    this.m_lastValue = this.m_input.value;
 
    this.updateControlFace();
    
    this.m_input.ComboBox = this;
    var _this = this;
    
    JsUtility.attachEvent(this.m_input, "keydown", function(e){return _this.onInputKeyDown(e);}, true);
    JsUtility.attachEvent(this.m_input, "keyup", function(e){return _this.onInputKeyUp(e);}, true);
    JsUtility.attachEvent(this.m_input, "keypress", function(e){return _this.onInputKeyPress(e);}, true);
    JsUtility.attachEvent(this.m_input, "focus", function(e){return _this.onInputFocus(e);}, true);
    JsUtility.attachEvent(this.m_input, "blur", function(e){return _this.onInputBlur(e);}, true);
    JsUtility.attachEvent(this.m_input, "change", function(e){return _this.onInputChange(e);}, true);
    JsUtility.attachEvent(this.m_input, "click", function(e){return _this.onInputClick(e);}, true);

    var _parentContainer = JsUtility.getParentByTagName(this.m_outerTable, "div");
		
	while(_parentContainer)
	{
		if(_parentContainer.m_onScrollAttachedEdd)
			break;
		
		JsUtility.attachEvent(_parentContainer, "scroll", onEddParentScroll, true);
		_parentContainer.m_onScrollAttachedEdd = true;
		_parentContainer = JsUtility.getParentByTagName(_parentContainer, "div");
	}
    
    this.updateInputBackground(false);
    this.m_initialized = true;
}
editableDropDown.prototype.reinit= function(source, validValues, forbiddenValues, eddParameters, config, validator, newValue, onChangeScript)
{
	this.registerOnChangeScript(onChangeScript);
    this.config(source, validValues, forbiddenValues, eddParameters, config, validator);
    this.attachValidators();
   
    this.m_input.value = newValue;
    this.m_lastValue = newValue;

    this.updateControlFace();
    this.updateInputBackground(false);
    
    this.hideDropDown();
    this.disposeDropPanel();
}
editableDropDown.prototype.updateControlFace= function()
{
    if(!this.DropDownMode || this.Disabled)
    {
        this.m_dropCell.style.width = "0px";
        this.m_dropButton.style.visibility = "hidden";
        this.m_dropButton.style.width = "0px";
    }
    else 
    {
		this.m_dropCell.style.width = this.m_config.dropImageWidth;
		this.m_dropButton.style.visibility = "visible";
		this.m_dropButton.style.width = this.m_config.dropImageWidth;
	}

    if(this.Disabled)
    {
        this.m_input.disabled = true;
        if(this.m_config.textCssClassDisabled != "")
             this.m_input.className = this.m_config.textCssClassDisabled;
    }
    else
    {
        this.m_input.disabled = false;
        if(this.m_config.textCssClass != "")
             this.m_input.className = this.m_config.textCssClass;
    }

    
    this.m_input.readOnly = this.ReadOnly;
}
editableDropDown.prototype.getMaxLength= function()
{
    if(!this.m_source.m_maxElementLength)
    {
        var _result = 0;

        for(var i=0; i < this.m_source.length; i++)
            _result = Math.max(_result, this.m_source[i].length);
        
        this.m_source.m_maxElementLength = _result;
        
        return _result;
    }
    else return this.m_source.m_maxElementLength;
       
}
editableDropDown.prototype.createHashArray= function()
{
    JsUtility.createHashArray(this.m_source);
}

editableDropDown.prototype.initDropDown= function()
{
    if(this.m_dropPanel == null)
    {
        var _this = this;
        
        this.m_dropPanel = document.createElement("DIV");
        document.body.appendChild(this.m_dropPanel);
        
        if(this.DropPanelCss)
            this.m_dropPanel.className = this.DropPanelCss;
            
        this.m_dropPanel.m_doNotBlur = true;
        this.m_dropPanel.style.position = "absolute";
        this.m_dropPanel.style.zIndex = "1002";
        this.m_dropPanel.style.visibility = "visible";
        this.m_dropPanel.style.left = "-5000px";
        this.m_dropPanel.style.top = "-200px";
        this.m_dropPanel.style.width = "300px";
        this.m_dropPanel.style.height = ((this.m_dropCount * 20) + 4) + "px";
        
        this.m_itemsTable = document.createElement("TABLE");
        this.m_dropPanel.appendChild(this.m_itemsTable);

        this.m_itemsTable.cellSpacing = "0";
        this.m_itemsTable.cellPadding = "0";
        this.m_itemsTable.style.width = "300px";
        //this.m_itemsTable.style.tableLayout = "fixed";
        this.m_itemsTable.m_doNotBlur = true;
        
        for(var i=0; i < this.m_dropCount; i++)
        {
            var _row = this.m_itemsTable.insertRow(0);
            var _cell = _row.insertCell(0);
            
           _cell.style.whiteSpace = "nowrap";
           _cell.style.width = "100%";
           _cell.innerHTML = "&nbsp;" + i;
           _cell.m_editableDropDown = this;
           _cell.m_index = i;
            
           JsUtility.attachEvent(_cell, "click", this.onItemClick, false);
           JsUtility.attachEvent(_cell, "mouseover", this.onItemMouseOver, false);
           JsUtility.attachEvent(_cell, "mouseout", this.onItemMouseOut, false);
        }
        
        var _firstRow = this.m_itemsTable.rows[0];
        this.m_scrollCell = _firstRow.insertCell(1);
        this.m_scrollCell.style.width = "22px";
        
        this.m_scrollCell.rowSpan = this.m_dropCount;
       
        this.m_scrollArea = document.createElement("DIV");
        this.m_scrollArea.style.overflow = "auto";
        this.m_scrollArea.style.width = "22px";
        this.m_scrollArea.style.height = (this.m_dropCount * 20) +"px";
        this.m_scrollArea.m_doNotBlur = true;
        this.m_scrollCell.appendChild(this.m_scrollArea);
        
        JsUtility.attachEvent(this.m_scrollArea, "scroll", function(e){_this.onScroll(e);}, true);
                    
        this.m_scrollPlaceHolder = document.createElement("DIV");
        this.m_scrollPlaceHolder.innerHTML = "&nbsp;";
        this.m_scrollArea.appendChild(this.m_scrollPlaceHolder);
                
	    JsUtility.attachEvent(this.m_dropPanel, "click", function(e){return _this.onDropPanelClick(e);}, false);
	    JsUtility.attachEvent(this.m_dropPanel, "mousedown", function(e){_this.onDropPanelMouseDown(e);}, false);
        
        if(document.all)
			JsUtility.attachEvent(this.m_dropPanel, "mousewheel", function(e){_this.onDropPanelMouseWheel(e);}, false);
		else JsUtility.attachEvent(this.m_dropPanel, "DOMMouseScroll", function(e){_this.onDropPanelMouseWheel(e);}, false);
        
        this.decorateScrollbar();

        JsUtility.makeElementUnselectable(this.m_dropPanel);
    }
}
editableDropDown.prototype.decorateScrollbar= function()
{
    if(this.m_source.length > this.m_dropCount)
    {
        this.m_scrollCell.style.width = "22px";
        this.m_scrollArea.style.width = "22px";
        this.m_scrollArea.style.height = this.m_scrollCell.clientHeight + "px";
        this.m_scrollPlaceHolder.style.width = "1px";
        this.m_scrollPlaceHolder.style.height = (this.m_source.length * this.m_itemsTable.rows[0].cells[0].offsetHeight) + "px";
        this.m_scrollArea.style.visibility = "visible";
        this.m_scrollPlaceHolder.style.visibility = "visible";
    }
    else
    {
        this.m_scrollCell.style.width = "0px";
        this.m_scrollArea.style.width = "0px";
        this.m_scrollArea.style.visibility = "hidden";
        this.m_scrollPlaceHolder.style.visibility = "hidden";
    }
}
editableDropDown.prototype.calculateDropPanelSize= function(setHeight)
{
    var _width = Math.max(this.m_maxElementLength * JsUtility.getUnitEx() + 30, this.m_outerTable.offsetWidth);
    _width = Math.min(_width, this.MaxDropPanelWidth);
    _width = Math.max(_width, this.MinDropPanelWidth);
    
    this.m_itemsTable.style.width = _width + "px";
    this.m_dropPanel.style.width = _width + "px";
    
    if(this.m_scrollCell)
        this.m_scrollArea.style.height = this.m_scrollCell.clientHeight + "px";
}

editableDropDown.prototype.updateItems= function(doNotUpdateScroll)
{
    for(var i = 0 ; i < this.m_itemsTable.rows.length; i++)
    {
        var _item = this.m_itemsTable.rows[i].cells[0];
        var _index = this.m_firstVisible + i;

        _item.m_index = _index;

        if(_index == this.m_selectedIndex)
        {
            if(this.ListItemCssSelected != "")
                _item.className = this.ListItemCssSelected;
        }
        else
        {
            if(this.ListItemCss != "")
                _item.className = this.ListItemCss;
        }
        
        if(_index < this.m_source.length)
            _item.innerHTML = JsUtility.htmlEncode(this.m_source[_index]);
        else _item.innerHTML = "&nbsp;";
    } 
    
    //this.decorateScrollbar();
    
    if(this.m_source.length > this.m_dropCount)
    {
//        this.m_scrollArea.style.width = (this.m_scrollArea.offsetWidth - this.m_scrollArea.clientWidth + 5) + "px";
//        this.m_scrollArea.style.height = this.m_scrollCell.offsetHeight + "px";

        if(!doNotUpdateScroll)
            this.m_scrollArea.scrollTop = (this.m_scrollArea.scrollHeight / this.m_source.length) * this.m_firstVisible;
    }

    this.m_dropPanel.style.height = this.m_itemsTable.offsetHeight + "px";
}


editableDropDown.prototype.showDropDown= function()
{	
	if(!this.DropDownMode)
		return;
		
	if(!this.m_canToggle)
		return;
	
	this.initDropDown();
	
    if(document.currentEditableDropDown && document.currentEditableDropDown.m_visible)
        document.currentEditableDropDown.hideDropDown();
  
    this.calculateDropPanelSize(false);
    var _pos = JsUtility.getElementPosition(this.m_outerTable);
        
	_pos.x = Math.max(_pos.x, _pos.x + this.m_outerTable.offsetWidth - this.m_dropPanel.offsetWidth);
	_pos.y += this.m_outerTable.offsetHeight;

	
	if(_pos.x < 0)
		_pos.x = 0;
        
	if(_pos.y < 0)
		_pos.y = 0;
	
	this.m_dropPanel.style.left = _pos.x + "px";
	this.m_dropPanel.style.top = _pos.y + "px";
	this.updateItems();
	
    this.m_popUpShim = JsUtility.showShim(this.m_popUpShim, this.m_dropPanel);
    
	document.currentEditableDropDown = this;
	this.m_visible = true;

	if(this.findMatchingItem())
	    this.highlightSelectedItem();
	else if(this.findNearestMatchingItem())
        this.getSelectedItemIntoView();
	else this.m_firstVisible = 0;
	
	this.updateItems();
	this.m_input.select();
}

editableDropDown.prototype.hideDropDown= function()
{
    if(this.m_dropPanel)
	{
	    this.m_dropPanel.style.top = "-10px";
	    this.m_dropPanel.style.left = "-5000px";
		JsUtility.hideShim(this.m_popUpShim);
		this.m_visible = false;
	}
	
	this.clearHideTimeout();
}
editableDropDown.prototype.hideDropDownWithTimeout= function()
{
    this.clearHideTimeout();
    var _comboBox = this;
    this.m_hideTimeout = window.setTimeout(function () {_comboBox.hideDropDown();}, 100);
}
editableDropDown.prototype.clearHideTimeout= function()
{
    if(this.m_hideTimeout)
    {
        window.clearTimeout(this.m_hideTimeout);
        this.m_hideTimeout = null;
    }
}
editableDropDown.prototype.blockBlurUntilTimeout= function()
{
    this.clearBlockTimeout();
    this.m_blockBlur = true;
    var _comboBox = this;
    this.m_blockBlurTimeout = window.setTimeout(function () {_comboBox.clearBlockTimeout();}, 50);
}
editableDropDown.prototype.clearBlockTimeout= function()
{
    if(this.m_blockBlurTimeout)
    {   
        window.clearTimeout(this.m_blockBlurTimeout);
        this.m_blockBlurTimeout = null;
        this.m_blockBlur = false;
    }
}
editableDropDown.prototype.toggleDropDown= function()
{
    if(this.m_visible)
        this.hideDropDown();
    else this.showDropDown();
}


editableDropDown.prototype.itemNeverFound= function(value)
{
    if(!value || value.length == 0)
        return false;
    
    var _value = value;
    
    while(true)
    {
        if(this.m_notFoundItems[_value])
            return true;
        
        if(_value.length > 1)
            _value = _value.substr(0, _value.length - 1);
        else break;
    }
    
    return false;
}


editableDropDown.prototype.findMatchingItem= function()
{
    var _text = "" + this.m_input.value;
    var _upperText = _text.toUpperCase();
    
    var _item = this.m_source.Hashtable[_upperText];
    
	if(_item != null)
	{
		this.m_selectedIndex = _item;
		return true;
	}
 
    this.m_selectedIndex = -1;
    return false;
}
editableDropDown.prototype.findNearestMatchingItem= function()
{
    var _text = "" + this.m_input.value;
    var _upperText = _text.toUpperCase();
    for(var i=0; i < this.m_source.length; i++)
    {
        var _itemText = this.m_source[i];
        var _uItemText = _itemText.toUpperCase();
        
        if(_uItemText != _upperText && _uItemText.indexOf(_upperText) == 0)
        {
            this.m_selectedIndex = i;
            return true;
        }
    }
    this.m_selectedIndex = -1;
    return false;
}

editableDropDown.prototype.updateInputBackground= function(doNotFind, isAllowed)
{
	if(this.Disabled)
	{
		this.updateBackground("#F0F0F0");
		return;
	}
	
	if(doNotFind)
    {
	    if(!isAllowed)
		    this.updateBackground(this.NotAllowedBackgrounColor);
	    else this.updateBackground(this.AllowedBackgrounColor);
    }
    else
    {
        var _validator = new Object();
        var _args = new Object();
        _args.IsValid = true;
        
        this.isDropDownValueAllowed(_validator, _args);
        
        if(_args.IsValid)
            this.updateBackground(this.AllowedBackgrounColor);
        else this.updateBackground(this.NotAllowedBackgrounColor);
    }
}

editableDropDown.prototype.updateBackground= function(color)
{
	this.m_input.style.backgroundColor = color;
	this.m_textCell.style.backgroundColor = color;
}

editableDropDown.prototype.unHighlightPrevious= function()
{
	if(this.m_highlightedItem)
		this.m_highlightedItem.unHighlight();
}
editableDropDown.prototype.setText= function(text)
{
	this.m_text = text;
	this.m_input.value = text;
	this.updateTitle();
    this.updateInputBackground(false);
}
editableDropDown.prototype.setSelectedValue= function(doNotSelect)
{
    if(this.m_selectedIndex >= 0 && this.m_selectedIndex < this.m_source.length)
    {
        this.setText(this.m_source[this.m_selectedIndex]);
        
        if(!doNotSelect)
            this.m_input.select();
    }
}

editableDropDown.prototype.unHighlightAll= function()
{
    this.updateItems();
}
editableDropDown.prototype.getSelectedItemIntoView= function()
{
    this.m_firstVisible = Math.max(0, Math.min(this.m_firstVisible, this.m_source.length - this.m_dropCount));
    
    if(this.m_selectedIndex >= 0 && this.m_selectedIndex < this.m_source.length)
    {
        if(this.m_firstVisible + this.m_dropCount > this.m_source.length)
            this.m_firstVisible = Math.max(0, this.m_source.length - this.m_dropCount);
            
        if(this.m_selectedIndex < this.m_firstVisible  || this.m_selectedIndex >= this.m_firstVisible + this.m_dropCount)
        {
            if(this.m_firstVisible < this.m_selectedIndex)
                this.m_firstVisible = Math.max(0, this.m_selectedIndex - this.m_dropCount + 1);
            else this.m_firstVisible = this.m_selectedIndex;
        }
    }
    else this.m_firstVisible = 0;
}
editableDropDown.prototype.highlightSelectedItem= function()
{   
    this.getSelectedItemIntoView();
    this.updateItems();
}

editableDropDown.prototype.canCausePostback= function()
{
    if(!this.m_config.autoPostback)
        return false;
        
    if(this.m_ignorePostbackConditions)
        return true;
        
    if(this.m_config.postbackConditions && this.m_config.postbackConditions != null && this.m_config.postbackConditions.Hashtable && this.m_config.postbackConditions.Hashtable[this.m_input.value.toUpperCase()])
    {
        if(this.m_inclusivePostbackConditions)
            return true;
        else return false;
    }
    else if(this.m_inclusivePostbackConditions)
        return false;
    else return true;
}

editableDropDown.prototype.fireChange= function(message)
{
    if(this.m_lastValue != this.m_input.value)
    {
		var _validator = new Object();
		var _args = new Object();
		_args.IsValid = true;
		
		this.isDropDownValueAllowed(_validator, _args);

		if(typeof(this.onchange) == "function")
			this.onchange();
	
	    JsUtility.invokeCallback("DropDownInputChanged", null);
		if(this.m_config && this.m_config.changeCallbackEventName)
			JsUtility.invokeCallback(this.m_config.changeCallbackEventName, null);

		this.m_lastValue = this.m_input.value;

		
		if(_args.IsValid)
		{
			if(this.canCausePostback())
			{
			    var _this = this;
			    if(this.m_config && this.m_config.postbackScript)
			        window.setTimeout(function()
									{
										eval(_this.m_config.postbackScript);
									}, 
									10);
			}
        }
    }
}
editableDropDown.prototype.isDropDownValueAllowed = function(validator, args)
{
	args.IsValid = true;
	validator.errormessage = null;
	
	this.isDropDownValueAllowedInternal(validator, args);
	this.m_isValid = args.IsValid;
	this.m_lastError = validator.errormessage;
}
editableDropDown.prototype.isDropDownValueAllowedInternal = function(validator, args)
{
    if(!this.CausesValidation)
    {
        args.IsValid = true;
        return;
    }
    
    var _value = ValidatorTrim(this.m_input.value);
    var _emptyValue = _value == null || _value.length == 0;
    
    if(this.Required)
        if(_emptyValue)
        {
            args.IsValid = false;
            validator.errormessage = this.m_validatorCfg.requiredValidatorErrorMessage;
            return;
        }
    
    
    if(!_emptyValue && this.isValueForbidden(_value))
    {
        args.IsValid = false;
        validator.errormessage = this.m_validatorCfg.forbiddenValidatorErrorMessage;
        return;
    }
    
    if(!this.SuggestedMode)
    {
		if(!_emptyValue && !this.findMatchingItem())
        {
            if(!this.isValueValid(_value))
            {
                args.IsValid = false;
                validator.errormessage = this.m_validatorCfg.suggestedValidatorErrorMessage;
                return;
            }
        }
    }
    
    if(!_emptyValue && this.isValueInvalidNumber(_value, validator))
    {
       if(!this.isValueValid(_value))
        {
            args.IsValid = false;
            validator.errormessage =  this.m_validatorCfg.numberValidatorErrorMessage;
            return;
        }
    }

    if(this.m_config && this.m_config.matchPatterns)
    {
        for(var i=0;!_emptyValue && i < this.m_config.matchPatterns.length; i++)
            if(JsUtility.isMatchTFSPattern(this.m_config.matchPatterns[i], _value))
            {
                args.IsValid = true;
                return;
            }
        
        args.IsValid = false;
        validator.errormessage = this.m_validatorCfg.matchValidatorErrorMessage;
        return;
    }
    
    args.IsValid = true;    
}
editableDropDown.prototype.isValueValid= function(value)
{
    if(typeof(this.m_validValues) == "undefined" || this.m_validValues == null)
        return false;
    
    if(typeof(this.m_validValues.Hashtable) == "undefined" || this.m_validValues.Hashtable == null)
        return false;
    
    var _val = this.m_validValues.Hashtable[value.toUpperCase()];

    return (typeof(_val) != "undefined") && _val != null;
}
editableDropDown.prototype.isValueInvalidNumber= function(value, validator)
{
    var _matches = null;
    
    switch(this.NumberFormat)
    {
        case "WholeNumbers":
            _matches = /^(\d+)$/.exec(value);
            break;
        case "SignedWholeNumbers":
            _matches = /^[-\+]?(\d+)$/.exec(value);
            break;
        case "DecimalNumbers":
            _matches = new RegExp("^(\\d*)\\" + this.m_config.decimalChar + "?(\\d*)$").exec(value);
            break;
        case "SignedDecimalNumbers":
            _matches = new RegExp("^[-\\+]?(\\d*)\\" + this.m_config.decimalChar + "?(\\d*)$").exec(value);
            break;
        default:
            return false;
    }
    
    return _matches == null || _matches[0] != value;
}
editableDropDown.prototype.isValueForbidden= function(value)
{
    if(typeof(this.m_forbiddenValues) == "undefined" || this.m_forbiddenValues == null)
        return false;
    
    if(typeof(this.m_forbiddenValues.Hashtable) == "undefined" || this.m_forbiddenValues.Hashtable == null)
        return false;
    
    var _val = this.m_forbiddenValues.Hashtable[value.toUpperCase()];

    return (typeof(_val) != "undefined") && _val != null;
}
editableDropDown.prototype.getValue= function()
{
    return this.m_input.value;
}
editableDropDown.prototype.setValue= function(value)
{
    this.m_input.value = value;
}
editableDropDown.prototype.selectValue= function(value)
{
    this.m_input.value = value;
}
editableDropDown.prototype.setEnabled= function(enabled)
{
    this.Disabled = !enabled;
    this.updateControlFace();
}

editableDropDown.prototype.getEnabled= function()
{
    return !this.Disabled;
}
editableDropDown.prototype.updateTitle= function(title)
{
    title = title ? title : ("" + this.m_input.value);
    
    var _validator = new Object();
	var _args = new Object();
	_args.IsValid = true;
		
	this.isDropDownValueAllowed(_validator, _args);
		
	if(!_args.IsValid)
	{
		title += "\r\nError:" + _validator.errormessage
	}
    
    this.m_input.title = title;
    this.m_textCell.title = title;
}
editableDropDown.prototype.setSyncRoot= function(value)
{
    this.m_syncRoot = value;
}
editableDropDown.prototype.decSyncRoot= function()
{
    if(typeof(this.m_syncRoot) == "number")
        this.m_syncRoot-=1;
    else this.m_syncRoot = 0;
}
editableDropDown.prototype.isInSync= function()
{
    if(typeof(this.m_syncRoot) == "number")
        return this.m_syncRoot <= 0;
    
    return true;
}
editableDropDown.prototype.clearReinitInterval= function()
{
    if(typeof(this.m_reinitIntervalID) != "undefined" && this.m_reinitIntervalID != null)
    {
        window.clearInterval(this.m_reinitIntervalID); 
        this.m_reinitIntervalID=null;
    }
} 


editableDropDown.prototype.onInputKeyPress= function(e)
{
	if(!e)
       e = window.event;
       
    if(!e)
    {
		JsUtility.preventDefault();
		return false;
	}
    
    var _keyCode = e.keyCode;
    
    if(_keyCode == JsUtility.VK_ENTER)
	{
		JsUtility.preventDefault();
		return false;
	}
	
	
	if(this.NumberFormat != "None")
	{
	    var _currentText = this.m_input.value;
	    var _currentLength = _currentText.length;
	    var _selStart = -1;
	    var _selEnd = -1;

	    if(document.selection)
        {
            var _rangeSelection = document.selection.createRange();
            var _inputRange = this.m_input.createTextRange();
            
            _inputRange.moveToBookmark(_rangeSelection.getBookmark());
            _inputRange.moveEnd('character', _currentLength);
          
            _selStart = _currentLength - _inputRange.text.length;
            _selEnd = _selStart + _rangeSelection.text.length;
        }
        else
        {
            _selStart = this.m_input.selectionStart;
            _selEnd = this.m_input.selectionEnd;
        }
        
        var _selLength = _selEnd - _selStart;
        
        if(_selLength > 0)
        {
            _currentText = _currentText.substring(0, _selStart) + _currentText.substring(_selEnd, _currentLength);    
        }
        
	    var _allowedKeys = "0123456789";
        switch(this.NumberFormat)
	    {
	        case "WholeNumbers":
	            break;
	        case "SignedWholeNumbers":
	            if(_currentText.indexOf("-") < 0 && _currentText.indexOf("+") < 0 && _selStart == 0)
	                _allowedKeys += "-+";
	            else if((_currentText.indexOf("-") >= 0 || _currentText.indexOf("+") >= 0) && _selStart == 0)
	                _allowedKeys = "";
	            break;
	        case "DecimalNumbers":
	            if(_currentText.indexOf(this.m_config.decimalChar) < 0)
	                _allowedKeys += this.m_config.decimalChar;
	            break;
	        case "SignedDecimalNumbers":
	            if(_currentText.indexOf(this.m_config.decimalChar) < 0)
	                _allowedKeys += this.m_config.decimalChar;

	            if(_currentText.indexOf("-") < 0 && _currentText.indexOf("+") < 0 && _selStart == 0)
	                _allowedKeys += "-+";
	            else if((_currentText.indexOf("-") >= 0 || _currentText.indexOf("+") >= 0) && _selStart == 0)
	                _allowedKeys = "";
	            break;
	        default:
	            _allowedKeys = null;
	    }
	    
	    if(_allowedKeys != null)
	    {
            for(var i=0; i < _allowedKeys.length; i++)
            {
                if(_keyCode == _allowedKeys.charCodeAt(i))
                    return true;
            }
            
            JsUtility.preventDefault();
            return false;
	    }	
	}
	
    return true;
}
editableDropDown.prototype.onInputKeyDown= function(e)
{
    if(!e)
        e = window.event;
  
    var _delta = 1;
    var _keyCode = document.all ? e.keyCode : e.which;
    
    switch(_keyCode)
    {
        case JsUtility.VK_PAGE_DOWN:
            _delta = Math.max(1, this.m_dropCount-1);
        case JsUtility.VK_DOWN_ARROW:
            if(e.altKey && !this.m_visible)
            {
                this.showDropDown();
                return true;
            }
            
            if(!this.findMatchingItem())
            {
                if(this.m_input.value.length > 0)
                    this.findNearestMatchingItem();
                
                if(this.m_selectedIndex < 0)
                { 
                    if(this.m_source.length > 0)
                        this.m_selectedIndex = 0;
                    else return true;
                }
            }
            else this.m_selectedIndex = Math.min(this.m_selectedIndex + _delta, this.m_source.length-1);
            
            if(this.m_visible)
                this.highlightSelectedItem();
            
            this.setSelectedValue(); 
            break;
        case JsUtility.VK_PAGE_UP:
            _delta = Math.max(1, this.m_dropCount);            
        case JsUtility.VK_UP_ARROW:
            if(e.altKey && !this.m_visible)
            {
                this.showDropDown();
                return true;
            }

            if(!this.findMatchingItem())
            {
                if(this.m_input.value.length > 0)
                    this.findNearestMatchingItem();
                    
                if(this.m_selectedIndex < 0)
                {
                    if(this.m_source.length > 0)
                        this.m_selectedIndex = 0;
                    else return true;
                }
            }
            else this.m_selectedIndex = Math.max(this.m_selectedIndex - _delta, 0);
            
            if(this.m_visible)
                this.highlightSelectedItem();

            this.setSelectedValue();
            break;
        case JsUtility.VK_ENTER:
			if(!document.all)
				JsUtility.setAccidentalEnter(true);
            if(this.findMatchingItem())
                this.setSelectedValue();
            this.hideDropDown();
            JsUtility.preventDefault(e);
            this.fireChange("enter key");
            if(!document.all)
				window.setTimeout(function(){JsUtility.setAccidentalEnter(false);}, 500);
            return false;
            break;
        case JsUtility.VK_ESCAPE:
            this.hideDropDown();
            break;
        default:
            break;
    }
    
    return true;
}

editableDropDown.prototype.onInputKeyUp= function(e)
{
    if(!e)
        e = window.event;
    
    var _keyCode = document.all ? e.keyCode : e.which;
    
    if(_keyCode < 47 && _keyCode != 32)
    {
        this.updateInputBackground(false);
        return;
    }

    var _text = this.m_input.value;
    var _upperText = _text.toUpperCase();
    var _matching = false;
    this.m_selectedIndex = -1;
    
    if(!this.itemNeverFound(_upperText))
    {
        for(var i=0; i < this.m_source.length; i++)
        {
            var _itemText = this.m_source[i];
            var _uItemText = _itemText.toUpperCase();
            
            if(_uItemText != _upperText && _uItemText.indexOf(_upperText) == 0)
            {
                _matching = true;
                this.m_input.value = _text + _itemText.substr(_text.length);
                this.updateTitle();
                
                if(document.all)
                {
                    var _range = this.m_input.createTextRange();
                    _range.moveStart("character", _text.length);
                    _range.select();
                }
                else this.m_input.setSelectionRange(_text.length, this.m_input.value.length);
                
                this.m_selectedIndex = i;
                if(this.m_visible)
                    this.highlightSelectedItem();
                break;
            }
            else if(_uItemText == _upperText)
            {
                _matching = true;
                this.m_selectedIndex = i;
                
                if(this.m_visible)
                    this.highlightSelectedItem();
                break;
            }
        }
    
        if(!_matching)
            this.m_notFoundItems[_upperText] = true;
    }
    
    this.updateTitle();
    this.updateInputBackground(false);
    
    if(!_matching && this.m_visible)
    {
        this.m_dropPanel.scrollTop = 0;
        this.unHighlightAll();
    }
}

editableDropDown.prototype.onInputFocus= function(e)
{
}
editableDropDown.prototype.onInputBlur= function(e)
{
   if(!e)
        e = window.event;
   
    if(this.m_blockBlur)
    {
        this.m_input.focus();
        return;
    }

    if(document.activeElement && document.activeElement.m_doNotBlur)
    {
        this.m_input.focus();
        return;
    }

    //this.m_value.value = null;
    
    if(this.findMatchingItem())
        this.setSelectedValue(true);

    if(this.m_visible)
        this.hideDropDownWithTimeout();
    
    this.fireChange("on blur");
}
editableDropDown.prototype.onInputChange= function(e)
{
    if(!e)
        e = window.event;
   
    this.updateInputBackground(false);
    this.updateTitle();
}
editableDropDown.prototype.onInputClick= function(e)
{
	if(!e)
		e = window.event;
   
	if(e && e.ctrlKey)
		this.toggleDropDown();
}
editableDropDown.prototype.onScroll= function(e)
{
    var _ratio = this.m_source.length / this.m_scrollArea.scrollHeight;
    this.m_firstVisible = Math.round(_ratio * this.m_scrollArea.scrollTop);
    
    this.m_firstVisible = Math.min(this.m_firstVisible, this.m_source.length - this.m_dropCount);
    this.m_firstVisible = Math.max(this.m_firstVisible, 0);
    this.updateItems(true);
}
editableDropDown.prototype.onItemClick = function(e)
{
	if(!e)
		e = window.event;
	var _srcElement = JsUtility.getEventTarget(e);
	if(_srcElement && _srcElement.m_editableDropDown)
    {
		_srcElement.m_editableDropDown.m_selectedIndex = _srcElement.m_index;
		_srcElement.m_editableDropDown.hideDropDown();
		_srcElement.m_editableDropDown.setSelectedValue();
		_srcElement.m_editableDropDown.fireChange("onItemClick");
	    
	    JsUtility.stopPropagation(e);
	}
}
editableDropDown.prototype.onItemMouseOver = function(e)
{
	var _srcElement = JsUtility.getEventTarget(e);
	if(_srcElement && _srcElement.m_editableDropDown && _srcElement.m_editableDropDown.ListItemCssHover != "" && _srcElement.className != _srcElement.m_editableDropDown.ListItemCssSelected)
	{
		_srcElement.className = _srcElement.m_editableDropDown.ListItemCssHover;
	}
}
editableDropDown.prototype.onItemMouseOut = function(e)
{
	var _srcElement = JsUtility.getEventTarget(e);
	if(_srcElement && _srcElement.m_editableDropDown && _srcElement.m_editableDropDown.ListItemCss != "" && _srcElement.className != _srcElement.m_editableDropDown.ListItemCssSelected)
	{
		_srcElement.className = _srcElement.m_editableDropDown.ListItemCss;
	}
}

editableDropDown.prototype.onDropPanelSelectStart= function(e)
{
    return false;
}
editableDropDown.prototype.onDropPanelClick= function(e)
{
    this.clearHideTimeout();
    this.m_input.focus();
}
editableDropDown.prototype.onDropPanelMouseDown= function(e)
{
    this.blockBlurUntilTimeout();
}
editableDropDown.prototype.onDropPanelMouseWheel= function(e)
{
    if(!e)
        e = event;
    var _delta = 0;
    
    if(e)
    {
		if(e.wheelDelta) 
		{ /* IE/Opera. */
          _delta = event.wheelDelta/120;
          /** In Opera 9, delta differs in sign as compared to IE.
          */
          if(window.opera)
			_delta = -delta;
        } 
        else if(e.detail) 
        {		/** Mozilla case. */
                /** In Mozilla, sign of delta is different than in IE.
                 * Also, delta is multiple of 3.
                 */
                _delta = -e.detail/3;
        }

		if(_delta != 0)
		{
			if(_delta > 0)
				this.m_firstVisible = Math.max(this.m_firstVisible - this.m_dropCount + 1, 0);
			else this.m_firstVisible = Math.min(this.m_firstVisible + this.m_dropCount - 1, this.m_source.length - this.m_dropCount);
	        
			this.updateItems();
	        
			e.returnValue = false;
			JsUtility.preventDefault(e);
	            
			return false;
        }
    }
}

editableDropDown.prototype.isValid= function()
{
	var _args = new Object();
	_args.IsValid = true;
	this.isDropDownValueAllowed(this.m_validator, _args); 
	return _args.IsValid;
}

function onEddParentScroll()
{
	try
	{
		if(document.currentEditableDropDown && document.currentEditableDropDown.m_visible)
			document.currentEditableDropDown.hideDropDown();
    }
    catch(ex)
    {
		alert(ex.message);
    }
}
