

var __aspxLoadFilteredItemsCallbackPrefix = "CBLF";
var __aspxCorrectFilterCallbackPrefix = "CBCF";
var __aspxDropDownNameSuffix = "_DDD";
var __aspxCalendarNameSuffix = "_C";
var __aspxListBoxNameSuffix = "_L";
var __aspxItemImageCellClassName = "dxeIIC";
ASPxClientDropDownEditBase = _aspxCreateClass(ASPxClientButtonEditBase, {
    constructor: function(name) {
        this.constructor.prototype.constructor.call(this, name);
        this.DropDown = new ASPxClientEvent();
        this.CloseUp = new ASPxClientEvent();
        
        this.ddHeightCache = __aspxInvalidDimension;
        this.ddWidthCache = __aspxInvalidDimension;
        this.mainElementWidthCache = __aspxInvalidDimension;
        this.dropDownButtonIndex = -1;
        this.droppedDown = false;
        this.ddButtonPushed = false;
        this.lastSuccessText = "";
        this.isToolbarItem = false;
        this.allowFocusDropDownWindow = false;

        aspxGetDropDownCollection().Add(this);
    },
    Initialize: function(){
        var pc = this.GetPopupControl();
        if(_aspxIsExists(pc)) {
            pc.allowCorrectYOffsetPosition = false;
            pc.dropDownEditName = this.name;
        }
        this.AssignClientAttributes();
        this.InitLastSuccessText();
        ASPxClientEdit.prototype.Initialize.call(this);
    },
    InitLastSuccessText: function(){
        var rawText = this.GetTextInternal();
        this.SetLastSuccessTest(rawText);
    },
    IsRenderExists: function(){
        return _aspxIsExistsElement(this.GetMainElement());
    },
    AssignClientAttributes: function(){
        var element = this.GetDropDownButton();
        if(_aspxIsExistsElement(element))
            _aspxPreventElementDragAndSelect(element, true);
    },
    GetDropDownButton: function(){
        return this.GetButton(this.dropDownButtonIndex);
    },
    GetPopupControl: function(){
        return aspxGetControlCollection().Get(this.name + __aspxDropDownNameSuffix);
    },
    GetDropDownInnerControlName: function(suffix){
        var pc = this.GetPopupControl();
        if(_aspxIsExists(pc))
            return this.GetPopupControl().name + suffix;
        return "";
    },
    GetDropDownItemImageCell: function() {
        return _aspxGetChildsByClassName(this.GetMainElement(), __aspxItemImageCellClassName)[0];
    },
    GetIsControlWidthWasChanged: function(){
        return this.mainElementWidthCache == __aspxInvalidDimension || this.mainElementWidthCache != this.GetMainElement().clientWidth;
    },
    GetDropDownHeight: function(){
        return 0;
    },
    GetDropDownWidth: function(){
        return 0;
    },
    GetDropDownIsWindowElement: function(id, pcPostfix) {
        var pos = id.lastIndexOf(pcPostfix);
        if(pos != -1) {
            var name = id.substring(0, pos);
            var pc = aspxGetPopupControlCollection().Get(name);
            if(_aspxIsExists(pc) && _aspxIsExists(pc.dropDownEditName))
                return aspxGetDropDownCollection().Get(pc.dropDownEditName);
        }
        return null;
    },
    GetDropDownParents: function() {
        var parents = new Array();
        var mainElement = this.GetMainElement();
        var pcPostfix = __aspxPCWIdSuffix + "-1";

        var element = mainElement.parentNode;
        while(element != null){
            if(element.tagName == "BODY")
                break;
            if(_aspxIsExists(element.id) && element.id != "") {
                var dropDown = this.GetDropDownIsWindowElement(element.id, pcPostfix);
                if(dropDown != null)
                    parents.push(dropDown);
            }
            element = element.parentNode;
        }
        return parents.reverse();
    },
    ShowDropDownArea: function(isRaiseEvent){
        aspxGetDropDownCollection().RegisterDroppedDownControl(this, this.GetDropDownParents());
		
		this.lockListBoxClick = true;
		this.lockClosing = true;
		
        var pc = this.GetPopupControl();
        var element = this.GetMainElement();
        var pcwElement = pc.GetWindowElement(-1);
        
        _aspxSetElementDisplay(pcwElement, true);
        // Order is important. Width with scroll bar depends on Height
        var height = this.GetDropDownHeight();
        var width = this.GetDropDownWidth();
        if(this.ddHeightCache != height || this.ddWidthCache != width){
            pc.SetSize(width, height);
            this.ddHeightCache = height;
            this.ddWidthCache = width;
        }
        pc.popupVerticalOffset = - _aspxGetClientTop(element);
        this.RaiseDropDownEventRequired = isRaiseEvent;
        pc.ShowAtElement(element);

        this.droppedDown = true;
        this.lockClosing = false;
    },
    HideDropDownArea: function(isRaiseEvent){
        if(this.lockClosing) return; // B38675
    
        this.DropDownButtonPop();
        var pc = this.GetPopupControl();
        if (_aspxIsExists(pc)){
            aspxGetDropDownCollection().UnregisterDroppedDownControl(this);
            pc.Hide();
            if(isRaiseEvent)
                this.RaiseCloseUp();
            this.droppedDown = false;
        }
    },
    ProcessInternalButtonClick: function(number) {
        return this.dropDownButtonIndex == number;
    },
    ToggleDropDown: function(){
        this.OnApplyChanges();
        if(this.droppedDown)
            this.HideDropDownArea(true);
        else
            this.ShowDropDownArea(true);        
    },
    GetTextInternal: function(){
        var text = ASPxClientButtonEditBase.prototype.GetValue.call(this);
        return text != null ? text : "";
    },
    SetTextInternal: function(text){
        if(!this.readOnly)
            ASPxClientButtonEditBase.prototype.SetValue.call(this, text);
    },
    SetLastSuccessTest: function(text){
        if(text == null) text = "";
        this.lastSuccessText = text;
    },
    // base events
    OnValueChanged: function() {
        this.SetLastSuccessTest(this.GetTextInternal());
        ASPxClientEdit.prototype.OnValueChanged.call(this);
    },
    
    OnApplyChanges: function(){
    },
    OnCancelChanges: function(){
        var isCancelProcessed = (this.GetTextInternal() != this.lastSuccessText);
        this.SetTextInternal(this.lastSuccessText);
        return isCancelProcessed;
    },
    OnFocus: function(){
        this.OnSetFocus(true);
        ASPxClientButtonEditBase.prototype.OnFocus.call(this);
    },
    OnLostFocus: function(){
        this.OnSetFocus(false);
        ASPxClientButtonEditBase.prototype.OnLostFocus.call(this);
    },
    OnSetFocus: function(isFocused){
        aspxGetDropDownCollection().SetFocusedDropDownName(isFocused ? this.name : "");
    },
    IsEditorElement: function(element) {
        if(ASPxClientButtonEditBase.prototype.IsEditorElement.call(this, element))
            return true;
        if(this.allowFocusDropDownWindow)
            return false;
        var pc = this.GetPopupControl();
        if(pc != null) {
            var windowElement = pc.GetWindowElement(-1);
            return windowElement == element || _aspxGetIsParent(windowElement, element);
        }
        return false;
    },

    OnPopupControlShown: function(){
        if(this.RaiseDropDownEventRequired){
            this.RaiseDropDownEventRequired = false;
            _aspxSetTimeout("aspxDDBRaiseDropDownByTimer(\"" + this.name + "\")", 0);
        }
    },
    IsCanToDropDown: function(){
        return true;
    },
    OnDropDown: function(evt) { 
        if(!this.isInitialized) 
            return true;
        if(!this.IsCanToDropDown()) {
            this.ForceRefocusEditor();
            return true;
        }

        if(__aspxIE || __aspxOpera){
            _aspxEmulateDocumentOnMouseDown(evt); 
            aspxGetStateController().ClearSavedCurrentPressedElement();
        }
        this.OnDropDownCore(evt);
        return _aspxCancelBubble(evt); // Makes the StateController to hover items without releasing DropDownButton
    },
    OnDropDownCore: function(evt) {
        if(!this.droppedDown)
            this.DropDownButtonPush();
        this.ToggleDropDown();
        this.ForceRefocusEditor();
    },
    DropDownButtonPush: function(){
        if(this.droppedDown || this.ddButtonPushed) return;
        this.ddButtonPushed = true;
        
        if(__aspxIE || __aspxOpera) 
            this.DropDownButtonPushPop(true);
        else
            this.DropDownButtonPushMozilla();
    },    
    DropDownButtonPop: function(){
        if(!this.droppedDown || !this.ddButtonPushed) return;
        this.ddButtonPushed = false;
        
        if(__aspxIE || __aspxOpera) 
            this.DropDownButtonPushPop(false);
        else
            this.DropDownButtonPopMozilla();
    },
    DropDownButtonPushPop: function(isPush){
        var buttonElement = this.GetDropDownButton();
        if(_aspxIsExists(buttonElement)){
            var controller = aspxGetStateController();
            var element = controller.GetPressedElement(buttonElement);
            if(_aspxIsExists(element)){
                if(isPush){
                    controller.SetCurrentHoverElement(null);
                    controller.DoSetPressedState(element);
                } else {
                    controller.DoClearPressedState(element);
                    controller.SetCurrentPressedElement(null);
                    controller.SetCurrentHoverElement(element);
                }
            }
        }
    },
    DropDownButtonPushMozilla: function(){
        this.DisableStyleControllerForDDButton();
        var controller = aspxGetStateController();
        controller.savedCurrentPressedElement = null;
    },
    DropDownButtonPopMozilla: function(){
        this.EnableStyleControllerForDDButton();
        var controller = aspxGetStateController();
        var buttonElement = this.GetDropDownButton();
        if(_aspxIsExists(buttonElement)){
            var element = controller.GetPressedElement(buttonElement);
            if(_aspxIsExists(element))
                controller.DoClearPressedState(element);
            controller.currentPressedElement = null;
            element = controller.GetHoverElement(buttonElement);
            if(_aspxIsExists(element))
                controller.SetCurrentHoverElement(element);
        }
    },
    EnableStyleControllerForDDButton: function(){
        var element = this.GetDropDownButton();
        if(_aspxIsExists(element)){
            var controller = aspxGetStateController();
            this.ReplaceElementControlStyleItem(controller.hoverItems, __aspxHoverItemKind, element, this.ddButtonHoverStyle);
            this.ReplaceElementControlStyleItem(controller.pressedItems, __aspxPressedItemKind, element, this.ddButtonPressedStyle);
            this.ReplaceElementControlStyleItem(controller.selectedItems, __aspxSelectedItemKind, element, this.ddButtonSelectedStyle);
        }
    },
    DisableStyleControllerForDDButton: function(){
        var element = this.GetDropDownButton();
        if(_aspxIsExists(element)){
            var controller = aspxGetStateController();
            this.ddButtonHoverStyle = this.ReplaceElementControlStyleItem(controller.hoverItems, __aspxHoverItemKind, element, null);
            this.ddButtonPressedStyle = this.ReplaceElementControlStyleItem(controller.pressedItems, __aspxPressedItemKind, element, null);
            this.ddButtonSelectedStyle = this.ReplaceElementControlStyleItem(controller.selectedItems, __aspxSelectedItemKind, element, null);
        }
    },
    ReplaceElementControlStyleItem: function(items, kind, element, newStyleItem){
        var styleItem = items[element.id];
        items[element.id] = newStyleItem;
        element[kind] = newStyleItem;
        return styleItem;
    },

    CloseDropDownByDocumentOrWindowEvent: function(){
        this.HideDropDownArea(true);
    },
    OnDocumentMouseUp: function() {
        this.DropDownButtonPop();
    },
    OnDDButtonMouseMove: function(evt){
    },
    OnCloseUp: function(evt){
        this.HideDropDownArea(true);
    },
    OnOpenAnotherDropDown: function(){
        this.HideDropDownArea(true);
    },
    OnTextChanged: function() {
        this.ParseValue();
    },
    ChangeEnabledAttributes: function(enabled){
        ASPxClientButtonEditBase.prototype.ChangeEnabledAttributes.call(this, enabled);
        var btnElement = this.GetDropDownButton();
        if(_aspxIsExists(btnElement))
            this.ChangeButtonEnabledAttributes(btnElement, _aspxChangeAttributesMethod(enabled));
        var inputElement = this.GetInputElement();
        if(_aspxIsExists(inputElement))
            this.ChangeInputCellEnabledAttributes(inputElement.parentNode, _aspxChangeAttributesMethod(enabled));
    },
    ChangeEnabledStateItems: function(enabled){
        ASPxClientButtonEditBase.prototype.ChangeEnabledStateItems.call(this, enabled);
        var btnElement = this.GetDropDownButton();
        if(_aspxIsExists(btnElement))
            aspxGetStateController().SetElementEnabled(btnElement, enabled);
    },
	ChangeInputCellEnabledAttributes: function(element, method){
        method(element, "onclick");
        method(element, "onkeyup");
        method(element, "onmousedown");
        method(element, "onmouseup");
	},
    
    // Keyboard Support
    InitializeKeyHandlers: function() {
        this.AddKeyDownHandler(ASPxKey.Enter, "OnEnter");
        this.AddKeyDownHandler(ASPxKey.Esc, "OnEscape");
        this.AddKeyDownHandler(ASPxKey.PageUp, "OnPageUp");
        this.AddKeyDownHandler(ASPxKey.PageDown, "OnPageDown");
        this.AddKeyDownHandler(ASPxKey.End, "OnEndKeyDown");
        this.AddKeyDownHandler(ASPxKey.Home, "OnHomeKeyDown");
        this.AddKeyDownHandler(ASPxKey.Left, "OnArrowLeft");
        this.AddKeyDownHandler(ASPxKey.Right, "OnArrowRight");
        this.AddKeyDownHandler(ASPxKey.Up, "OnArrowUp");
        this.AddKeyDownHandler(ASPxKey.Down, "OnArrowDown");
        this.AddKeyDownHandler(ASPxKey.Tab, "OnTab");
    },
    OnArrowUp: function(evt){
        if(evt.altKey) {
            this.ToggleDropDown();
            return true;
        }
        return false;
    },
    OnArrowDown: function(evt){
        if(evt.altKey) {
            this.ToggleDropDown();
            return true;
        }
        return false;
    },
    OnPageUp: function(evt){
        return false;
    },    
    OnPageDown: function(evt){
        return false;
    },
    OnEndKeyDown: function(evt){
        return false;
    },
    OnHomeKeyDown: function(evt){
        return false;
    },
    OnArrowLeft: function(evt){
        return false;
    },
    OnArrowRight: function(evt){
        return false;
    },
    OnEscape: function(evt){
        var isCancelProcessed = this.OnCancelChanges() || this.droppedDown;
        this.HideDropDownArea(true);
        return isCancelProcessed;
    },
    OnEnter: function(evt){
        return false;
    },
    OnTab: function(evt){
        return false;
    },
    // API
    RaiseCloseUp: function(){
        if(!this.CloseUp.IsEmpty()){
            var args = new ASPxClientEventArgs();
            this.CloseUp.FireEvent(this, args);
        }
    },
    RaiseDropDown: function(){
        if(!this.DropDown.IsEmpty() && this.isInitialized){
            var args = new ASPxClientEventArgs();
            this.DropDown.FireEvent(this, args);
        }
    },
    ShowDropDown: function(){
        this.ShowDropDownArea(false);
    },
    HideDropDown: function(){
        this.HideDropDownArea(false);
    }
});
ASPxClientDropDownEdit = _aspxCreateClass(ASPxClientDropDownEditBase, {
    constructor: function(name) {
        this.constructor.prototype.constructor.call(this, name);

        this.dropDownWindowHeight = "";
        this.dropDownWindowWidth = "";
        this.allowFocusDropDownWindow = true;
    },
    InlineInitialize: function(){
        this.InitSpecialKeyboardHandling();
        ASPxClientDropDownEditBase.prototype.InlineInitialize.call(this);
    },
    Initialize: function(){
        if(__aspxIE){ // Strange bug fix
            var clickFunc = new Function("aspxGetControlCollection().Get('" + this.name + "').ForceRefocusEditor();");
            _aspxAttachEventToElement(this.GetMainElement(), "click", clickFunc);
        }
        ASPxClientDropDownEditBase.prototype.Initialize.call(this);
    },
    GetKeyValueInputElement: function(){
        return _aspxGetElementById(this.name + "KV");
    },
    GetDropDownHeight: function(){
        if(this.dropDownWindowHeight != "")
            return this.dropDownWindowHeight;
        return ASPxClientDropDownEditBase.prototype.GetDropDownHeight.call(this);
    },
    GetDropDownWidth: function(){
        if(this.dropDownWindowWidth != "")
            return this.dropDownWindowWidth;
        return this.GetMainElement().offsetWidth;
    },
    OnEnter: function(evt){
        return this.droppedDown;
    },
    OnEscape: function(evt){
        this.HideDropDownArea(true);
        return this.droppedDown;
    },
    OnTextChanged: function() {
        this.OnValueChanged();
    },
    GetKeyValueInternal: function(){
        var element = this.GetKeyValueInputElement();
        if(element != null && element.value != "")
            return element.value;
        else
            return null;
    },
    SetKeyValueInternal: function(keyValue){
        var element = this.GetKeyValueInputElement();
        if(element != null) element.value = keyValue;
    },
    // API
    AdjustDropDownWindow: function(){
        var pc = this.GetPopupControl();
        if(_aspxIsExists(pc))
            pc.AdjustSize();
    },
    GetKeyValue: function(){
        return this.GetKeyValueInternal();
    },
    SetKeyValue: function(keyValue){
        this.SetKeyValueInternal(keyValue);
    }
});

ASPxClientDropDownCollection = _aspxCreateClass(ASPxClientControlCollection, {
    constructor: function(){
        this.constructor.prototype.constructor.call(this);

        this.droppedControlName = "";
        this.droppedParentNames = new Array();
        this.focusedControlName = "";
        
        aspxGetControlCollection().SubscribeObjectToBrowserWindowResize(this);
    },
    SetFocusedDropDownName: function(name){
        this.focusedControlName = name;
    },
    ResetDroppedDownControl: function(){
        this.droppedControlName = "";
    },
    ResetDroppedDownParentCollection: function(startDroppedDownControlName) {
        var regArray = new Array();

        for(var i = 0; i < this.droppedParentNames.length; i++) {
            if(this.droppedParentNames[i] == startDroppedDownControlName)
                break;
            _aspxArrayPush(regArray, this.droppedParentNames[i]);
        }

        this.droppedParentNames = regArray;
        if(this.droppedParentNames.length > 0) {
            this.droppedControlName = this.droppedParentNames[this.droppedParentNames.length - 1];
            _aspxArrayRemoveAt(this.droppedParentNames, this.droppedParentNames.length - 1);
        }
    },
    ResetFocusedControl: function(){
        this.focusedControlName = "";
    },
    GetFocusedDropDown: function(){
        var control = this.GetDropDownControlInternal(this.focusedControlName);
        if(control == null) this.ResetFocusedControl();
        return control;
    },
    GetDroppedDropDown: function(){
        var control = this.GetDropDownControlInternal(this.droppedControlName);
        if(control == null) this.ResetDroppedDownControl();
        return control;
    },
    GetDroppedDropDownParents: function(startDroppedDownControlName) {
        var dropDownArray = new Array();
        var isNeedGetControl = false;

        for(var i = 0; i < this.droppedParentNames.length; i++) {
            if(this.droppedParentNames[i] == startDroppedDownControlName) isNeedGetControl = true;
            if(isNeedGetControl)
                var control = this.GetDropDownControlInternal(this.droppedParentNames[i]);
                if(control != null)
                    _aspxArrayPush(dropDownArray, control);
        }
        return dropDownArray;
    },
    FindFirstNameForClose: function(newDroppedDownParentArray) {
        var firstNameToClose = newDroppedDownParentArray.length > 0 ? "" : this.droppedParentNames[i];
        for(var i = 0; i < this.droppedParentNames.length; i++) {
            if(_aspxArrayIndexOf(newDroppedDownParentArray, this.Get(this.droppedParentNames[i])) == -1) {
                firstNameToClose = this.droppedParentNames[i];
                break;
            }
        }
        return firstNameToClose;
    },
    GetDropDownControlInternal: function(name){
        var control = this.Get(name);
        var isControlExists = _aspxIsExists(control) && control.IsRenderExists();
        if(!isControlExists)
            control = null;
        return control;
    },
    IsDroppedDropDownParentExist: function(name) {
        for(var i = 0; i < this.droppedParentNames.length; i++) {
            if(this.droppedParentNames[i] == name)
                return true;
        }
        return false;
    },
    OnDDButtonMouseMove: function(evt){
        var dropDownControl = this.GetDroppedDropDown();
        if(dropDownControl != null)
            dropDownControl.OnDDButtonMouseMove(evt);
    },
    OnDocumentMouseDown: function(evt){
        this.CloseDropDownByDocumentOrWindowEvent(evt, false);
        this.ClearFocusedDropDownByDocumentEvent(evt);
    },
    OnDocumentMouseUp: function(evt){
        var dropDownControl = this.GetDroppedDropDown();
        if(dropDownControl != null)
            dropDownControl.OnDocumentMouseUp();
    },
    OnBrowserWindowResize: function(evt){
            this.CloseDropDownByDocumentOrWindowEvent(evt, true);
            this.AdjustControls();
    },
    
    CloseDropDownByDocumentOrWindowEvent: function(evt, isResize){
        var dropDownControl = this.GetDroppedDropDown();
        if(dropDownControl != null && (this.IsEventNotFromControlSelf(evt, dropDownControl) || isResize))
            dropDownControl.CloseDropDownByDocumentOrWindowEvent();

        var childrenDropDownsToClose = this.GetDroppedDropDownParents(this.droppedParentNames[0]);
        if(childrenDropDownsToClose.length != 0) {
            childrenDropDownsToClose = childrenDropDownsToClose.reverse();
            this.ResetDroppedDownParentCollection(this.droppedParentNames[0]);

            var rollbackDroppedDownNames = new Array();
            for(var c = 0; c < childrenDropDownsToClose.length; c++) {
                if(this.IsEventNotFromControlSelf(evt, childrenDropDownsToClose[c]))
                    childrenDropDownsToClose[c].CloseDropDownByDocumentOrWindowEvent();
                else
                    _aspxArrayPush(rollbackDroppedDownNames, childrenDropDownsToClose[c].name);
            }

            if(rollbackDroppedDownNames != 0) {
                rollbackDroppedDownNames = rollbackDroppedDownNames.reverse();
                this.droppedParentNames = rollbackDroppedDownNames;
            }
        }
    },
    ClearFocusedDropDownByDocumentEvent: function(evt){
        var focusedDropDown = this.GetFocusedDropDown();
        if(focusedDropDown != null && this.IsEventNotFromControlSelf(evt, focusedDropDown))
            this.SetFocusedDropDownName("");        
    },
    AdjustControls: function(){
        for(var name in this.elements) {
            this.elements[name].AdjustControl(false);
        }
    },
    IsEventNotFromControlSelf: function(evt, control){
        // Prevent DocumentOnClick event fired by the DropDown control and DropDownElement(Mozilla only) click
        var srcElement = _aspxGetEventSource(evt);
        var mainElement = control.GetMainElement();
        var popupControl = control.GetPopupControl();
        if(srcElement == null || !_aspxIsExists(mainElement) || !_aspxIsExists(popupControl)) return true;
        
        return (!_aspxGetIsParent(mainElement, srcElement) &&
            !_aspxGetIsParent(popupControl.GetWindowElement(-1), srcElement));
    },
    RegisterDroppedDownControl: function(dropDownControl, droppedDownParentArray){
        var prevDropDownControl = this.GetDroppedDropDown();
        var areDroppedDownsCollectionParents = _aspxArrayIndexOf(droppedDownParentArray, prevDropDownControl) != -1;
        if(prevDropDownControl != null && prevDropDownControl != dropDownControl && !areDroppedDownsCollectionParents)
            prevDropDownControl.OnOpenAnotherDropDown();
        if(this.droppedParentNames.length > 0) {
            var firstDropDownsNameToClose = this.FindFirstNameForClose(droppedDownParentArray);
            if(firstDropDownsNameToClose != "") {
                var childrenDropDownsToClose = this.GetDroppedDropDownParents(firstDropDownsNameToClose);
                this.ResetDroppedDownParentCollection(firstDropDownsNameToClose);
                this.CloseDroppedDownCollection(childrenDropDownsToClose.reverse());
            }
        }

        this.droppedControlName = dropDownControl.name;
        this.droppedParentNames = new Array();
        for(var i = 0; i < droppedDownParentArray.length; i++)
            _aspxArrayPush(this.droppedParentNames, droppedDownParentArray[i].name);
    },
    UnregisterDroppedDownControl: function(dropDownControl){
        if(this.droppedControlName == dropDownControl.name)
            this.ResetDroppedDownControl();

        if(this.IsDroppedDropDownParentExist(dropDownControl.name)) {
            var prevDropDownControl = this.GetDroppedDropDown();
            if(prevDropDownControl != null)
                prevDropDownControl.OnOpenAnotherDropDown();

            var childrenDropDownsToClose = this.GetDroppedDropDownParents(dropDownControl.name);
            this.ResetDroppedDownParentCollection(dropDownControl.name);
            _aspxArrayRemoveAt(childrenDropDownsToClose, 0);

            this.CloseDroppedDownCollection(childrenDropDownsToClose.reverse());
        }
    },
    CloseDroppedDownCollection: function(dropDownParentArray) {
        for(var c = 0; c < dropDownParentArray.length; c++)
            dropDownParentArray[c].OnOpenAnotherDropDown();
    }
});
ASPxClientDateEdit = _aspxCreateClass(ASPxClientDropDownEditBase, {
    constructor: function(name) {
        this.constructor.prototype.constructor.call(this, name);
        this.dateFormatter = null;
        
        //set from server        
        this.date = null;
        this.dateOnError = "u";
        this.allowNull = true;
        this.calendarOwnerName = null;
        this.calendarConsumerName = null;
        this.DateChanged = new ASPxClientEvent();        
        this.ParseDate = new ASPxClientEvent();
    },
    Initialize: function() {
		if(this.calendarOwnerName == null) {
            var calendar = this.GetCalendar();
            if(_aspxIsExists(calendar)) {
				calendar.SelectionChanging.AddHandler(ASPxClientDateEdit.HandleCalendarSelectionChanging);
				calendar.MainElementClick.AddHandler(ASPxClientDateEdit.HandleCalendarMainElementClick);
                if (__aspxNetscapeFamily)
                    calendar.GetMainElement().style.borderCollapse = "separate";
            }
		}
        ASPxClientDropDownEditBase.prototype.Initialize.call(this);
    },
    InlineInitialize: function(){
        this.InitSpecialKeyboardHandling();
        ASPxClientDropDownEditBase.prototype.InlineInitialize.call(this);
    },
        
    ShowDropDownArea: function(isRaiseEvent){
        var cal = this.GetCalendar();
        if(_aspxIsExists(cal))            
            cal.SetValue(this.date);
        cal.forceMouseDown = true;
        __aspxActiveCalendar = cal;
        ASPxClientDateEdit.active = this;
        
        ASPxClientDropDownEditBase.prototype.ShowDropDownArea.call(this, isRaiseEvent);
        
		var calendarOwner = this.GetCalendarOwner();
		if(calendarOwner != null)
		    calendarOwner.calendarConsumerName = this.name;
		this.calendarConsumerName = null;
    },    	  
    GetPopupControl: function() { // overriden
		var calendarOwner = this.GetCalendarOwner();
		if(calendarOwner != null)
			return calendarOwner.GetPopupControl();
		return ASPxClientDropDownEditBase.prototype.GetPopupControl.call(this);
    },
    OnPopupControlShown: function() {
        if(this.calendarConsumerName != null)
            aspxGetControlCollection().Get(this.calendarConsumerName).OnPopupControlShown();
        else        
            ASPxClientDropDownEditBase.prototype.OnPopupControlShown.call(this);
    },
    GetCalendar: function() {    
        var name = this.GetDropDownInnerControlName(__aspxCalendarNameSuffix);
        return aspxGetControlCollection().Get(name);
    },
    GetCalendarOwner: function() {
		if(!this.calendarOwnerName)
			return null;
		return aspxGetControlCollection().Get(this.calendarOwnerName);
    },
    GetFormattedDate: function() {
		if(this.maskInfo != null)
			return this.maskInfo.GetValue();
        if(this.date == null)
            return this.focused ? "" : this.nullText;
        return this.dateFormatter.Format(this.date);
    },
    RaiseValueChangedEvent: function() {
        if(!this.isInitialized) return false;
        var processOnServer = ASPxClientEdit.prototype.RaiseValueChangedEvent.call(this);
        processOnServer = this.RaiseDateChanged(processOnServer);
        return processOnServer;
    },
    OnApplyChanges: function(){
        this.OnTextChanged();
    },
    OnCalendarSelectionChanging: function(date) {
        if(!this.GetCalendar().isDateChangingByKeyboard) {
            this.HideDropDownArea(true);
            if(date != null)
				this.ApplyExistingTime(date);
            this.ChangeDate(date);
            this.SelectInputElement();
        }
    },
    OnArrowUp: function(evt){    
        var isProcessed = ASPxClientDropDownEditBase.prototype.OnArrowUp.call(this, evt);
        if(!isProcessed && this.droppedDown)
            return this.GetCalendar().OnArrowUp(evt);                   
        return false;
    },
    OnArrowDown: function(evt){
        var isProcessed = ASPxClientDropDownEditBase.prototype.OnArrowDown.call(this, evt);
        if(!isProcessed && this.droppedDown)
            return this.GetCalendar().OnArrowDown(evt);
        return false;
    },
    OnArrowLeft: function(evt){
        if (this.droppedDown) {
            this.GetCalendar().OnArrowLeft(evt);
            return true;
        }
        return false;
    },
    OnArrowRight: function(evt){
        if (this.droppedDown) {    
            this.GetCalendar().OnArrowRight(evt);
            return true;
        }
        return false;
    },
    
    OnPageUp: function(evt){
        if (this.droppedDown) {    
            this.GetCalendar().OnPageUp(evt);
            return true;
        }
        return false;        
    },
    OnPageDown: function(evt){
        if (this.droppedDown) {
            this.GetCalendar().OnPageDown(evt);
            return true;
        }
        return false;        
    },
    OnEndKeyDown: function(evt) {
        if (this.droppedDown) {
            this.GetCalendar().OnEndKeyDown(evt);
            return true;
        }
        return false;
    },
    OnHomeKeyDown: function(evt) {
        if (this.droppedDown) {
            this.GetCalendar().OnHomeKeyDown(evt);
            return true;
        }
        return false;    
    },
    
    OnEnter: function() {
        this.enterProcessed = false; // hack for defaultbutton
        if (this.droppedDown) {
			var calendar = this.GetCalendar();
            if (calendar.IsFastNavigationActive()) {
                calendar.GetFastNavigation().OnEnter();
            } else {
                this.OnCalendarSelectionChanging(this.GetCalendar().GetValue());
            }
            this.enterProcessed = true;
        }
        else
            this.OnApplyChanges();
        return this.enterProcessed;
    },
    OnEscape: function() {
        if (this.droppedDown){
            if (this.GetCalendar().IsFastNavigationActive())
                this.GetCalendar().OnEscape();
            else
                this.HideDropDownArea(true);
        } else {
            this.ChangeDate(this.date);        
        }
        return true;
    },
    OnTab: function(evt){
        if(!this.droppedDown) return;
        
		var calendar = this.GetCalendar();
        if (calendar.IsFastNavigationActive()) 
            calendar.GetFastNavigation().Hide();
            
        this.OnCalendarSelectionChanging(this.GetCalendar().GetValue());
    },
        
    ParseValue: function() {    
		var date;
		if(this.maskInfo != null) {
			date = _aspxMaskDateTimeHelper.GetDate(this.maskInfo);			
		} else {
			var text = this.GetInputElement().value;
			var userParseResult = this.GetUserParsedDate(text);
			if(userParseResult !== false) {
				date = userParseResult;
			} else {
				if(text == null || text == "")
					date = null;
				else
					date = this.dateFormatter.Parse(text);
			}			
		}
		this.ApplyParsedDate(date);
    },
    GetUserParsedDate: function(text) {
		if(!this.ParseDate.IsEmpty()) {
			var args = new ASPxClientParseDateEventArgs(text);
			this.ParseDate.FireEvent(this, args);
			if(args.handled)
				return args.date;
		}
		return false;
    },
    
    ApplyParsedDate: function(date) {
		if(date === false || !this.GetCalendar().IsDateInRange(date)) {
			switch(this.dateOnError) {
				case "n":
					date = null;
					break;
				case "t":
					date = new Date();
					break;
				default:
					date = this.date;
					break;
			}
		}
		if(!this.allowNull && date == null)
			date = this.date;
		this.ChangeDate(date);		
    },
    
    ApplyExistingTime: function(date) {
		if(this.date == null)  return;		
		var savedDay = date.getDate();
        date.setHours(this.date.getHours());
        var diff = date.getDate() - savedDay;
        if(diff != 0) {
			var sign = (diff == 1 || date.getDate() == 1) ? -1 : 1;
			date.setTime(date.getTime() + sign * 3600000);
        }
        date.setMinutes(this.date.getMinutes());
        date.setSeconds(this.date.getSeconds());
        date.setMilliseconds(this.date.getMilliseconds());
    },
    
    GetValue: function() {
        return this.date;
    },    
    GetValueString: function() {
        return this.date != null ? _aspxGetInvariantDateTimeString(this.date) : null;
    },
    SetValue: function(date) {        
        this.date = date;
        if(this.maskInfo != null) {
			_aspxMaskDateTimeHelper.SetDate(this.maskInfo, date);
			this.ApplyMaskInfo(false);
			this.SavePrevMaskValue();
        } else {
			this.GetInputElement().value = this.GetFormattedDate();
			this.SyncRawInputValue();
		}
		if(this.styleDecoration != null)
			this.styleDecoration.Update();
    },
    ChangeDate: function(date) {    
		var changed = !this.AreDatesEqualExact(this.date, date);
		this.SetValue(date);        
		if(changed) {
            this.RaisePersonalStandardValidation();
            this.OnValueChanged();
        }
    },
    AreDatesEqualExact: function(date1, date2) {
        if(date1 == null && date2 == null)
            return true;
        if(date1 == null || date2 == null)
            return false;
        return date1.getTime() == date2.getTime();
    },
    GetText: function() {
		return this.GetFormattedDate();
    },
    SetText: function(value) {
		ASPxClientTextEdit.prototype.SetValue.call(this, value);
		if(this.maskInfo == null)
			this.ParseValue();
    },    
        
    // Mask
    ShouldCancelMaskKeyProcessing: function(htmlEvent, keyDownInfo) {
		if(htmlEvent.altKey)
			return true;
		if(ASPxClientDropDownEditBase.prototype.ShouldCancelMaskKeyProcessing.call(this, htmlEvent, keyDownInfo))
			return true;		
		if(!this.droppedDown)
			return false;
		return !_aspxMaskManager.IsPrintableKeyCode(keyDownInfo) 
			&& keyDownInfo.keyCode != ASPxKey.Backspace
			&& keyDownInfo.keyCode != ASPxKey.Delete;
    },
    DecodeRawInputValue: function(value) {
		if(value == "N") return null;
		var date = new Date();
		date.setTime(Number(value));
		return _aspxToUtcTime(date);
    },
    SyncRawInputValue: function() {
		this.GetRawInputElement().value = this.date == null ? "N" : _aspxToLocalTime(this.date).valueOf();
    },    
    
    HasTextDecorators: function() {
		return (this.maskInfo != null && this.date == null) || ASPxClientDropDownEditBase.prototype.HasTextDecorators.call(this);
    },
    GetMaskDisplayText: function() {
		if(!this.focused) {
			if(this.date == null)
				return this.nullText;
			if(this.HasTextDecorators())
				return this.GetDecoratedText(this.date);
		}
		return this.maskInfo.GetText();
    },
    ToggleTextDecorationCore: function() {
		if(this.maskInfo != null) {
			this.ApplyMaskInfo(false);
		} else {
			var text;
			var input = this.GetInputElement();
			if(this.focused) {
				text = this.GetFormattedDate();
			} else {
				if(this.date == null)
					text = this.nullText;
				else if(this.displayFormat != null)
					text = ASPxFormatter.Format(this.displayFormat, this.date);
				else
					text = this.GetFormattedDate();
			}
			if(input.value != text)
				input.value = text;			
		}
    },
    
    // API
    RaiseDateChanged: function(processOnServer) {
        if(!this.DateChanged.IsEmpty()) {
            var args = new ASPxClientProcessingModeEventArgs(processOnServer);
            this.DateChanged.FireEvent(this, args);
            processOnServer = args.processOnServer;
        }
        return processOnServer;
    },
    SetDate: function(date) {
        this.SetValue(date);
    },
    GetDate: function() {
        return this.date;
    },
	GetMinDate: function() {
		var cal = this.GetCalendar();
		if(cal)
			return cal.GetMinDate();
		return null;
	},
	SetMinDate: function(date) {
		var cal = this.GetCalendar();
		if(cal)
			cal.SetMinDate(date);
	},
	GetMaxDate: function() {
		var cal = this.GetCalendar();
		if(cal)
			return cal.GetMaxDate();
		return null;
	},
	SetMaxDate: function(date) {
		var cal = this.GetCalendar();
		if(cal)
			cal.SetMaxDate(date);	
	}    
});
ASPxClientDateEdit.active = null;
ASPxClientDateEdit.HandleCalendarSelectionChanging = function(s, e) {
	if(ASPxClientDateEdit.active == null) return;
	ASPxClientDateEdit.active.OnCalendarSelectionChanging(e.selection.GetFirstDate());
};
ASPxClientDateEdit.HandleCalendarMainElementClick = function(s, e) {
	if(ASPxClientDateEdit.active == null) return;
	ASPxClientDateEdit.active.SetFocus();
};
ASPxClientParseDateEventArgs = _aspxCreateClass(ASPxClientEventArgs, {
	constructor: function(value) {
		this.constructor.prototype.constructor.call(this);
		this.value = value;
		this.date = null;
		this.handled = false;
	}	
});


__aspxCCValueInputSuffix = "VI";
ASPxClientComboBoxBase = _aspxCreateClass(ASPxClientDropDownEditBase, {
    constructor: function(name) {
        this.constructor.prototype.constructor.call(this, name);
        
        this.lbEventLockCount = 0;
        this.receiveGlobalMouseWheel = false;
        
        // Cache
        this.listBox = null;
        this.lastSuccessValue = "";
        this.islastSuccessValueInit = false;        
        this.SelectedIndexChanged = new ASPxClientEvent();
    },
    Initialize: function(){
        this.InitializeListBoxOwnerName();
        ASPxClientDropDownEditBase.prototype.Initialize.call(this);
    },
    InitializeListBoxOwnerName: function(){
        var lb = this.GetListBoxControl();
        if(_aspxIsExists(lb))
            lb.ownerName = this.name;
    },
    GetDropDownInnerControlName: function(suffix){
        return "";
    },
    GetListBoxControl: function(){
        if(!_aspxIsExistsElement(this.listBox)){
            var name = this.GetDropDownInnerControlName(__aspxListBoxNameSuffix);
            this.listBox = aspxGetControlCollection().Get(name);
        }
        return this.listBox;
    },
    GetCallbackArguments: function(){
        return this.GetListBoxCallbackArguments();
    },
    GetListBoxCallbackArguments: function(){
        var lb = this.GetListBoxControl();
        return lb.GetCallbackArguments();
    },
    SendCallback: function(){
        this.CreateCallback(this.GetCallbackArguments());
    },
    SetText: function (text){
        var lb = this.GetListBoxControl();
        var index = this.GetAdjustedSelectedIndexByText(lb, text);
        this.SelectIndex(index, false);
        this.SetTextInternal(text);
        this.SetLastSuccessTest(text);
        this.lastSuccessValue = index >= 0 ? lb.GetValue() : text;
        this.islastSuccessValueInit = true;
    },
    GetValue: function(){
        return this.islastSuccessValueInit ? this.lastSuccessValue : this.GetValueInternal();
    },
    GetValueInternal: function(){
        var text = this.GetTextInternal();
        var lb = this.GetListBoxControl();
        if (_aspxIsExists(lb)){
            var index = this.GetAdjustedSelectedIndexByText(lb, text);
            lb.SelectIndexSilent(index, false); // Prevent to direct input value changing
            if(index != -1)
                return lb.GetValue();
        }
        return ASPxClientDropDownEditBase.prototype.GetValue.call(this);
    },
    SetValue: function(value){
        var lb = this.GetListBoxControl();
        lb.SetValue(value);
        // TODO Extract method with OnSelectChanged (params: value)
        var item = lb.GetSelectedItem();
        var text = _aspxIsExists(item) ? item.text : value;
        this.OnSelectionChangedCore(text, item, false);
        
        this.UpdateValueInput();
        //
    },
    
    GetAdjustedSelectedIndexByText: function(lb, text){
        var lbSelectedItem = lb.GetSelectedItem();
        if(lbSelectedItem != null && lbSelectedItem.text == text)
            return lbSelectedItem.index;
        return this.FindItemIndexByText(lb, text);
    },
    FindItemIndexByText: function(lb, text){
        if (!_aspxIsExists(lb)) return;
        for(var i = 0; i < lb.GetItemCount(); i ++){
            if(lb.GetItem(i).text == text)
                return i;
        }
        return -1;
    },
    CollectionChanged: function(){
    },
    SelectIndex: function(index, initialize){
        var lb = this.GetListBoxControl();
        var isSelectionChanged = lb.SelectIndexSilentAndMakeVisible(index, initialize);
        var item = lb.GetSelectedItem();
        var text = item != null ? item.text : "";
        
        if(isSelectionChanged)
            this.OnSelectionChangedCore(text, item, false);
            
        this.UpdateValueInput();
        
        return isSelectionChanged;
    },
    OnSelectChanged: function(){
        if(this.lbEventLockCount > 0) return;

        var lb = this.GetListBoxControl();
        // TODO Extract method with SetValue (params: value = "")
        var item = lb.GetSelectedItem();
        var text = item != null ? item.text : "";
        this.OnSelectionChangedCore(text, item, false);
        //
        this.OnChange(); 
        
        if(!this.isToolbarItem)
            this.SelectInputElement();
    },
    OnSelectionChangedCore: function(text, item, canBeRolledBack){
        this.SetTextInternal(text);
        this.ShowItemImage(item);
        
        if(!canBeRolledBack){
            this.SetLastSuccessTest(text);
            this.lastSuccessValue = item != null ? item.value : text;
            this.islastSuccessValueInit = true;
        }
    },
    ShowItemImage: function(item){
        var imageUrl = item != null ? item.imageUrl : "";
        this.SetSelectedImage(imageUrl);
    },
    
    GetDropDownImageElement: function(){
        var itemImageCell = this.GetDropDownItemImageCell();
        if(itemImageCell != null)
            return _aspxGetChildByTagName(itemImageCell, "IMG", 0);
        return null;
    },
    SetSelectedImage: function(imageUrl) {
        var imgElement = this.GetDropDownImageElement();
        if(imgElement != null) {
            imageUrl = imageUrl != "" ? imageUrl : window.__aspxEmptyImageUrl;
            imgElement.src = imageUrl;
            if(__aspxIE) {
                this.CollapseControl();
                this.CorrectEditorWidth();
            }
        }
    },
    OnCallback: function(result) {
    },
    OnChange: function(){
        this.UpdateValueInput();
        this.RaisePersonalStandardValidation();
        this.OnValueChanged();
    },
    UpdateValueInput: function() {
    },
    
    RaiseValueChangedEvent: function() {
        if(!this.isInitialized) return;
        var processOnServer = ASPxClientTextEdit.prototype.RaiseValueChangedEvent.call(this);
        processOnServer = this.RaiseSelectedIndexChanged(processOnServer);
        return processOnServer;
    },
    RaiseSelectedIndexChanged: function(processOnServer) {
        if(!this.SelectedIndexChanged.IsEmpty()){
            var args = new ASPxClientProcessingModeEventArgs(processOnServer);
            this.SelectedIndexChanged.FireEvent(this, args);
            processOnServer = args.processOnServer;
        }
        return processOnServer;
    },
    AddItem: function(text, value, imageUrl){
        var index = this.GetListBoxControl().AddItem(text, value, imageUrl);
        this.CollectionChanged();
        return index;
    },
    InsertItem: function(index, text, value, imageUrl){
        this.GetListBoxControl().InsertItem(index, text, value, imageUrl);
        this.CollectionChanged();
    },
    RemoveItem: function(index){
        this.GetListBoxControl().RemoveItem(index);
        this.CollectionChanged();
    },
    ClearItems: function(){
        this.GetListBoxControl().ClearItems();
        this.ClearItemsInternal();
    },
    BeginUpdate: function(){
         this.GetListBoxControl().BeginUpdate();
    },
    EndUpdate: function(){
        this.GetListBoxControl().EndUpdate();
        this.CollectionChanged();
    },
    MakeItemVisible: function(index){
    },
    GetItem: function(index){
        return this.GetListBoxControl().GetItem(index);
    },
    GetItemCount: function(){
        return this.GetListBoxControl().GetItemCount(); 
    },
    GetSelectedIndex: function(){
        return this.GetListBoxControl().GetSelectedIndex();
    },
    SetSelectedIndex: function(index){
        this.SelectIndex(index, false);
    },
    GetSelectedItem: function(){
        var lb = this.GetListBoxControl();
        var index = lb.GetSelectedIndex();
        return lb.GetItem(index);
    },
    SetSelectedItem: function(item){
        var index = (item != null) ? item.index : -1;
        this.SelectIndex(index, false);
    },
    GetText: function(){
        return this.lastSuccessText;
    },
    PerformCallback: function(arg) {
    },
    ClearItemsInternal: function(){
        this.SetValue(null);
        this.CollectionChanged();
    }
});

ASPxClientComboBox = _aspxCreateClass(ASPxClientComboBoxBase, {
    constructor: function(name) {
        this.constructor.prototype.constructor.call(this, name);
        
        this.filterTimerId = -1;
        // Callback
        this.allowMultipleCallbacks = false;
        this.isApplyAndCloseAfterCallback = false;
        this.isCallbackMode = false;
        this.isPerformCallback = false;
        this.changeSelectAfterCallback = 0;
        // Filtering
        this.isFilterEnabled = false;
        this.isEnterLocked = false;
        this.isLastFilteredKeyWasTab = false; // B30455. FilteringHighlightComplitedText invoke setFocus().
        this.currentCallbackIsFiltration = false;
        this.filter = "";
        this.filterTimer = 100;
                
        this.initTextCorrectionRequired = false;
        this.isDropDownListStyle = true;
        this.defaultDropDownHeight = "";
        this.dropDownHeight = "";
        this.dropDownWidth = "";
    },
    Initialize: function(){
        var lb = this.GetListBoxControl();
        this.InitializeListBoxOwnerName();
        
        var mainElement = this.GetMainElement();
        if(_aspxIsExists(mainElement))
            _aspxAttachEventToElement(mainElement, __aspxNetscapeFamily ? "DOMMouseScroll" : "mousewheel",
                new Function("aspxCBMouseWheel('" + this.name + "', event);"));
        var input = this.GetInputElement();
        var ddbutton = this.GetDropDownButton();
        if(_aspxIsExists(ddbutton))
            _aspxAttachEventToElement(ddbutton, "mousemove", aspxCBDDButtonMMove);
        if(this.isFilterEnabled)
            _aspxAttachEventToElement(input, "keyup", aspxCBKeyUp);
        if(this.isDropDownListStyle && __aspxIE){
            _aspxPreventElementDragAndSelect(mainElement, true);
            _aspxPreventElementDragAndSelect(input, true);
            if(_aspxIsExists(ddbutton))
                _aspxPreventElementDragAndSelect(ddbutton, true);
        }
        if(this.isToolbarItem){
            mainElement.unselectable="on";
            input.unselectable="on";
            if(_aspxIsExists(input.offsetParent))
                input.offsetParent.unselectable="on";
            if(_aspxIsExists(ddbutton))
                ddbutton.unselectable="on";
            if(_aspxIsExists(lb)){
                var table = lb.GetListTable();
                for(var i = 0; i < table.rows.length; i ++){
                    for(var j = 0; j < table.rows[i].cells.length; j ++)
                        _aspxSetElementAsUnselectable(table.rows[i].cells[j], true);
                }
            }
        }
        
        this.RemoveRaisePSValidationFromListBox();
        this.RedirectStandardValidators();
        this.UpdateValueInput();
        this.InitDropDownSize();
        this.InitListBoxScrollStyle();

        ASPxClientComboBoxBase.prototype.Initialize.call(this);
    },
    InlineInitialize: function(){
        this.InsureInputValueCorrect();
        this.InitSpecialKeyboardHandling();
        ASPxClientEditBase.prototype.InlineInitialize.call(this);
    },
    InsureInputValueCorrect: function(){ // B139038
        if(this.initTextCorrectionRequired){
            var lb = this.GetListBoxControl();
            if(_aspxIsExists(lb)){
                var initSelectedIndex = lb.GetSelectedIndexInternal();
                if(initSelectedIndex >= 0){
                    var initSelectedText = lb.GetItem(initSelectedIndex).text;
                    var input = this.GetInputElement();
                    var rawInput = this.GetRawInputElement();
                    if(_aspxIsExists(rawInput) && rawInput.value != initSelectedText){
                        rawInput.value = initSelectedText;
                        input.value = this.GetDecoratedText(initSelectedText);
                    } else if(input.value != initSelectedText)
                        input.value = initSelectedText
                }
            }
        }
    },
        
    GetDropDownInnerControlName: function(suffix){
        return ASPxClientDropDownEditBase.prototype.GetDropDownInnerControlName.call(this, suffix);
    },
    AdjustControlCore: function() {
        ASPxClientEdit.prototype.AdjustControlCore.call(this);
        this.ddHeightCache = __aspxInvalidDimension;
        this.ddWidthCache = __aspxInvalidDimension;
    },
    
    RemoveRaisePSValidationFromListBox: function() {
        var listBox = this.GetListBoxControl();
        if (_aspxIsExists(listBox))
            listBox.RaisePersonalStandardValidation = function() { };
    },
    RedirectStandardValidators: function() {
        var valueInput = this.GetValueInput();
        if(_aspxIsExistsElement(valueInput) && _aspxIsExists(valueInput.Validators)) {
            for(var i = 0; i < valueInput.Validators.length; i++)
                valueInput.Validators[i].controltovalidate = valueInput.id;
        }
    },
    GetValueInputToValidate: function(){
        return this.GetValueInput();
    },
    GetValueInput: function(){
        return document.getElementById(this.name + "_" + __aspxCCValueInputSuffix);
    },
    GetListBoxScrollDivElement: function(){
        return this.GetListBoxControl().GetScrollDivElement();
    },
    UpdateValueInput: function() {
        var inputElement = this.GetValueInput();
        if(_aspxIsExists(inputElement)){
            var value = this.GetValue();
            inputElement.value = value != null ? value : "";
        }
    },
    
    VisibleCollectionChanged: function(){
		this.CollectionChangedCore();
    },
    CollectionChanged: function(){
        this.CollectionChangedCore();
    },
    CollectionChangedCore: function(byTimer){
        if(this.GetListBoxControl().APILockCount == 0){
            this.UpdateDropDownPositionAndSize();
            
            if(__aspxIE){ // Prevent wrong selected style render
                var lb = this.GetListBoxControl();
                var selectedIndex = lb.GetSelectedIndex();
                if(selectedIndex > -1){
                    var selectedItemTextCell = lb.GetItemFirstTextCell(selectedIndex);
                    var controller = aspxGetStateController();
                    controller.DeselectElementBySrcElement(selectedItemTextCell);
                    controller.SelectElementBySrcElement(selectedItemTextCell);
                }
            }
        }
    },
    UpdateDropDownPositionAndSize: function(){
        this.InitDropDownSize();
        if(this.droppedDown){
            var pc = this.GetPopupControl();
            var element = this.GetMainElement();
            pc.UpdatePositionAtElement(element);
        }
    },
    InitListBoxScrollStyle: function(){
        this.PreventScrollSpoilDDShowing();
    },
    GetDropDownHeight: function(){
        return (this.ddHeightCache != __aspxInvalidDimension) ? this.ddHeightCache : this.InitListBoxHeight();
    },
    GetDropDownWidth: function(){
        return (this.ddWidthCache != __aspxInvalidDimension && !this.GetIsControlWidthWasChanged()) ? this.ddWidthCache : this.InitListBoxWidth();
    },
    InitDropDownSize: function(){
        if(!this.enabled || this.GetItemCount() == 0) return; // B132741
        
        var pc = this.GetPopupControl();
        if(_aspxIsExists(pc) && this.IsDisplayed()) {
            var pcwElement = pc.GetWindowElement(-1);
            if(_aspxIsExistsElement(pcwElement)){
                var isPcwDisplayed = _aspxGetElementDisplay(pcwElement);
                if(!isPcwDisplayed)
                    pc.SetWindowDisplay(-1, true);
                this.ddHeightCache = this.InitListBoxHeight();
                this.ddWidthCache = this.InitListBoxWidth();
                pc.SetSize(this.ddWidthCache, this.ddHeightCache);
                if(!isPcwDisplayed)
                    pc.SetWindowDisplay(-1, false);
            }
        }
    },
    InitMainElementCache: function(){
        this.mainElementWidthCache = this.GetMainElement().clientWidth;
    },
    GetVisibleItemCount: function(lb){
        if(!this.isFilterEnabled || this.isCallbackMode)
            return this.GetItemCount();
        
        var lbTable = lb.GetListTable();
        var count = this.GetItemCount();
        var visibleItemCount = 0;
        for(var i = 0; i < count; i ++){
            if(_aspxGetElementDisplay(lbTable.rows[i]))
                visibleItemCount++;
        }
        return visibleItemCount;
    },
    GetDefaultDropDownHeight: function(listHeight, count){
        if(this.defaultDropDownHeight == ""){
            this.defaultDropDownHeight = ((listHeight / count) * 7) + "px";
        }
        return this.defaultDropDownHeight;
    },
    InitListBoxHeight: function(){
        var lbScrollDiv = this.GetListBoxScrollDivElement();
        var height = this.dropDownHeight;
        var lb = this.GetListBoxControl();
        lb.GetMainElement().style.height = "0px";
        var lbHeight = 0;
        if(height == ""){
            var listHeight = lb.GetListTableHeight();
            var count = this.GetVisibleItemCount(lb);
            if(count > 7)
                height = this.GetDefaultDropDownHeight(listHeight, count);
            else
                height = count == 0 ? "0px" : listHeight + "px";
            lbScrollDiv.style.height = height;
            lbHeight = lbScrollDiv.offsetHeight;
        } else {
            var lbMainElement = lb.GetMainElement();
            lbMainElement.style.height = "0px";
            lbScrollDiv.style.height = "0px";
            lbMainElement.style.height = height;
            var trueLbOffsetHeight = lbMainElement.offsetHeight;
            var trueLbClientHeight = lbMainElement.clientHeight;
            lbScrollDiv.style.height = lbMainElement.clientHeight + "px";
            lbHeightCorrection = lbMainElement.offsetHeight - trueLbOffsetHeight;
            lbScrollDiv.style.height = (trueLbClientHeight - lbHeightCorrection) + "px";
            lbHeight = lbMainElement.offsetHeight;
        }
        lb.InitializePageSize();
        return lbHeight;
    },
    InitListBoxWidth: function(){
        this.InitMainElementCache();
    
        var mainElement = this.GetMainElement();
        var lbScrollDiv = this.GetListBoxScrollDivElement();
        var lb = this.GetListBoxControl();
        var lbMainElement = lb.GetMainElement();
        var lbTable = lb.GetListTable();
        
		lbMainElement.style.width = "";
        lbScrollDiv.style.paddingRight = "0px";
        lbScrollDiv.style.width = "100%";

        if(this.dropDownWidth != ""){
            lbMainElement.style.width = this.dropDownWidth;
            var width = lbMainElement.clientWidth;
            width = this.SetLbScrollDivAndCorrectionForScroll(lb, width, false);
            if(!__aspxIE) {
                var difference = lbTable.offsetWidth - lbScrollDiv.clientWidth;
                if(difference > 0){
                    lbMainElement.style.width = (lbMainElement.offsetWidth + difference) + "px";
                    lbScrollDiv.style.width = (lbMainElement.clientWidth)  + "px";
                }
            }
        } else {
            var pc = this.GetPopupControl();
            var width = lbTable.offsetWidth;
            width = this.SetLbScrollDivAndCorrectionForScroll(lb, width, true);
            if(__aspxFirefox && lbMainElement.offsetWidth < lbScrollDiv.offsetWidth)
                lbMainElement.style.width = "0%"; // FIX B19014
            var widthDifference = mainElement.offsetWidth - lbMainElement.offsetWidth;
            if(widthDifference > 0){
                lbScrollDiv.style.width = (width + widthDifference) + "px";
                var twoBorderSize = (lbMainElement.offsetWidth - lbMainElement.clientWidth);
                lbMainElement.style.width = (width + widthDifference + twoBorderSize) + "px"; // prevent lbMainElement size hover ScrollBar
            }
        }
        if(lb.IsMultiColumn())
            lb.CorrectHeaderWidth();
        return lbScrollDiv.offsetWidth;
    },
    SetLbScrollDivAndCorrectionForScroll: function(lb, width, widthByContent){
        var lbScrollDiv = this.GetListBoxScrollDivElement();
        var scrollWidth = lb.GetVerticalScrollBarWidth();

        // B37486 (IE8)
        var browserPutsScrollBarOnContent = __aspxIE && __aspxBrowserVersion > 5.5 && __aspxBrowserVersion < 8;
        var browserCanHaveScroll = lb.GetVerticalOverflow(lbScrollDiv) == "auto" || this.IsScrollSpoilDDShowing();

        if(browserPutsScrollBarOnContent) {
            width -= scrollWidth;
            lbScrollDiv.style.paddingRight = scrollWidth + "px";
        } else if(widthByContent && browserCanHaveScroll)
            width += scrollWidth;

        lbScrollDiv.style.width = width + "px";
        return width;
    },
    
    SelectIndexSilent: function(lb, index){
        this.lbEventLockCount ++;
        lb.SelectIndexSilentAndMakeVisible(index);
        this.lbEventLockCount --;
    },
    SelectInputText: function(){
        var input = this.GetInputElement();
        _aspxSetInputSelection(input, 0, input.value.length);
    },
    GetDecoratedText: function(value){
        var selectedItem = this.GetSelectedItem();
        var lb = this.GetListBoxControl();
        if(this.displayFormat != null && lb.IsMultiColumn() && selectedItem != null){
            var textColumnCount = lb.GetItemTextCellCount();
            var texts = [textColumnCount];
            for(var i = 0; i < textColumnCount; i++){
                texts[i] = selectedItem.GetColumnTextByIndex(i)
            }
            return ASPxFormatter.Format(this.displayFormat, texts);
            
        } else
            return ASPxClientComboBoxBase.prototype.GetDecoratedText.call(this, value);
    },
    
    ShowDropDownArea: function(isRaiseEvent){
        var lb = this.GetListBoxControl();
        if(!_aspxIsExists(lb) || lb.GetItemCount() == 0) 
            return;

        ASPxClientDropDownEditBase.prototype.ShowDropDownArea.call(this, isRaiseEvent);
	        
        var rawText = this.GetTextInternal();
        var lbItem = lb.GetSelectedItem();
        var lbText = lbItem != null ? lbItem.text : "";
        if(rawText != lbText && rawText != null && lbText != ""){
            var newSelectedIndex = this.GetAdjustedSelectedIndexByText(lb, rawText);
            lb.SelectIndexSilent(newSelectedIndex, false);
        }
        this.EnsureSelectedItemVisibleOnShow(lb);
        lb.CallbackSpaceInit();
    },
    HideDropDownArea: function(isRaiseEvent){
        this.FilteringStop();
        if(__aspxWebKitFamily || __aspxOpera) // B36477
            this.GetListBoxControl().CachedScrollTop();
        ASPxClientDropDownEditBase.prototype.HideDropDownArea.call(this, isRaiseEvent);

        this.PreventScrollSpoilDDShowing();
    },
    EnsureSelectedItemVisibleOnShow: function(listBox){
        if(__aspxWebKitFamily || __aspxOpera) // B36477 Before EnsureSelectedItemVisible will make decision about item's visibility
            listBox.RestoreScrollTopFromCache();
        listBox.EnsureSelectedItemVisible();
    },
    IsScrollSpoilDDShowing: function (){
        var pc = this.GetPopupControl();
        return (__aspxNetscapeFamily && pc.enableAnimation); // Prevent mozilla wrong animation
    },
    EnableLBDivOverflow: function(){
        var divElement = this.GetListBoxScrollDivElement();
        divElement.style.overflow = "auto";
    },
    DisableLBDivOverflow: function(){
        var divElement = this.GetListBoxScrollDivElement();
        divElement.style.overflow = "hidden";
    },
    PreventScrollSpoilDDShowing: function(){
        if(this.IsScrollSpoilDDShowing())
            this.DisableLBDivOverflow();
    },
    ChangeReadOnlyAttribute: function(element, enabled){
        if(!this.isDropDownListStyle || this.isFilterEnabled)
            ASPxClientTextEdit.prototype.ChangeReadOnlyAttribute.call(this, element, enabled);
    },
    // Filtering
    IsCtrlV: function(evt, keyCode){
        return evt.ctrlKey && keyCode == 118;
    },
    EventKeyCodeChangesTheInput: function(evt){
        var keyCode = _aspxGetKeyCode(evt);
        if(evt.ctrlKey)
            return this.IsCtrlV(evt, keyCode);
            
        var isSystemKey = ASPxKey.Windows <= keyCode && keyCode <= ASPxKey.ContextMenu;
        var isFKey = ASPxKey.F1 <= keyCode && keyCode <= 127; // 127 - F16 for MAC
        return ASPxKey.Delete <= keyCode && !isSystemKey && !isFKey || keyCode == ASPxKey.Backspace || keyCode == ASPxKey.Space;
    },
    OnFilteringKeyUp: function(evt){
        if(!this.isFilterEnabled || this.InCallback()) return;
        
        if(this.EventKeyCodeChangesTheInput(evt)){
            this.FilterStopTimer();
            var input = this.GetInputElement();
            var newFilter = input.value.toLowerCase();
            if(evt.keyCode == ASPxKey.Backspace && _aspxHasInputSelection(input) && newFilter == this.filter)
                this.FilteringBackspace();
            else
                this.FilterStartTimer();
        }
    },
    IsFilterTimerActive: function(){
        return (this.filterTimerId != -1);
    },
    FilterStartTimer: function(){
        this.isEnterLocked = true;
        this.filterTimerId = _aspxSetTimeout("aspxCBFilterByTimer('" + this.name + "')", this.filterTimer);
    },
    FilterStopTimer: function(){
        this.filterTimerId = _aspxClearTimer(this.filterTimerId);
    },
    EnshureShowDropDownArea: function(){
        if(!this.droppedDown)
            this.ShowDropDownArea(true);
    },
    Filtering: function(){
        this.FilterStopTimer();
    
        var input = this.GetInputElement();
        var newFilter = input.value.toLowerCase();
        if(this.filter != newFilter){
            this.filter = newFilter;
            this.EnshureShowDropDownArea();

            if(this.isCallbackMode)
                this.FilteringOnServer();
            else
                this.FilteringOnClient(input); 
        } else 
            this.isEnterLocked = false;
    },
    FilteringBackspace: function(){
        if(this.isFilterEnabled){
            var input = this.GetInputElement();
            var currentText = input.value;
            var cutText = currentText.slice(0, -1);
            if(cutText != currentText)
                input.value = cutText;
            this.FilterStartTimer();
        } 
    },
    GetCallbackArguments: function(){
        var args = ASPxClientComboBoxBase.prototype.GetCallbackArguments.call(this);
        if(this.isCallbackMode)
            args += this.GetCallbackArgumentsInternal();
        return args;
    },
    GetCallbackArgumentsInternal: function(){
        var args = "";
        if(this.filter != "")
            args = this.GetCallbackArgumentFilter(this.filter);
        return args;
    },
    GetCallbackArgumentFilter: function(value){
        var callbackPrefix = this.isDropDownListStyle ? __aspxCorrectFilterCallbackPrefix : __aspxLoadFilteredItemsCallbackPrefix;
        return this.FormatCallbackArg(callbackPrefix, value);
    },
    FilteringOnServer: function(){
        if(!this.InCallback()){
            var listBox = this.GetListBoxControl();
            
            listBox.ClearItems(); // TODO Extract method in 8.x with ListBoxAPI
            listBox.serverIndexOfFirstItem = 0;
            listBox.SetScrollSpacerVisibility(true, false);
            listBox.SetScrollSpacerVisibility(false, false);
            
            this.SendFilteringCallback();
        }
    },
    SendFilteringCallback: function(){
        this.currentCallbackIsFiltration = true;
        this.SendCallback();
    },
    FilteringOnClient: function(input){
        var filter = this.filter.toLowerCase();
        var lb = this.GetListBoxControl();
        var listTable = lb.GetListTable();
        var count = lb.GetItemCount();
        var text = "";
        var isSatisfy = false;
        var isFirstSatisfyItemFinded = false;
        
        if(this.isDropDownListStyle){
            var coincide = new Array(count);
            var maxCoincide = 0;
            for(var i = count - 1; i >= 0; i--){
                coincide[i] = this.GetCoincideCharCount(lb.GetItem(i).text.toLowerCase(), filter);
                if(coincide[i] > maxCoincide)
                    maxCoincide = coincide[i];
            }
            filter = filter.substr(0, maxCoincide);
            input.value = filter;
        }
        for(var i = 0; i < count; i ++){
            text = lb.GetItem(i).text; //TODO create able to get server-cached text
            isSatisfy = this.isDropDownListStyle ? (coincide[i] == maxCoincide) : 
                (text.toLowerCase().indexOf(filter) == 0);
            _aspxSetElementDisplay(listTable.rows[i], isSatisfy);
            if(!isFirstSatisfyItemFinded && isSatisfy){
                var isTextClearing = !this.isDropDownListStyle && this.filter == "" && this.filter != text;
                if(!isTextClearing)
                    this.FilteringHighlightComplitedText(text);
                this.SelectIndexSilent(lb, isTextClearing ? -1 : i);
                isFirstSatisfyItemFinded = true;
            }
        }
        if(this.isDropDownListStyle)
            this.filter = filter;
        if(!isFirstSatisfyItemFinded)
            this.HideDropDownArea(true);
        else
            this.VisibleCollectionChanged();
        this.isEnterLocked = false;
    },
    GetCoincideCharCount: function(text, filter) {
        while(filter != "" && text.indexOf(filter) != 0) {
            filter = filter.slice(0, -1);
        }
        return filter.length;
    },
    FilteringHighlightComplitedText: function(filterItemText){
        var lb = this.GetListBoxControl();
        var input = this.GetInputElement();
        var text = input.value;
        var valueLenght = text.length;
        var itemTextLenght = filterItemText.length;
        
        input.value = filterItemText;
        if(valueLenght < itemTextLenght)
            _aspxSetInputSelection(input, valueLenght, itemTextLenght);
    },
    FilteringStop: function(){
        if(this.isFilterEnabled){
            this.isEnterLocked = false;
            if(!this.isCallbackMode)
                this.FilteringStopClient();
        }
    },
    FilteringStopClient: function(){
        var lb = this.GetListBoxControl();
        var listTable = lb.GetListTable();
        var count = lb.GetItemCount();
        for(var i = 0; i < count; i ++)
            _aspxSetElementDisplay(listTable.rows[i], true);
        this.VisibleCollectionChanged();
    },
    // LoadingPanel
    ShowLoadingPanel: function() {    
        var lb = this.GetListBoxControl();
        var loadingParentElement = lb.GetScrollDivElement().parentNode;
        if(!_aspxIsExists(this.loadingDivElement))
            this.CreateLoadingDiv(loadingParentElement);
        if(!_aspxIsExists(this.loadingPanelElement))
            this.CreateLoadingPanelWithAbsolutePosition(loadingParentElement, loadingParentElement);
    },
    HideLoadingPanelOnCallback: function(){
        return false;
    },
    // CallbackMode
    FormatCallbackArg: function(prefix, arg) {
        return (_aspxIsExists(arg) ? prefix + "|" + arg.length + ';' + arg + ';' : "");
    },
    FilterChanged: function(){
        return this.filter != this.GetInputElement().value.toLowerCase();
    },
    OnCallback: function(result) {
        if(this.currentCallbackIsFiltration && this.FilterChanged()) {
            this.preventEndCallbackRising = true;
            _aspxSetTimeout("aspxCBFilterByTimer('" + this.name + "')", 0);
        } else {
            this.OnCallbackBeforeListBox();
            this.GetListBoxControl().OnCallback(result);
            this.OnCallbackInternal(result);
            this.OnCallbackFinally(true);
        }
    },
    DoEndCallback: function(){
        if(this.preventEndCallbackRising)
            this.preventEndCallbackRising = false;
        else
            ASPxClientDropDownEditBase.prototype.DoEndCallback.call(this);
    },
    OnCallbackError: function(result, data){
        this.GetListBoxControl().OnCallbackError(result);
        this.OnCallbackFinally(false);
    },
    OnCallbackFinally: function(isSuccessful){
        this.currentCallbackIsFiltration = false;
        this.CollectionChanged();
        this.HideLoadingDiv();
        this.HideLoadingPanel();
        this.isPerformCallback = false;
        this.changeSelectAfterCallback = 0;
        if(isSuccessful){
            if(this.isApplyAndCloseAfterCallback){
                this.OnApplyChangesAndCloseWithEvents();
                this.isApplyAndCloseAfterCallback = false;
            }
        }
    },
    OnCallbackBeforeListBox: function(){
        var lb = this.GetListBoxControl();
        this.changeSelectAfterCallback = lb.changeSelectAfterCallback;
    },
    OnCallbackCorrectSelectedIndex: function(){
        var lb = this.GetListBoxControl();
        if(this.changeSelectAfterCallback != 0)
            this.SetTextInternal(lb.GetSelectedItem().text);
    },
    OnCallbackInternal: function(result){
        this.OnCallbackCorrectSelectedIndex();
        this.OnFilterCallback(result);
    },
    OnFilterCallback: function(result){
        if(!this.currentCallbackIsFiltration && !this.isPerformCallback) //[Serj S.] isPerformCallback is used to avoid a breacking change
            return;
        
        var lb = this.GetListBoxControl();
        if(lb.GetItemCount() == 0)
            this.HideDropDownArea(true);
        else 
            this.OnFilterCallbackWithResult(lb);        
        this.isEnterLocked = false;
    },
    OnFilterCallbackWithResult: function(lb){
        this.OnFilterCallbackHighlightAndSelect(lb);
        var isNeedToKeepDropDownVisible = !this.isPerformCallback && !this.isLastFilteredKeyWasTab;
        if(isNeedToKeepDropDownVisible)
            this.EnshureShowDropDownArea();
    },
    OnFilterCallbackHighlightAndSelect: function(lb){
        var firstItemText = lb.GetItem(0).text;
        var isTextClearing = !this.isDropDownListStyle && this.filter == "" && this.filter != firstItemText;
        if(!isTextClearing){
            var isFilterRollBack = this.CheckForFilterRollback(lb, firstItemText);
            var isNonFilterChangingCallback = (lb.GetSelectedItem() == null);
            if(isFilterRollBack || isNonFilterChangingCallback){
                if(this.isLastFilteredKeyWasTab){
                    this.isLastFilteredKeyWasTab = false;
                    this.SelectIndex(0);
                    this.OnChange(); // B94483
                } else  {
                    this.FilteringHighlightComplitedText(firstItemText);
                    if(this.isPerformCallback )
                        this.SelectIndex(0); // this.isPerformCallback - Q96137, B30516 
                    else
                        this.SelectIndexSilent(lb, 0);
                }
            }
        }
    },
    CheckForFilterRollback: function(lb, firstItemText){
        var isHasCorrection = false;
        var filter = this.filter.toLowerCase();
        firstItemText = firstItemText.toLowerCase();
        
        while(firstItemText.substring(0, filter.length).toLowerCase() != filter){
            filter = filter.slice(0, -1);
            isHasCorrection = true;
        }
        if(isHasCorrection){
            this.filter = this.filter.substring(0, filter.length);
            this.GetInputElement().value = this.filter;
        } 
        return isHasCorrection;
    },
    SendCallback: function(){
        this.ShowLoadingPanel();
        ASPxClientComboBoxBase.prototype.SendCallback.call(this);
    },
    
    // Key Board support
    SelectNeighbour: function (step){
        if(this.isToolBarItem && !this.droppedDown) return;
        
        var lb = this.GetListBoxControl();
        var step = this.GetStepForClientFiltrationEnabled(lb, step);
        this.SelectNeighbourInternal(lb, step);
    },
    SelectNeighbourInternal: function(lb, step){
        if(this.droppedDown)
            this.lbEventLockCount ++;
        
        lb.SelectNeighbour(step);
        
        if(this.droppedDown){
            var selectedItem = lb.GetSelectedItem();
            this.OnSelectionChangedCore(selectedItem.text, selectedItem, true);
            this.lbEventLockCount --;
        } 
    },
    GetStepForClientFiltrationEnabled: function(lb, step){
        var isClientFiltrationEnabled = this.isFilterEnabled && !this.isCallbackMode;
        if(isClientFiltrationEnabled){
            var stepDirection = step > 0 ? 1 : -1;
            var startIndex = this.GetSelectedIndex();
            var count = lb.GetItemCount();
            var listTable = lb.GetListTable();
            var needVisibleItemCount = Math.abs(step);
            var outermostVisibleIndex = startIndex;
            
            for(var index = startIndex + stepDirection; needVisibleItemCount > 0; index += stepDirection){
                if(index < 0 || count <= index) break;
                
                if(_aspxGetElementDisplay(listTable.rows[index])){
                    outermostVisibleIndex = index;
                    needVisibleItemCount --;
                }
            }
            step = outermostVisibleIndex - this.GetSelectedIndex();
        }
        return step;
    },
    
    OnSpecialKeyDown: function(evt){
        if(this.isFilterEnabled && this.EventKeyCodeChangesTheInput(evt))
            this.FilterStopTimer();

        return ASPxClientEdit.prototype.OnSpecialKeyDown.call(this, evt);
    },
    OnArrowUp: function(evt){
        if(!this.isInitialized) return true;
        var isProcessed = ASPxClientDropDownEditBase.prototype.OnArrowUp.call(this, evt);
        if (!isProcessed)
            this.SelectNeighbour(-1);
        return true;
    },
    OnArrowDown: function(evt){
        if(!this.isInitialized) return true;
        var isProcessed = ASPxClientDropDownEditBase.prototype.OnArrowDown.call(this, evt);
        if (!isProcessed)
            this.SelectNeighbour(1);
        return true;
    },
    OnPageUp: function(){
        if(!this.isInitialized) return true;
        return this.OnPageButtonDown(false);
    },
    OnPageDown: function(){
        if(!this.isInitialized) return true;
        return this.OnPageButtonDown(true);
    },
    OnPageButtonDown: function(isDown){
        if(!this.isInitialized) return true;
        var lb = this.GetListBoxControl();
        if(_aspxIsExists(lb)){
            var direction = isDown ? 1 : -1;
            this.SelectNeighbour(lb.scrollPageSize * direction);
        }
        return true;
    },
    OnHomeKeyDown: function(evt){
        if(!this.isInitialized) return true;
        return this.OnHomeEndKeyDown(evt, true);
    },
    OnEndKeyDown: function(evt){
        if(!this.isInitialized) return true;
        return this.OnHomeEndKeyDown(evt, false);
    },
    OnHomeEndKeyDown: function(evt, isHome){
        if(!this.isInitialized) return true;
        var input = this.GetValueInput();
        if(input.readOnly || evt.ctrlKey){
            var lb = this.GetListBoxControl();
            var count = lb.GetItemCount();
            this.SelectNeighbour(isHome ? -count : count);
            return true;
        }
        return false;
    },
    OnEnter: function(){
        if(!this.isInitialized) return true;
        this.enterProcessed = this.droppedDown; // hack for defaultbutton
        if(!this.isEnterLocked) //Prevent to extra fast push enter while filtering continue
            this.OnApplyChangesAndCloseWithEvents();
        return this.enterProcessed;
    },
    OnTab: function(evt){
        if(!this.isInitialized) 
            return true;
        if(this.IsFilterTimerActive() || this.currentCallbackIsFiltration){
            this.isLastFilteredKeyWasTab = true;
            this.Filtering(); // B91550 Tab sends KeyDown without KeyUp
        }
        
        if(this.InCallback())
            this.isApplyAndCloseAfterCallback = true;
        else
            this.OnApplyChangesAndCloseWithEvents();
    },

    OnApplyChanges: function(){
        if(!this.focused || (this.isDropDownListStyle && !this.isFilterEnabled)) return;
        this.OnApplyChangesInternal();
    },
    OnApplyChangesAndCloseWithEvents: function(){
        this.OnApplyChangesInternal();
        this.HideDropDownArea(true);
    },
    OnApplyChangesInternal: function(){
        var text = this.GetInputElement().value;
        var isChanged = this.lastSuccessText != text;
        if(isChanged){
            var lb = this.GetListBoxControl();
            if(this.isDropDownListStyle && this.GetAdjustedSelectedIndexByText(lb, text) < 0){
                var lbItem = lb.GetSelectedItem();
                text = lbItem != null ? lbItem.text : this.lastSuccessText;
            }
        } 
        this.SetText(text);
        if(isChanged)
            this.OnChange();
    },
    OnButtonClick: function(number){
        if(number != this.dropDownButtonIndex){
            this.HideDropDownArea(true);
        }
        ASPxClientButtonEditBase.prototype.OnButtonClick.call(this, number);
    },
    OnCancelChanges: function(){
        var isCancelProcessed = ASPxClientDropDownEditBase.prototype.OnCancelChanges.call(this);
        var lb = this.GetListBoxControl();
        var index = this.GetAdjustedSelectedIndexByText(lb, this.lastSuccessText);
        this.SelectIndexSilent(lb, index);
        return isCancelProcessed;
    },
    OnCloseUp: function(evt){
        var evt = _aspxGetEvent(evt);
        var scrollDiv = this.GetListBoxControl().GetScrollDivElement();
        var scrollDivID = _aspxIsExists(scrollDiv) ? scrollDiv.id : "";
        if(__aspxFirefox && evt.type == "mouseup" && 
            (_aspxGetEventSource(evt).tagName == "DIV" && scrollDivID == _aspxGetEventSource(evt).id)) // Prevent FF closing DropDownArea by DropDownArea ScrollBar MouseUp
            return;
        ASPxClientDropDownEditBase.prototype.OnCloseUp.call(this, evt);
    },
    OnDDButtonMouseMove: function(evt){
        return (this.droppedDown ? _aspxCancelBubble(evt) : true);
    },
    CloseDropDownByDocumentOrWindowEvent: function(){
        this.OnApplyChangesInternal();
        ASPxClientDropDownEditBase.prototype.CloseDropDownByDocumentOrWindowEvent.call(this);
    },
    IsCanToDropDown: function(){
        return (this.GetListBoxControl().GetItemCount() > 0);
    },
    OnPopupControlShown: function(){
        if(!this.isInitialized) return;
        if(__aspxOpera) // B36477
            this.GetListBoxControl().RestoreScrollTopFromCache();
        if(this.IsScrollSpoilDDShowing())
            _aspxSetTimeout("aspxCBMozillaOverflowOn(\"" + this.name + "\")", 100);
        if(this.lockListBoxClick)
            delete this.lockListBoxClick;
        ASPxClientDropDownEditBase.prototype.OnPopupControlShown.call(this);
    },
    OnLBSelectedIndexChanged: function(){
        if(!this.lockListBoxClick) {
            this.OnSelectChanged();
        }
    },
    OnListBoxItemMouseUp: function(evt){
        if(!this.lockListBoxClick && !this.InCallback()){
            this.OnApplyChangesInternal();
            this.OnCloseUp(evt);
        }
    },
    OnMouseWheel: function(evt){
        if(!this.droppedDown){
            var wheelDelta = _aspxGetWheelDelta(evt);
            if(wheelDelta > 0)
			    this.SelectNeighbour(-1);
		    else  if(wheelDelta < 0)
			    this.SelectNeighbour(1);
			return _aspxPreventEvent(evt);
		}
    },
    OnSetFocus: function(isFocused){
        if(isFocused && this.isFilterEnabled && !this.isToolbarItem)
            this.SelectInputText();
        ASPxClientDropDownEditBase.prototype.OnSetFocus.call(this, isFocused);
    },
    OnOpenAnotherDropDown: function(){
        this.OnApplyChangesAndCloseWithEvents();
    },

    ParseValue: function() {
        var newText = this.GetInputElement().value;
        var oldText = this.GetText();
        if(oldText != newText){
            if(this.CanTextBeAccepted(newText, oldText)){
                this.SetText(newText);
                this.OnChange();
            } else
                this.SetTextInternal(oldText);
        }
    },
    CanTextBeAccepted: function(newText, oldText){
        var notAnyTextCanBeAccepted = this.isDropDownListStyle && oldText != "";
        if(notAnyTextCanBeAccepted){
            var lb = this.GetListBoxControl();
            var newTextPresentInItemCollection = this.GetAdjustedSelectedIndexByText(lb, newText) != -1;
            return newTextPresentInItemCollection;
        }
        return true;
    },

    MakeItemVisible: function(index){
        var lb = this.GetListBoxControl();
        lb.MakeItemVisible(index);
    },
    PerformCallback: function(arg) {
        this.isPerformCallback = true;
        this.filter = "";
        this.ClearItemsInternal();
        this.GetListBoxControl().PerformCallback(arg);
    },

    ClearItemsInternal: function(){
        ASPxClientComboBoxBase.prototype.ClearItemsInternal.call(this);
        var lbScrollDiv = this.GetListBoxScrollDivElement();
        if(_aspxIsExists(lbScrollDiv))
            lbScrollDiv.scrollTop = "0px";
    }
});

ASPxClientNativeComboBox = _aspxCreateClass(ASPxClientComboBoxBase, {
    constructor: function(name) {
        this.constructor.prototype.constructor.call(this, name);
        
        this.initSelectedIndex = -1;
        this.raiseValueChangedOnEnter = false;
    },
    Initialize: function(){
        var lb = this.GetListBoxControl();
        if(lb != null) lb.SetMainElement(this.GetMainElement());
        
        ASPxClientComboBoxBase.prototype.Initialize.call(this);
    },
    InitLastSuccessText: function(){
        this.SelectIndex(this.initSelectedIndex, true);
    },
    FindInputElement: function(){
        return this.GetMainElement();
    },    
    GetDropDownInnerControlName: function(suffix){
        return this.name + suffix;
    },
    PerformCallback: function(arg) {
        this.GetListBoxControl().PerformCallback(arg);
    },
    GetTextInternal: function(){
        var selectedItem = this.GetSelectedItem();
        return (selectedItem != null) ? selectedItem.text : "";
    },
    SetText: function (text){
        var lb = this.GetListBoxControl();
        var index = this.FindItemIndexByText(lb, text);
        this.SelectIndex(index, false);
        this.SetLastSuccessTest((index > -1) ? text : "");
        this.lastSuccessValue = (index > -1) ? lb.GetValue() : null;
        this.islastSuccessValueInit = true;
    },
    GetValue: function(){
        var selectedItem = this.GetSelectedItem();
        return (selectedItem != null) ? selectedItem.value : null;
    },
    SetValue: function(value){
        var lb = this.GetListBoxControl();
        lb.SetValue(value);
        // TODO Extract method with OnSelectChanged (params: value)
        var item = lb.GetSelectedItem();
        var text = _aspxIsExists(item) ? item.text : value;
        this.SetLastSuccessTest((item != null) ? text : "");
        this.lastSuccessValue = (item != null) ? item.value : null;
        this.islastSuccessValueInit = true;
    },
    ForceRefocusEditor: function(){
    },
    OnCallback: function(result) {
        this.GetListBoxControl().OnCallback(result);
        if(this.GetItemCount() > 0)
            this.SetSelectedIndex(0);
    },
    OnTextChanged: function() {
        this.OnChange();
    },
    SetTextInternal: function(text){
    },
    ChangeEnabledAttributes: function(enabled){
        this.GetMainElement().disabled = !enabled;
    }
});

// DropDown
var __aspxDropDownCollection = null;
function aspxGetDropDownCollection(){
    if(__aspxDropDownCollection == null)
        __aspxDropDownCollection  = new ASPxClientDropDownCollection();
    return __aspxDropDownCollection;
}

_aspxAttachEventToDocument("mousedown", aspxDropDownDocumentMouseDown);
function aspxDropDownDocumentMouseDown(evt){
    return aspxGetDropDownCollection().OnDocumentMouseDown(evt);
}
_aspxAttachEventToDocument("mouseup", aspxDropDownDocumentMouseUp);
function aspxDropDownDocumentMouseUp(evt){
    return aspxGetDropDownCollection().OnDocumentMouseUp(evt);
}

function aspxDDDropDown(name, evt){
    if(_aspxGetIsLeftButtonPressed(evt)){
        var dd = aspxGetControlCollection().Get(name);
        if(_aspxIsExists(dd))
            return dd.OnDropDown(evt);
    }
}
function aspxDDCloseUp(name, evt){
    var dd = aspxGetControlCollection().Get(name);
    dd.OnCloseUp(evt);
}

// ComboBox
function aspxDDBPCShown(name){
    var cb = aspxGetControlCollection().Get(name);
    if(cb != null) cb.OnPopupControlShown();
}
function aspxDDBRaiseDropDownByTimer(name){
    var cb = aspxGetControlCollection().Get(name);
    if(cb != null) cb.RaiseDropDown();
}
function aspxCBLBSelectedIndexChanged(name, evt){
    var cb = aspxGetControlCollection().Get(name);
    if(cb != null) cb.OnLBSelectedIndexChanged();
}
function aspxCBLBItemMouseUp(name, evt){
    var cb = aspxGetControlCollection().Get(name);
    if(cb != null) cb.OnListBoxItemMouseUp(evt);
}
function aspxCBMozillaOverflowOn(name){
    var cb = aspxGetControlCollection().Get(name);
    cb.EnableLBDivOverflow();
}
function aspxCBDDButtonMMove(evt){
    return aspxGetDropDownCollection().OnDDButtonMouseMove(evt);
}
function aspxCBMouseWheel(name, evt){
    var focusedCB = aspxGetDropDownCollection().GetFocusedDropDown();
    if(focusedCB != null && focusedCB.name == name)
        return focusedCB.OnMouseWheel(evt);
}
function aspxCBKeyUp(evt){
    var cb = aspxGetDropDownCollection().GetFocusedDropDown();
    if (cb != null) 
        cb.OnFilteringKeyUp(evt);
}
function aspxCBFilterByTimer(name){
    var cb = aspxGetControlCollection().Get(name);
    if(cb != null) cb.Filtering();
}
