

var __aspxLBSerializingSeparator = "|";
var __aspxLBSerializingSeparatorLength = __aspxLBSerializingSeparator.length;
var __aspxLoadRangeItemsCallbackPrefix = "LBCRI";
var __aspxLBIPostfixes = ['I', 'T'];
var __aspxLBIIdSuffix = "LBI";
var __aspxLBSIIdSuffix = __aspxLBIIdSuffix + "-1";
var __aspxLBTSIdSuffix = "_TS";
var __aspxLBBSIdSuffix = "_BS";
var __aspxLBHeaderDivIdSuffix = "_H";
var __aspxLTableIdSuffix = "_LBT";
var __aspxLEVISuffix = "_VI";
var __aspxLBDSuffix = "_D";
var __aspxEmptyItemsRange = "0:-1";
var __aspxNbsp = "&nbsp;";
var __aspxNbspChar = String.fromCharCode(160);

var __aspxCachedHoverItemKind = "cached" + __aspxHoverItemKind;
var __aspxCachedSelectedItemKind = "cached" + __aspxSelectedItemKind;
var __aspxCachedDisabledItemKind = "cached" + __aspxDisabledItemKind;

var ListBoxSelectionMode = { Single : 0, Multiple : 1, CheckColumn : 2 };
ASPxClientListEdit = _aspxCreateClass(ASPxClientEdit, {
    constructor: function(name) {
        this.constructor.prototype.constructor.call(this, name);
        this.SelectedIndexChanged = new ASPxClientEvent();
        
        //set from server
	    this.savedSelectedIndex = -1;
	},
    FindInputElement: function() {
        return this.FindStateInputElement();
    },
    FindStateInputElement: function(){
        return document.getElementById(this.name + __aspxLEVISuffix);
    },
    GetItem: function(index) {
        throw "Not implemented";
    },
    GetItemValue: function(index) {
        throw "Not implemented";
    },
    GetValue: function(){
        return this.GetItemValue(this.GetSelectedIndex());
    },    
    GetSelectedIndexInternal: function(){
        return this.savedSelectedIndex;
    }, 
    SetSelectedIndexInternal: function(index){
        this.savedSelectedIndex = index;
    },

    RaiseItemClick: function() {
        var processOnServer = this.autoPostBack;
        if(!this.ItemClick.IsEmpty()){
            var args = new ASPxClientProcessingModeEventArgs(processOnServer);
            this.ItemClick.FireEvent(this, args);
            processOnServer = args.processOnServer;
        }
        return processOnServer;
    },
    RaiseItemDoubleClick: function() {
        var processOnServer = this.autoPostBack;
        if(!this.ItemDoubleClick.IsEmpty()){
            var args = new ASPxClientProcessingModeEventArgs(processOnServer);
            this.ItemDoubleClick.FireEvent(this, args);
            processOnServer = args.processOnServer;
        }
        return processOnServer;
    },
    RaiseValueChangedEvent: function() {
        if(!this.isInitialized) return false;
        var processOnServer = ASPxClientEdit.prototype.RaiseValueChangedEvent.call(this);
        processOnServer = this.RaiseValueChangedAdditionalEvents(processOnServer);
        return processOnServer;
    },
    RaiseValueChangedAdditionalEvents: function(processOnServer){
        return this.RaiseSelectedIndexChanged(processOnServer);
    },
    RaiseSelectedIndexChanged: function(processOnServer) {
        if(!this.SelectedIndexChanged.IsEmpty()){
            var args = new ASPxClientProcessingModeEventArgs(processOnServer);
            this.SelectedIndexChanged.FireEvent(this, args);
            processOnServer = args.processOnServer;
        }
        return processOnServer;
    },
    
    UpdateHiddenInputs: function(){
        var element = this.FindStateInputElement();
        if(_aspxIsExistsElement(element)) {
            var value = this.GetValue();
            if (value == null)
                value = "";
            element.value = value;
        }
    },
    GetSelectedItem: function(){
        var index = this.GetSelectedIndexInternal();
        return this.GetItem(index);
    },
    GetSelectedIndex: function(){
        return this.GetSelectedIndexInternal();
    },
    SetSelectedItem: function(item){
        var index = (item != null) ? item.index : -1;
        this.SetSelectedIndex(index);
    },
    SetSelectedIndex: function(index){
        this.SelectIndexSilent(index);
    },
    SelectIndexSilent: function(index){
        throw "Not implemented";
    }
});
    // [Seleznyov] The selected field and the GetColumnText and GetColumnText methods defined in the ASPxClientListBoxItem.
    // This is made to simplify the help
ASPxClientListEditItem = _aspxCreateClass(null, {
	constructor: function(listEditBase, index, text, value, imageUrl){
	    this.listEditBase = listEditBase;
        this.index = index;
        this.imageUrl = imageUrl;
        this.text = text;
        this.value = value;
    }
});
ASPxClientListBoxItem = _aspxCreateClass(ASPxClientListEditItem, {
	constructor: function(listEditBase, index, texts, value, imageUrl, selected){
	    this.constructor.prototype.constructor.call(this, listEditBase, index, null, value, imageUrl);
        
        this.selected = selected ? selected : false;
        this.texts = texts;
        this.text = listEditBase.FormatText(texts);
    },
    GetColumnText: function(columnIndexOrFieldName){
        var columnIndex = -1;
        if(typeof(columnIndexOrFieldName) == "string")
            columnIndex = _aspxArrayIndexOf(this.listEditBase.columnFieldNames, columnIndexOrFieldName);
        else if(typeof(columnIndexOrFieldName) == "number")
            columnIndex = columnIndexOrFieldName;
            
        return this.GetColumnTextByIndex(columnIndex);
    },
    GetColumnTextByIndex: function(columnIndex){
        if(0 <= columnIndex && columnIndex < this.texts.length)
            return this.texts[columnIndex];
        else
            return null;
    }
});

_aspxListBoxScrollCallbackHelperBase = _aspxCreateClass(null, {
    constructor: function(listBoxControl) {
        this.listBoxControl = listBoxControl;
        this.itemsRange = "";
        this.defaultItemsRange = "0:" + (this.listBoxControl.callbackPageSize - 1);
    },
    OnScroll: function(){ },
    Reset: function(){ },
    IsScrolledToTopSpacer: function(){ return false; },
    IsScrolledToBottomSpacer: function(){ return false; },
    GetIsNeedToHideTopSpacer: function(){ return false; },
    GetIsNeedCallback: function(){ return false; },
    GetItemsRangeForLoad: function(){ return this.defaultItemsRange; },
    SetItemsRangeForLoad: function(){}
});
_aspxListBoxScrollCallbackHelper = _aspxCreateClass(_aspxListBoxScrollCallbackHelperBase, {
    constructor: function(listBoxControl) {
        this.constructor.prototype.constructor.call(this, listBoxControl);
        this.isScrolledToTopSpacer = false;
        this.isScrolledToBottomSpacer = false;
    },
    OnScroll: function(){
        this.DetectScrollDirection();
        this.ResetItemsRange();
        if(this.GetIsAnySpacerVisible())
            this.RecalcItemsRangeForLoad();
    },
    DetectScrollDirection: function(){
        var listBoxControl = this.listBoxControl;
        var divElement = listBoxControl.GetScrollDivElement();
        var listTable = listBoxControl.GetListTable();
        var scrollTop = divElement.scrollTop;
        var scrollBottom = divElement.scrollTop + divElement.clientHeight;
        var isTopSpacerVisible = listBoxControl.GetScrollSpacerVisibility(true);
        var isBottomSpacerVisible = listBoxControl.GetScrollSpacerVisibility(false);
        
        var topSpacerHeight = listBoxControl.GetScrollSpacerVisibility(true) ? parseInt(listBoxControl.GetScrollSpacerElement(true).clientHeight) : 0;
        
        this.isScrolledToTopSpacer = (scrollTop < topSpacerHeight) && isTopSpacerVisible;
        this.isScrolledToBottomSpacer = (scrollBottom >= topSpacerHeight + listTable.clientHeight) && isBottomSpacerVisible;
    },
    Reset: function(){
        this.ResetItemsRange();
        this.isScrolledToTopSpacer = false;
        this.isScrolledToBottomSpacer = false;
    },
    ResetItemsRange: function(){
        this.itemsRange = "";
    },
    RecalcItemsRangeForLoad: function(){
        if(this.listBoxControl.isCallbackMode) {
            if(this.isScrolledToTopSpacer || this.isScrolledToBottomSpacer)
                this.SetItemsRangeForLoad(this.isScrolledToTopSpacer);
        }
    },
    IsScrolledToTopSpacer: function(){
        return this.isScrolledToTopSpacer;
    },
    IsScrolledToBottomSpacer: function(){
        return this.isScrolledToBottomSpacer;
    },
    GetIsAnySpacerVisible: function(){
        return this.isScrolledToTopSpacer || this.isScrolledToBottomSpacer;
    },
    GetIsNeedCallback: function(){
        return !this.GetIsItemsRangeEmpty();
    },
    GetIsNeedToHideTopSpacer: function(){
        return this.isScrolledToTopSpacer && this.GetIsItemsRangeEmpty();
    },
    GetItemsRangeForLoad: function(){
        return (!this.GetIsItemsRangeEmpty() ? this.itemsRange : this.defaultItemsRange);
    },
    SetItemsRangeForLoad: function(isForTop){
        var listbox = this.listBoxControl;
        var beginIndex = isForTop ? 
            listbox.serverIndexOfFirstItem - listbox.callbackPageSize : 
            listbox.serverIndexOfFirstItem + listbox.GetItemCount();
        beginIndex = beginIndex < 0 ? 0 : beginIndex;
        
        var endIndex = isForTop ? 
            listbox.serverIndexOfFirstItem - 1 : 
            beginIndex + listbox.callbackPageSize - 1;
    
        this.itemsRange = beginIndex + ":" + endIndex;
        this.isScrolledToTopSpacer = isForTop;
        this.isScrolledToBottomSpacer = !isForTop;
    },
    GetIsItemsRangeEmpty: function(){
        return (this.itemsRange == "" || this.itemsRange == __aspxEmptyItemsRange);
    }
});
ASPxClientListBoxBase = _aspxCreateClass(ASPxClientListEdit, {
    constructor: function(name) {
        this.constructor.prototype.constructor.call(this, name);
        
        this.APILockCount = 0;
        this.autoScrollLockCount = 0;
        this.isComboBoxList = false;
        this.isSyncEnabled = true;
        this.ownerName = "";
        this.selectionEventsLockCount = 0;
        this.syncLockCount = 0;
        this.encodeHtml = true;

        this.serializingHelper = null;
        this.deletedItems = [];
        this.insertedItems = [];
        this.itemsValue = [];    
        this.ItemDoubleClick = new ASPxClientEvent();

        this.ItemClick = new ASPxClientEvent();
    },
    
    LockAutoScroll: function(){
        this.autoScrollLockCount++;
    },
    UnlockAutoScroll: function(){
        this.autoScrollLockCount--;
    },
    LockSelectionEvents: function(){
		this.selectionEventsLockCount++;
    },
	UnlockSelectionEvents: function(){
		this.selectionEventsLockCount--;
    },
	IsSelectionEventsLocked: function(){
		return this.selectionEventsLockCount > 0;
	},
    GetItemCount: function(){
        return 0;
    },
    GetItemValue: function(index){
        if(0 <= index && index < this.GetItemCount())
            return this.PrepareItemValue(this.itemsValue[index]);
        return null;
    },
    GetItemTexts: function(item) {
        return item.text;
    },
    PrepareItemValue: function(value) {
        return (typeof(value) == "string" && value == "" && this.convertEmptyStringToNull) ? null : value;
    },
    LoadItemsFromCallback: function(isToTop, itemStrings){
    },
    SetValue: function(value){
        var index = this.GetItemIndexByValue(value);
        this.SelectIndexSilentAndMakeVisible(index);
    },
    GetItemIndexByValue: function(value){
        for(var i = this.GetItemCount() - 1; i >= 0 ; i--){
            if(this.GetItemValue(i) == value)
                break;
        }
        return i;
    },
    SelectIndex: function (index){ // TODO try remove it
        if(this.SelectIndexSilentAndMakeVisible(index, false)){
            this.RaisePersonalStandardValidation();
            this.OnValueChanged();
        }
    },
    SelectIndexSilentAndMakeVisible: function(index){
        var selectionChanged = this.SelectIndexSilent(index);
        if(this.autoScrollLockCount == 0)
            this.MakeItemVisible(index);
        return selectionChanged;
    },

    // API
    MakeItemVisible: function(index){
    },
    InitOnContainerMadeVisible: function(){
    },
    AddItem: function(texts, value, imageUrl){
        var index = this.GetItemCount();
        this.InsertItemInternal(index, texts, value, imageUrl);
        return index;
    },
    InsertItem: function(index, texts, value, imageUrl){
        this.InsertItemInternal(index, texts, value, imageUrl);
    },
    InsertItemInternal: function(index, text, value, imageUrl){
    },
    BeginUpdate: function(){
        this.APILockCount ++;
    },
    EndUpdate: function(){
        this.APILockCount --;
        this.Synchronize();
    },
    ClearItems: function(){
        this.BeginUpdate();
        this.UpdateArraysItemsCleared();
        this.ClearItemsCore();
        this.EndUpdate();
    },
    ClearItemsCore: function(){
    },
    ClearItemsForPerformCallback: function(){
        this.itemsValue = [];
        this.ClearItemsCore();
    },
    RemoveItem: function(index){
    },
    GetItem: function(index){
        return null;
    },
    PerformCallback: function(arg) {
    },
    GetCallbackArguments: function(){
        var args = this.GetCustomCallbackArg();
        args += this.GetLoadItemsRangeCallbackArg();
        return args;
    },
    GetLoadItemsRangeCallbackArg: function(){
        return this.FormatCallbackArg(__aspxLoadRangeItemsCallbackPrefix, this.GetItemsRangeForLoad());
    },
    FormatCallbackArg: function(prefix, arg) { // REFACTOR with ASPxGrigView, replace to Callback.js
        arg = arg.toString();
        return (_aspxIsExists(arg) ? prefix + "|" + arg.length + ';' + arg + ';' : "");
    },
    GetItemsRangeForLoad: function(){
        return __aspxEmptyItemsRange;
    },
    GetCallbackOwnerControl: function(){
        if(this.ownerName != "" && !_aspxIsExists(this.ownerControl))
            this.ownerControl = aspxGetControlCollection().Get(this.ownerName);
        return this.ownerControl;
    },
    GetCustomCallbackArg: function(){
        return this.GetSyncHiddenInput("CustomCallback").value;
    },
    SetCustomCallbackArg: function(arg){
        this.GetSyncHiddenInput("CustomCallback").value = arg;
    },
    FormatAndSetCustomCallbackArg: function(arg){
        var formatArg = this.FormatCallbackArg("LECC", _aspxIsExists(arg) ? arg : "");
        this.SetCustomCallbackArg(formatArg);
    },
    SendCallback: function(){
    },
    
    LockSynchronization: function(){
        this.syncLockCount++;
    },
    UnlockSynchronization: function(){
        this.syncLockCount--;
    },
    IsSyncLocked: function(){
        return this.syncLockCount > 0;
    },
    IsSyncEnabled: function(){
        return this.isSyncEnabled && !this.IsSyncLocked();
    },
    RegisterInsertedItem: function(index, text, value, imageUrl){
        if(this.IsSyncEnabled()){
            this.RefreshSynchroArraysIndex(index, true);
            var item = this.CreateItem(index, text, value, imageUrl);
            _aspxArrayPush(this.insertedItems, item);
            this.Synchronize();
        }
    },
    CreateItem: function(index, text, value, imageUrl){
        return new ASPxClientListEditItem(this, index, text, value, imageUrl);
    },
    
    UpdateSyncArraysItemDeleted: function(item, isValueRemovingRequired){
        if(isValueRemovingRequired)
            _aspxArrayRemoveAt(this.itemsValue, item.index);
        if(this.IsSyncEnabled()){
            var index = this.FindItemInArray(this.insertedItems, item);
            if(index == -1){
                this.RefreshSynchroArraysIndex(item.index, false);
                _aspxArrayPush(this.deletedItems, item);
            } else {
                this.RefreshSynchroArraysIndex(item.index, false);
                _aspxArrayRemoveAt(this.insertedItems, index);
            }
            this.Synchronize();
        }
    },
    UpdateArraysItemsCleared: function(){
        if(this.IsSyncEnabled()){
            for(var i = this.GetItemCount() - 1; i >= 0; i --)
                this.UpdateSyncArraysItemDeleted(this.GetItem(i), false);
        } 
        this.itemsValue = [];
    },
    RefreshSynchroArraysIndex: function(startIndex, isIncrease){
        this.RefreshSynchroArrayIndexIndex(this.deletedItems, startIndex, isIncrease);
        this.RefreshSynchroArrayIndexIndex(this.insertedItems, startIndex, isIncrease);
    },
    RefreshSynchroArrayIndexIndex: function(array, startIndex, isIncrease){
       var delta = isIncrease ? 1 : -1;
       for(var i = 0; i < array.length; i ++){
            if(array[i].index >= startIndex)
                array[i].index += delta;
        }   
    },
    FindItemInArray: function(array, item){
	    for(var i = array.length - 1; i >= 0; i--){
	        var currentItem = array[i];
	        
	        // B139647 if EncodeHtml = false then the texts could be different (one with tags and another without).
            if ((!this.encodeHtml || currentItem.text == item.text) && currentItem.value == item.value &&
                currentItem.imageUrl == item.imageUrl)
	            break;
	    }
	    return i;
    },

    GetSyncHiddenInput: function(syncType){
        return _aspxGetElementById(this.name + syncType);
    },
    Synchronize: function(){
        if(this.APILockCount == 0){
            if(this.IsSyncEnabled()){
                this.SynchronizeItems(this.deletedItems, "DeletedItems");
                this.SynchronizeItems(this.insertedItems, "InsertedItems");
            }
            this.CorrectSizeByTimer();
        }
    },
    CorrectSizeByTimer: function(){
    },
    SynchronizeItems: function(items, syncType){
        var inputElement = this.GetSyncHiddenInput(syncType);
        if(!_aspxIsExistsElement(inputElement))
            return;

        inputElement.value = _aspxEncodeHtml(this.SerializeItems(items));
    },
    
    GetSerializingHelper: function(){ 
        if(this.serializingHelper == null)
            this.serializingHelper = this.CreateSerializingHelper();
        return this.serializingHelper;
    },
    CreateSerializingHelper: function(){
        return new _aspxListBoxBaseItemsSerializingHelper(this);
    },
    SerializeItems: function(items){
        var serialiser = this.GetSerializingHelper();
        return serialiser.SerializeItems(items);
    },
    DeserializeItems: function(serializedItems){
        var serialiser = this.GetSerializingHelper();
        return serialiser.DeserializeItems(serializedItems);
    }
});

_aspxListBoxBaseItemsSerializingHelper = _aspxCreateClass(null, {
    constructor: function(listBoxControl) {
        this.listBoxControl = listBoxControl;
        this.startPos = 0;
    },
    SerializeItems: function(items){
        var sb = new ASPxStringBuilder();
        for(var i = 0; i < items.length; i++)
            this.SerializeItem(sb, items[i]);
        
        return sb.ToString();
    },
    SerializeItem: function(sb, item) {
        if(!_aspxIsExists(item))
            return;

        this.SerializeAtomValue(sb, item.index);
        this.SerializeAtomValue(sb, item.value);
        this.SerializeAtomValue(sb, item.imageUrl);
        
        var texts = this.listBoxControl.GetItemTexts(item);
        if(typeof(texts) == "string")
            this.SerializeAtomValue(sb, texts);
        else {
            for(var i = 0; i < texts.length; i++)
                this.SerializeAtomValue(sb, texts[i]);
        }
    },
    SerializeAtomValue: function(sb, value) {
        var valueStr = _aspxIsExists(value) ? value.toString() : "";
        sb.Append(valueStr.length);
        sb.Append('|');
        sb.Append(valueStr);
    },
    
    DeserializeItems: function(serializedItems){
        var deserializedItems = [];
        var item;
        this.startPos = 0;
        while(this.startPos < serializedItems.length){
            var index = this.ParseItemIndex(serializedItems);
            var value = this.ParseItemValue(serializedItems);
            var imageUrl = this.ParseString(serializedItems);
            if(imageUrl == "")
                imageUrl = this.listBoxControl.defaultImageUrl;
            var texts = this.ParseTexts(serializedItems);

            item = this.listBoxControl.CreateItem(index, texts, value, imageUrl);
            _aspxArrayPush(deserializedItems, item);
        }
        return deserializedItems;
    },
    ParseItemIndex: function(serializedItem){
        return parseInt(this.ParseString(serializedItem));
    },
    ParseItemValue: function(serializedItem){
        return this.ParseString(serializedItem);
    },
    ParseString: function(str){
        var indexOfSeparator = str.indexOf(__aspxLBSerializingSeparator, this.startPos);
        var strLength = parseInt(str.substring(this.startPos, indexOfSeparator));
        var strStartPos = indexOfSeparator + __aspxLBSerializingSeparatorLength;
        this.startPos = strStartPos + strLength;
        
        return str.substring(strStartPos, strStartPos + strLength);
    },
    ParseTexts: function(serializedItems){
        return this.ParseString(serializedItems);
    }
});

_aspxListBoxItemsSerializingHelper = _aspxCreateClass(_aspxListBoxBaseItemsSerializingHelper, {
    constructor: function(listBoxControl) {
        this.constructor.prototype.constructor.call(this, listBoxControl);
    },
    ParseTexts: function(serializedItems){
        var textColumnCount = this.listBoxControl.GetItemTextCellCount();
        return (textColumnCount > 1) ? this.DeserializeItemTexts(serializedItems, textColumnCount) 
            : this.constructor.prototype.ParseTexts.call(this, serializedItems);
    },
    DeserializeItemTexts: function(serializedItem, textColumnCount){
        var text = "";
        var texts = [];
        for(var i = 0; i < textColumnCount; i++)
            _aspxArrayPush(texts, this.ParseString(serializedItem));
        return texts;
    }
});

_aspxListBoxSingleSelectionHelper = _aspxCreateClass(null, {
    constructor: function(listBoxControl) {
        this.listBoxControl = listBoxControl;
        this.savedSelectedIndex = -1;
        this.updateHiddenInputsLockCount = 0;
        this.cachedSelectionChangedArgs = [];
    },
    
    GetSelectedIndexInternal: function(){
        return this.savedSelectedIndex;
    }, 
    SetSelectedIndexInternal: function(index){
        this.savedSelectedIndex = index;
    }, 
    SetSelectedIndexCore: function(index){
        if(index != this.savedSelectedIndex && -1 <= index && index < this.GetItemCount()){
            this.BeginSelectionUpdate();
            this.SetSelectedIndexInternal(index);
            this.EndSelectionUpdate();
            return true;
        }
        return false;
    },
    GetSelectedIndex: function(){
        return this.GetSelectedIndexInternal();
    },
    SetSelectedIndex: function(index){
        this.ChangeSelectedItem(index);
        this.SetSelectedIndexCore(index);
        this.OnItemSelectionChanged(index, true);
    },
    GetSelectedIndices: function(){ 
        var selectedIndex = this.GetSelectedIndexInternal();
        return selectedIndex != -1 ? [selectedIndex] : [];
    },
    GetSelectedValues: function(){ 
        var selectedValue =  this.listBoxControl.GetValue();
        return selectedValue != null ? [selectedValue] : [];
    },
    GetSelectedItems: function(){ 
        var selectedItem = this.listBoxControl.GetSelectedItem();
        return selectedItem != null? [selectedItem] : [];
    },
    
    SelectIndices: function(indices){},
    SelectItems: function(items){},
    SelectValues: function(values){},
    UnselectIndices: function(selected){},
    UnselectItems: function(items){},
    UnselectValues: function(values){},
    
    GetIsItemSelected: function(index){ return index == this.GetSelectedIndexInternal(); },
    
    ResetSelectionCollectionsCache: function(){ },
    
    OnItemClick: function(index, evt){
        var selected = true;
        this.BeginSelectionUpdate();
        this.ChangeSelectedItem(index);
        var selectedIndexChanged = this.SetSelectedIndexCore(index);
        this.EndSelectionUpdate();
        if(selectedIndexChanged)
            this.OnItemSelectionChanged(index, selected);
    },
    ChangeSelectedItem: function(newSelectedIndex){
        var selected = true;
        var oldSelectedIndex = this.GetSelectedIndexInternal();
        this.BeginSelectionUpdate();
        this.SetItemSelectionState(oldSelectedIndex, !selected);
        this.SetItemSelectionState(newSelectedIndex, selected);
        this.EndSelectionUpdate();
    },
    SetItemSelectionState: function(itemIndex, selected, controller){
        this.BeginSelectionUpdate();
        this.listBoxControl.SetItemSelectionState(itemIndex, selected, controller);
        this.EndSelectionUpdate();
    },
    GetFocusedIndex: function(){
        return this.GetSelectedIndexInternal();
    },
    BeginSelectionUpdate: function(){
        this.updateHiddenInputsLockCount++;
    },
    EndSelectionUpdate: function(){
        this.updateHiddenInputsLockCount--;
        if(!this.IsUpdateInternalSelectionStateLocked()){
            this.listBoxControl.UpdateInternalState();
            this.FlushSelectionChanged();
        }
    },
    IsUpdateInternalSelectionStateLocked: function(){
        return this.updateHiddenInputsLockCount > 0;
    },
    GetItemCount: function(){
        return this.listBoxControl.GetItemCount();
    },
    OnItemSelectionChanged: function(index, selected){
        if(this.IsUpdateInternalSelectionStateLocked()){
            var a = {Index: index, Selected: selected};
            this.cachedSelectionChangedArgs.push(a);
        }
        else 
            this.listBoxControl.OnItemSelectionChanged(index, selected);
    },
    FlushSelectionChanged: function(){
        if(this.IsUpdateInternalSelectionStateLocked()) 
            return;
        
        for(var i = 0; i < this.cachedSelectionChangedArgs.length; i++)
            this.listBoxControl.OnItemSelectionChanged(this.cachedSelectionChangedArgs[i].Index, this.cachedSelectionChangedArgs[i].Selected);
        this.cachedSelectionChangedArgs = [];
    },
    OnItemInserted: function(index){
        if(index <= this.savedSelectedIndex && this.savedSelectedIndex != -1)
            this.SetSelectedIndexInternal(this.savedSelectedIndex + 1);
    },
    OnItemRemoved: function(index){
        var selectedIndex = this.GetSelectedIndex();
        if(index < this.savedSelectedIndex)
            this.SetSelectedIndexInternal( this.savedSelectedIndex - 1);
        else if(index == this.savedSelectedIndex)
            this.SetSelectedIndexInternal(-1);
    }
});
_aspxListBoxMultiSelectionHelper = _aspxCreateClass(_aspxListBoxSingleSelectionHelper, {
    constructor: function(listBoxControl) {
        this.constructor.prototype.constructor.call(this, listBoxControl);
        this.selectedValuesCache = [];
        this.selectedItemsCache = [];
        this.savedSelectedIndices = [];
        this.selectedIndicesSortingRequired = false;
        this.focusedIndex = -1;
        this.lastIndexFocusedWithoutShift = -1;
    },

    SetSelectedIndex: function(index){
        this.SingleIndexSelection(index);
    },
    ResetSelectionCollectionsCache: function(){
        this.selectedIndicesSortingRequired = true;
        this.selectedItemsCache = [];
        this.selectedValuesCache = [];
    },
    GetSelectedIndices: function(){
        if(this.savedSelectedIndices.length > 1 && this.selectedIndicesSortingRequired)
            this.SortSelectedIndices();
        return this.savedSelectedIndices.slice();
    },
    GetSelectedValues: function(){ 
        if(this.savedSelectedIndices.length == 0)
            return [];
        if(this.selectedValuesCache.length == 0)
            this.selectedValuesCache = this.GetSelectedValuesCore();
        return this.selectedValuesCache;
    },
    GetSelectedValuesCore: function(){
        var selectedValues = [];
        var selectedItems = this.GetSelectedItems();
        for(var i = 0; i < selectedItems.length; i++)
            selectedValues.push(selectedItems[i].value);
        return selectedValues;
    },
    GetSelectedItems: function(){
        if(this.savedSelectedIndices.length == 0)
            return [];
        if(this.selectedItemsCache.length == 0)
            this.selectedItemsCache = this.GetSelectedItemsCore();
        return this.selectedItemsCache;
    },
    GetSelectedItemsCore: function(){
        var selectedItems = [];
        for(var i = 0; i < this.savedSelectedIndices.length; i++)
            selectedItems.push(this.listBoxControl.GetItem(this.savedSelectedIndices[i]));
        return selectedItems;
    },

    SetIndicesSelectionState: function(indices, selected){
        this.BeginSelectionUpdate();
        var controller = aspxGetStateController();
        if(indices){
            for(var i = 0; i < indices.length; i++)
                this.SetItemSelectionState(indices[i], selected, controller);
        } else
            this.SetAllItemsSelectionState(selected, controller);
        this.SetSelectedIndexCore(this.GetFirstSelectedIndex());
        this.EndSelectionUpdate();
    },
    SetItemsSelectionState: function(items, selected){
        var indices = items ? this.ConvertItemsToIndices(items) : null;
        this.SetIndicesSelectionState(indices, selected);
    },
    SetValuesSelectionState: function(values, selected){
        var indices = values ? this.ConvertValuesToIndices(values)  : null;
        this.SetIndicesSelectionState(indices, selected);
    },
    ConvertValuesToIndices: function(values){
        var indices = [];
        for(var i = 0; i < values.length; i++)
            indices.push(this.listBoxControl.GetItemIndexByValue(values[i]));
        return indices;
    },
    ConvertItemsToIndices: function(items){
        var indices = [];
        for(var i = 0; i < items.length; i++)
            indices.push(items[i].index);
        return indices;
    },

    SelectIndices: function(indices){
        this.SetIndicesSelectionState(indices, true);
    },
    SelectItems: function(items){
        this.SetItemsSelectionState(items, true);
    },
    SelectValues: function(values){
        this.SetValuesSelectionState(values, true);
    },
    UnselectIndices: function(indices){
        this.SetIndicesSelectionState(indices, false);
    },
    UnselectItems: function(items){
        this.SetItemsSelectionState(items, false);
    },
    UnselectValues: function(values){
        this.SetValuesSelectionState(values, false);        
    },

    GetIsItemSelected: function(index){ 
        return _aspxArrayIndexOf(this.savedSelectedIndices, index) != -1; 
    },
    
    OnItemClick: function(index, evt){
        this.BeginSelectionUpdate();
        var ctrlKey = evt.ctrlKey || evt.metaKey;
        var shift = evt.shiftKey;
        
        if(ctrlKey)
            this.AddSelectedIndex(index);
        else if(shift){
            var startIndex = index > this.lastIndexFocusedWithoutShift ? this.lastIndexFocusedWithoutShift + 1 : index;
            var endIndex = index > this.lastIndexFocusedWithoutShift ? index : this.lastIndexFocusedWithoutShift - 1;
            this.SelectRangeIndicesOnly(startIndex, endIndex);
            this.SetFocusedIndexInternal(index, true);
        }else 
            this.SingleIndexSelection(index);
        this.EndSelectionUpdate();
    },
    OnItemCheckBoxClick: function(index, evt){
        this.BeginSelectionUpdate();
        this.AddSelectedIndex(index);
        this.EndSelectionUpdate();
    },
    AddSelectedIndex: function(index){
        this.SetFocusedIndexInternal(index, false);
        var indexInSelectedIndices = _aspxArrayIndexOf(this.savedSelectedIndices, index);
        var selectionOperation = indexInSelectedIndices == -1;
        
        this.SetItemSelectionState(index, selectionOperation);
        this.SetSelectedIndexCore(this.GetFirstSelectedIndex());
    },
    SelectRangeIndicesOnly: function(startIndex, endIndex){
        this.BeginSelectionUpdate();
        var controller = aspxGetStateController();
        var itemCount = this.GetItemCount();
        for(var i = 0; i < itemCount; i ++) {
            if(i == this.lastIndexFocusedWithoutShift) 
                continue;
            this.SetItemSelectionState(i, i >= startIndex && i <= endIndex, controller);
        }
        this.SetSelectedIndexCore(this.GetFirstSelectedIndex());
        this.EndSelectionUpdate();
    },
    SingleIndexSelection: function(index){
        this.SetFocusedIndexInternal(-1, false);
        this.SelectRangeIndicesOnly(index, index);
        this.SetFocusedIndexInternal(index, false);
    },
    
    SetAllItemsSelectionState: function(selected, controller){
        this.BeginSelectionUpdate();
        if(!controller)
            controller = aspxGetStateController();
            
        var itemCount = this.GetItemCount();
        for(var i = 0; i < itemCount; i ++)
            this.SetItemSelectionState(i, selected, controller);
        this.EndSelectionUpdate();
    },
    SetItemSelectionState: function(itemIndex, selected, controller){
        this.SetItemSelectionStateCore(itemIndex, selected, controller);
        this.ResetSelectionCollectionsCache();
        
        var indexInSelectionArray = _aspxArrayIndexOf(this.savedSelectedIndices, itemIndex);
        if(selected && indexInSelectionArray == -1){
            this.PushSelectedIndex(itemIndex);
            this.OnItemSelectionChanged(itemIndex, true);
        }
        if(!selected && indexInSelectionArray != -1){
            this.RemoveSelectedIndex(indexInSelectionArray);
            this.OnItemSelectionChanged(itemIndex, false);
        }
    },
    // Internal
    GetFirstSelectedIndex: function(){
        var selectedIndices = this.GetSelectedIndices();
        var selectedIndicesCount = selectedIndices.length;
        var firstSelectedIndex = -1;
        if(selectedIndicesCount > 0){
            firstSelectedIndex = selectedIndices[0];
            for(var i = 1; i < selectedIndices.length; i++){
                if(firstSelectedIndex > selectedIndices[i])
                    firstSelectedIndex = selectedIndices[i];
            }
        }
        return firstSelectedIndex;
    },
    PushSelectedIndex: function(index){
        this.savedSelectedIndices.push(index);
    },
    RemoveSelectedIndex: function(index){
        _aspxArrayRemoveAt(this.savedSelectedIndices, index);
    },
    SortSelectedIndices: function(){
        _aspxArrayIntegerAscendingSort(this.savedSelectedIndices);
        this.selectedIndicesSortingRequired = false;
    },
    SetItemSelectionStateCore: function(itemIndex, selected, controller){
        _aspxListBoxSingleSelectionHelper.prototype.SetItemSelectionState.call(this, itemIndex, selected, controller);
    },
    GetFocusedIndex: function(){
        return this.focusedIndex;
    },
    SetFocusedIndexInternal: function(index, isShiftPressed){
        if(!isShiftPressed)
            this.lastIndexFocusedWithoutShift = index;
        this.focusedIndex = index;
    },
    OnItemInserted: function(index){
        this.ResetSelectionCollectionsCache();
        _aspxListBoxSingleSelectionHelper.prototype.OnItemInserted.call(this, index);
        
        if(this.focusedIndex >= index)
            this.focusedIndex ++;
        
        for(var i = 0; i < this.savedSelectedIndices.length; i++){
            if(this.savedSelectedIndices[i] >= index)
                this.savedSelectedIndices[i]++;
        }
    },
    OnItemRemoved: function(index){
        this.ResetSelectionCollectionsCache();
        _aspxListBoxSingleSelectionHelper.prototype.OnItemRemoved.call(this, index);
        
        if(this.focusedIndex == index)
            this.focusedIndex = -1;
        else if(this.focusedIndex > index)
            this.focusedIndex --;
        
        if(this.GetIsItemSelected(index))
            this.RemoveSelectedIndex(index);
        for(var i = 0; i < this.savedSelectedIndices.length; i++){
            if(this.savedSelectedIndices[i] > index)
                this.savedSelectedIndices[i]--;
        }
        if(this.GetSelectedIndex() == -1)
            this.SetSelectedIndexCore(this.GetFirstSelectedIndex());
    }
});
_aspxListBoxCheckSelectionHelper = _aspxCreateClass(_aspxListBoxMultiSelectionHelper, {
    constructor: function(listBoxControl) {
        this.constructor.prototype.constructor.call(this, listBoxControl);
    },
    OnItemClick: function(index, evt){
        this.BeginSelectionUpdate();
        if(evt.shiftKey)
            _aspxListBoxMultiSelectionHelper.prototype.OnItemClick.call(this, index, evt);
        else
            this.AddSelectedIndex(index);
        this.EndSelectionUpdate();
    }
});

ASPxClientListBox = _aspxCreateClass(ASPxClientListBoxBase, {
    constructor: function(name) {
        this.constructor.prototype.constructor.call(this, name);
        
        this.enableSyncOnPerfCallback = false;
        this.freeUniqIndex = -1;
        this.isHasFakeRow = false;
        this.headerDiv = null;
        this.headerTable = null;
        this.listTable = null;
        this.sampleItemFirstTextCell = null;
        this.width = "";
        this.hasSampleItem = false;
        this.hoverClasses = [""];
        this.hoverCssArray = [""];
        this.selectedClasses = [""];
        this.selectedCssArray = [""];
        this.disabledClasses = [""];
        this.disabledCssArray = [""];
        this.imageCellExists = false;
        this.scrollHandlerLockCount = 0;
        this.columnFieldNames = [];
        this.textFormatString = "";
        this.defaultImageUrl = "";
        this.selectionMode = 0;
        this.initSelectedIndices = [];
        this.itemHorizontalAlign = "";
        // Callback
        this.allowMultipleCallbacks = false;
        this.isCallbackMode = false;
        this.callbackPageSize = -1;
        this.isTopSpacerVisible = false;
        this.isBottomSpacerVisible = false;
        this.serverIndexOfFirstItem = 0;
        this.scrollHelper = null;
        this.changeSelectAfterCallback = 0;
        // Cache
        this.ownerControl = null;
        this.SampleItem = null;
        this.scrollDivElement = null;
        this.scrollPageSize = 4;
        this.itemsValue = [];
        this.cachedValue = null;
        
        aspxGetListBoxCollection().Add(this);
    },
    Initialize: function() {   
        this.LockScrollHandler();
        this.InitScrollPos();
        this.freeUniqIndex = this.GetItemCount();
        
        this.InitSelection();
        this.AdjustControl(false);
        this.InitializeLoadOnDemand();
        this.UnlockScrollHandler();
        ASPxClientEdit.prototype.Initialize.call(this);
    },
    InitSelection: function(){
        if(this.MultiSelectionMode())
            this.SelectIndices(this.initSelectedIndices);
        else
            this.SelectIndexSilent(this.GetSelectedIndexInternal());
        this.CacheValue();
    },
    GetInitSelectedIndex: function(){
        return this.savedSelectedIndex;
    },
    CacheValue: function(){
        this.cachedValue = this.GetValue();
    },
    InitScrollPos: function(){ // Fix auto-scroll
        if(!this.isComboBoxList && this.isCallbackMode && this.GetInitSelectedIndex() == -1)
			this.GetScrollDivElement().scrollTop = 0;
    },
    InitializeLoadOnDemand: function(){
        var loadOnDemandRequired = this.isCallbackMode && this.GetEnabledByServer();
        this.scrollHelper = loadOnDemandRequired ? new _aspxListBoxScrollCallbackHelper(this) : new _aspxListBoxScrollCallbackHelperBase(this);
    },
    InlineInitialize: function(){
        this.LockScrollHandler();
        this.InitializeItemsAttributes();
        this.InitSpecialKeyboardHandling();
        this.GenerateStateItems();
        this.UnlockScrollHandler();
        ASPxClientEditBase.prototype.InlineInitialize.call(this);
    },
    InitializeItemsAttributes: function() { 
        var listTable = this.GetListTable();
        if(this.isHasFakeRow){
            this.LockSynchronization();
            this.ClearItems();
            this.UnlockSynchronization();
        }
        
        listTable.ListBoxId = this.name;  
        
        var rows = listTable.rows;
        var count = rows.length;
        
        var rowIdConst = this.name + "_";
        if(this.hasSampleItem)
            this.InitializeItemAttributes(this.GetSampleItemRow(), rowIdConst + __aspxLBSIIdSuffix);
        rowIdConst += __aspxLBIIdSuffix;
        for(var i = 0; i < count; i ++)
            this.InitializeItemAttributes(rows[i], rowIdConst + i);
    },
    InitializeItemAttributes: function(row, rowId) {
        var cells = row.cells;
        var itemCellsIdSuffixes = this.GetItemCellsIdPostfixes();
        for(var i = 0; i < row.cells.length; i++) {
            cells[i].style.textAlign = this.itemHorizontalAlign;
            cells[i].id = rowId + itemCellsIdSuffixes[i];
        }
    },
    InitializePageSize: function(){
        var divElement = this.GetScrollDivElement();
        var listTable = this.GetListTable();
        var rows = listTable.rows;
        var count = rows.length;

        if(_aspxIsExists(divElement) && count > 0)
            this.scrollPageSize = Math.round(divElement.clientHeight / rows[0].offsetHeight) - 1;
    },
    GenerateStateItems: function() {
        var itemCellsIdSuffixes = this.GetItemCellsIdPostfixes();
        var count = this.GetItemCount();
        var constName = this.name + "_" + __aspxLBIIdSuffix;
        var name = "";
        var controller = aspxGetStateController();
        var i = this.hasSampleItem ? -1 : 0 ;
        for(; i < count; i ++){
            name = constName + i;
            controller.AddHoverItem(name, this.hoverClasses, this.hoverCssArray, itemCellsIdSuffixes, null, null);
            controller.AddSelectedItem(name, this.selectedClasses, this.selectedCssArray, itemCellsIdSuffixes, null, null);
            controller.AddDisabledItem(name, this.disabledClasses, this.disabledCssArray, itemCellsIdSuffixes, null, null);
        }
    },
    AfterInitialize: function(){
        this.CallbackSpaceInit(true);
        this.constructor.prototype.AfterInitialize.call(this);
    },
    
    GetEnabledByServer: function(){
        return this.enabled;
    },
    SetEnabled: function(enabled){  
        ASPxClientListBoxBase.prototype.SetEnabled.call(this, enabled);
        this.CallbackSpaceInit(false);
    },
    CallbackSpaceInit: function(isInitialization){
        if(this.isCallbackMode){
            this.SetBottomScrollSpacerVisibility(this.GetScrollSpacerVisibility(false));
            this.SetTopScrollSpacerVisibility(this.GetScrollSpacerVisibility(true));
            if(isInitialization || this.isComboBoxList){
                this.EnsureSelectedItemVisible();
                _aspxAttachEventToElement(this.GetScrollDivElement(), "scroll", aspxLBScroll);
            }
            
        }
    },
    // Render
    GetListTable: function(){
        if(!_aspxIsExistsElement(this.listTable))
            this.listTable = _aspxGetElementById(this.name + __aspxLTableIdSuffix);
        return this.listTable;
    },
    GetListTableHeight: function(){
        return this.GetListTable().offsetHeight;
    },
    GetHeaderDivElement: function(){
        if(!_aspxIsExistsElement(this.headerDiv))
            this.headerDiv = _aspxGetElementById(this.name + __aspxLBHeaderDivIdSuffix);
        return this.headerDiv;
    },
    GetHeaderTableElement: function(){
        if(!_aspxIsExistsElement(this.headerTable)){
            var headerDiv = this.GetHeaderDivElement();
            this.headerTable = _aspxGetChildByTagName(headerDiv, "table", 0);
        }
        return this.headerTable;
    },
    GetScrollDivElement: function(){
        if(!_aspxIsExistsElement(this.scrollDivElement))
            this.scrollDivElement = document.getElementById(this.name + __aspxLBDSuffix);
        return this.scrollDivElement;
    },
    GetItemElement: function(index){
        var itemElement = this.GetItemRow(index);
        return __aspxWebKitFamily && itemElement != null ? itemElement.cells[0] : itemElement;
    },
    GetItemRow: function(index){
        var listTable = this.GetListTable();
        if(_aspxIsExists(listTable)){
            if(0 <= index && index < listTable.rows.length)
                return listTable.rows[index];
        }
        return null;
    },
    GetItemTexts: function(item) {
        return item.texts ? item.texts : [ item.text ];
    },
    GetItemCount: function(){
        var lbt = this.GetListTable();
        if(_aspxIsExists(lbt))
            return this.GetListTable().rows.length;
        return 0;
    },
    GetItemCellCount: function(){
        if(this.hasSampleItem)
            return this.GetSampleItemRow().cells.length;
        else if(this.GetItemCount() > 0){
            var listTable = this.GetListTable();
            return listTable.rows[0].cells.length;
        }
        return 0;
    },
    GetItemTextCellCount: function(){
        return this.GetItemCellCount() - this.GetItemFirstTextCellIndex();
    },
    GetItemFirstTextCellIndex: function(){
       var itemFirstTextCellIndex  = 0;
        if(this.GetIsCheckColumnExists())
            itemFirstTextCellIndex++;
        if(this.imageCellExists)
            itemFirstTextCellIndex++;
        return itemFirstTextCellIndex;
    },
    GetItemFirstTextCell: function(index){
        var rowElement = this.GetItemRow(index);
        if(rowElement == null) 
            return null;
        var cells = __aspxIE ? rowElement.childNodes : rowElement.cells;// Prevent IE cells undefining
        return cells[this.GetItemFirstTextCellIndex()];
    },
    GetItemTopOffset: function(index){
        var itemElement = this.GetItemElement(index);
        return (itemElement != null) ? itemElement.offsetTop + this.GetTopScrollSpacerHeight() : 0;
    },
    GetItemHeight: function(index){
        var itemElement = this.GetItemElement(index);
        return (itemElement != null) ? itemElement.offsetHeight : 0;
    },
    GetItemCheckBoxElement: function(index){
        var itemRow = this.GetItemRow(index);
        var checkBoxCell = itemRow.cells[this.GetCheckBoxCellIndex()];
        return _aspxGetElementsByTagName(checkBoxCell, "input")[0];
    },
    GetIsCheckColumnExists: function(){
        if(!this.checkCellExists)
            this.checkCellExists = this.CheckColumnSelectionMode();
        return this.checkCellExists;
    },
    GetCheckBoxCellIndex: function(){
        return 0;
    },
    GetImageCellIndex: function(){
        return this.GetIsCheckColumnExists() ? 1 : 0;
    },
    GetItemCellsIdPostfixes: function(){
        if(this.itemCellsIdPostfixes == null){
            this.itemCellsIdPostfixes = [];
            var i = 0;
            // TODO take in account a check column here
            if(this.imageCellExists){
                this.itemCellsIdPostfixes.push(__aspxLBIPostfixes[0]);
                i = 1;
            }
            var cellCount = this.GetItemCellCount();
            for(; i < cellCount; i++)
                this.itemCellsIdPostfixes.push(__aspxLBIPostfixes[1] + i);
        }
        return this.itemCellsIdPostfixes;
    },
    AdjustControlCore: function(){
        ASPxClientEdit.prototype.AdjustControlCore.call(this);
        
        this.CorrectSize();
        this.EnsureSelectedItemVisible();

        if(!this.isComboBoxList && __aspxIE && __aspxBrowserVersion >= 7) // FIX orevent to IE7 invisible scrollbar accounting
            this.CorrectWidth();
    },
    CorrectSize: function() {
        if(this.isComboBoxList)
            return;
        this.LockScrollHandler();
        this.CorrectHeight();
        this.CorrectWidth();
        this.InitializePageSize();
        this.UnlockScrollHandler();
    },
    OnCorrectSizeByTimer: function() {
        if(this.IsVisible())
            this.CorrectSize();
    }, 
    
    SetProtectionFromFlick_inFF: function(changeVisibility, changeDisplay){
        if(!__aspxFirefox) return;
        
		var listTable = this.GetListTable();
		if(changeVisibility)
        	listTable.style.visibility = "hidden";
		if(changeDisplay)
        	listTable.style.display = "none";
    },
    ResetProtectionFromFlick_inFF: function(){
        if(!__aspxFirefox) return;
        
        var listTable = this.GetListTable();
        listTable.style.visibility = "";
        listTable.style.display = "";
    },
    CorrectHeight: function(){
        if(__aspxFirefox && this.heightCorrected) return; // Prevent FF flicks
        this.heightCorrected = true;
    
        var mainElement = this.GetMainElement();
        var divElement = this.GetScrollDivElement();
        if(__aspxIE && __aspxBrowserVersion == 5.5)
            divElement.style.display = "none";
        divElement.style.height = "0px";
        var height = mainElement.offsetHeight;
        if(__aspxIE && __aspxBrowserVersion == 5.5)
            divElement.style.display = "";
        divElement.style.height = height + "px";
        var extrudedHeight = mainElement.offsetHeight;
        var heightCorrection = extrudedHeight - height;
        if(heightCorrection > 0){
            var divHeight = divElement.offsetHeight;

            this.SetProtectionFromFlick_inFF(true, false);
            divElement.style.height = (divHeight - heightCorrection) + "px";
            this.ResetProtectionFromFlick_inFF(); 

            extrudedHeight = mainElement.offsetHeight;
            var paddingsHeightCorrection = extrudedHeight - height;
            if(paddingsHeightCorrection > 0)
                divElement.style.height = (divHeight - heightCorrection - paddingsHeightCorrection) + "px";
        } 
    },
    IsMultiColumn: function(){
        return this.columnFieldNames.length > 0;
    },
    CorrectWidth: function(){
        if(this.IsMultiColumn())
            this.CorrectHeaderWidth();
        else
            this.CorrectWidthNonMultiColumn();
    },
    CorrectHeaderWidth: function(){
        var scrollDivElement = this.GetScrollDivElement();
        var headerDivElement = this.GetHeaderDivElement();
        var scrollBarWidth = this.GetVerticalScrollBarWidth(); // Prevent IE7 fail WidthCorrection test
        var browserPutsScrollBarOnContent = __aspxIE && __aspxBrowserVersion > 5.5 && __aspxBrowserVersion < 8;
        
        // B37486 (IE8)
        if(browserPutsScrollBarOnContent)
            scrollDivElement.style.paddingRight = scrollBarWidth + "px";
        if(_aspxIsExistsElement(headerDivElement)){
            var headerTable;
            if(__aspxWebKitFamily){
                headerTable = this.GetHeaderTableElement();
                if(!_aspxIsExistsElement(headerTable))
                    headerTable = null;
            }
            
            if(__aspxIE && __aspxBrowserVersion == 6 && this.IsListBoxWidthLessThenList()){
                var mainElement = this.GetMainElement();
                if(this.width == "")
                    mainElement.style.width = scrollDivElement.offsetWidth + "px";
                else
                    scrollDivElement.style.width = (mainElement.clientWidth - scrollBarWidth) + "px";
            }
            if(headerTable)
                headerTable.style.width = "0";
            // B37486 (IE8)
            if(__aspxIE && __aspxBrowserVersion < 8)
                headerDivElement.style.width = scrollDivElement.style.width;
            headerDivElement.style.paddingRight = scrollBarWidth + "px";
            if(headerTable)
                window.setTimeout(function() { headerTable.style.width = "100%"; }, 0);
        }
    },
    CorrectWidthNonMultiColumn: function(){
        var divElement = this.GetScrollDivElement();
        // B37486 (IE8)
        if(__aspxIE && __aspxBrowserMajorVersion < 8) {
            var mainElement = this.GetMainElement();
            var scrollBarWidth = this.GetVerticalScrollBarWidth(); // Prevent IE7 fail WidthCorrection test
            mainElement.style.width = "";
            divElement.style.width = "100%";
            if(__aspxIE && __aspxBrowserVersion > 5.5)
                divElement.style.paddingRight = "0px";
            if(this.width != ""){
                mainElement.style.width = this.width;
                divElement.style.width = "0px";
                var widthCorrectrion = (__aspxIE && __aspxBrowserVersion == 5.5) ? 0 : scrollBarWidth;
                divElement.style.width = (mainElement.clientWidth - widthCorrectrion) + "px";
            } else {
                var widthCorrectrion = (__aspxIE && __aspxBrowserVersion == 5.5) ? scrollBarWidth : 0;
                if(this.IsListBoxWidthLessThenList())
                    widthCorrectrion -= scrollBarWidth;
                divElement.style.width = (mainElement.clientWidth + widthCorrectrion) + "px";
            }
            if(__aspxIE && __aspxBrowserVersion > 5.5)
                divElement.style.paddingRight = scrollBarWidth + "px";
        } else {
            if(this.width == ""){
                var listTable = this.GetListTable();
                var mainElement = this.GetMainElement();
                if(listTable.offsetWidth != 0 || !__aspxNetscapeFamily){ // Mozilla: Prevent width collapse when item collection is empty
                    divElement.style.width = (listTable.offsetWidth + this.GetVerticalScrollBarWidth()) + "px";
                    if(__aspxFirefox) // Prevent right border invisibility
                        mainElement.style.width = divElement.offsetWidth + "px";
                }
            }
        }
    },
    EnsureSelectedItemVisible: function(){
        var index = this.GetSelectedIndex();
        if(index != -1)
            this.MakeItemVisible(index);
    },
    MakeItemVisible: function(index){
        if(!this.IsItemVisible(index))
            this.ScrollItemToTop(index);
    },
    IsItemVisible: function(index){
        var scrollDiv = this.GetScrollDivElement();
        var itemElement = this.GetItemElement(index);
        var topVisible = false;
        var bottomVisible = false;
        if(itemElement != null){
            var itemOffsetTop = itemElement.offsetTop + this.GetTopScrollSpacerHeight();
            topVisible = itemOffsetTop >= scrollDiv.scrollTop;
            bottomVisible = itemOffsetTop + itemElement.offsetHeight < scrollDiv.scrollTop + scrollDiv.clientHeight;
        }
        return (topVisible && bottomVisible);
    },
    ScrollItemToTop: function(index){
        this.LockScrollHandler();
        this.SetScrollTop(this.GetItemTopOffset(index));
        this.UnlockScrollHandler();
    },
    ScrollToItemVisible: function(index){
        if(!this.IsItemVisible(index)){
            var scrollDiv = this.GetScrollDivElement();
            var scrollTop = scrollDiv.scrollTop;
            var scrollDivHeight = scrollDiv.clientHeight;
            var itemOffsetTop = this.GetItemTopOffset(index);
            var itemHeight = this.GetItemHeight(index);
            
            var itemAbove = scrollTop > itemOffsetTop;
            var itemBelow = scrollTop  + scrollDivHeight < itemOffsetTop + itemHeight;
            if(itemAbove)
                scrollDiv.scrollTop = itemOffsetTop;
            else if(itemBelow){
                var scrollPaddings = scrollDiv.scrollHeight - this.GetListTable().offsetHeight - 
                    this.GetTopScrollSpacerHeight() - this.GetBottomScrollSpacerHeight();
                scrollDiv.scrollTop = itemOffsetTop + itemHeight - scrollDivHeight + scrollPaddings;
            }
        }
    },
    SetScrollTop: function(scrollTop){
        var scrollDiv = this.GetScrollDivElement();
        if(_aspxIsExists(scrollDiv)){ // Render may be removed when callback processing
            scrollDiv.scrollTop = scrollTop;
            if(__aspxOpera) // B36477
                this.CachedScrollTop();
        }   
    },
    CachedScrollTop: function(){
        var scrollDiv = this.GetScrollDivElement();
        scrollDiv.cachedScrollTop = scrollDiv.scrollTop;
    },
    RestoreScrollTopFromCache: function(){
       var scrollDiv = this.GetScrollDivElement();
       if(_aspxIsExists(scrollDiv) && _aspxIsExists(scrollDiv.cachedScrollTop))
            scrollDiv.scrollTop = scrollDiv.cachedScrollTop;
    },
    IsListBoxWidthLessThenList: function(){
        var divElement = this.GetScrollDivElement();
        var listTable = this.GetListTable();
        var listTabelWidth = listTable.style.width;
        var isLess = false;
        
        listTable.style.width = "";
        isLess = listTable.offsetWidth < divElement.offsetWidth;
        listTable.style.width = listTabelWidth;
        return isLess;
    },
    GetVerticalScrollBarWidth: function(){
        var divElement = this.GetScrollDivElement();    
        if(!this.verticalScrollBarWidth || this.verticalScrollBarWidth <= 0){
            this.verticalScrollBarWidth = this.GetVerticalScrollBarWidthCore(divElement);
            return this.verticalScrollBarWidth;
        } else
            return this.GetIsVerticalScrollBarVisible(divElement) ? this.verticalScrollBarWidth : 0;
    },
    GetIsVerticalScrollBarVisible: function(divElement){
        var verticalOverflow = this.GetVerticalOverflow(divElement);
        if(verticalOverflow != "auto"){ 
            var listTable = this.GetListTable();
            return divElement.clientHeight < listTable.offsetHeight;
        } else {
            var borderWidthWithScroll = divElement.offsetWidth - divElement.clientWidth;
            return borderWidthWithScroll == this.scrollDivBordersWidthWithScroll;
        }
    },
    GetVerticalScrollBarWidthCore: function(divElement){
        var overflowYReserv = this.GetVerticalOverflow(divElement);
        this.SetVerticalOverflow(divElement, "auto");
        this.scrollDivBordersWidthWithScroll = divElement.offsetWidth - divElement.clientWidth;
        if(__aspxIE && __aspxBrowserVersion >= 7)
            return this.scrollDivBordersWidthWithScroll; // Prevent IE7 Border invisible
        this.SetProtectionFromFlick_inFF(false, true);
        this.SetVerticalOverflow(divElement, "hidden");
        var bordersWidthWithoutScroll = divElement.offsetWidth - divElement.clientWidth;
        this.SetVerticalOverflow(divElement, overflowYReserv);
		this.ResetProtectionFromFlick_inFF();
        return this.scrollDivBordersWidthWithScroll - bordersWidthWithoutScroll;
    },
    GetVerticalOverflow: function(element){
        if(__aspxIE || __aspxSafari && __aspxBrowserVersion >= 3 || __aspxChrome)
            return element.style.overflowY;
        return element.style.overflow;
    },
    SetVerticalOverflow: function(element, value){
        if(__aspxIE || __aspxSafari && __aspxBrowserVersion >= 3 || __aspxChrome)
            element.style.overflowY = value;
        else
            element.style.overflow = value;
    },

    MultiSelectionMode: function(){
        return this.selectionMode != ListBoxSelectionMode.Single;
    },
    CheckColumnSelectionMode: function(){
        return this.selectionMode == ListBoxSelectionMode.CheckColumn;
    },
    IsCheckBoxClicked: function(evt){
        var eventSource = _aspxGetEventSource(evt);
        return eventSource.type == "checkbox";
    },
    OnItemClick: function(index, evt){
        if(!this.isInitialized) 
            return;
        if(this.readOnly)
            return this.OnItemClickOrDblClickReadOnly();

        if(this.CheckColumnSelectionMode() && this.IsCheckBoxClicked(evt))
            this.GetItemSelectionHelper().OnItemCheckBoxClick(index, evt);
        else
            this.GetItemSelectionHelper().OnItemClick(index, evt);
      
        this.SetFocus();
        this.RaiseItemClick();
    },
    OnItemClickOrDblClickReadOnly: function(){
        return false;
    },
    OnItemDblClick: function(){
        if(this.readOnly)
            return this.OnItemClickOrDblClickReadOnly();
        return this.RaiseItemDoubleClick();
    },
    CanChangeSelection: function(){
        return !this.readOnly || !this.isInitialized;
    },
    SelectIndexSilent: function(index){ // TODO remove it
		return this.SetItemSelectionStateSilent(index);
	},
    SetItemSelectionStateSilent: function(index){
        if(!this.CanChangeSelection())
			return;
    
        var oldSelectionIndex = this.GetSelectedIndex();
        
        this.LockSelectionEvents();
        this.GetItemSelectionHelper().SetSelectedIndex(index);
		this.UnlockSelectionEvents();

		return index != oldSelectionIndex;
    },
    SetItemSelectionState: function(index, selected, controller){
		if(!this.CanChangeSelection())
			return;

        if(!controller)
            controller = aspxGetStateController();
        if(!this.isInitialized)
            this.SetHoverElement(null);
        
        var itemFirstTextCell = this.GetItemFirstTextCell(index);
        if(selected)
            controller.SelectElementBySrcElement(itemFirstTextCell);
        else
            controller.DeselectElementBySrcElement(itemFirstTextCell);

        if(!this.isInitialized)
            this.SetHoverElement(itemFirstTextCell);
    },
    
        
    GetItemSelectionHelper: function(){
        if(!this.itemSelectionHelper)
            this.itemSelectionHelper = this.CreateItemSelectionHelper();
        return this.itemSelectionHelper;
    },
    CreateItemSelectionHelper: function(){
        if(this.selectionMode == ListBoxSelectionMode.Single)
            return new _aspxListBoxSingleSelectionHelper(this);
        else if(this.selectionMode == ListBoxSelectionMode.Multiple)
			return new _aspxListBoxMultiSelectionHelper(this);
		else if(this.selectionMode == ListBoxSelectionMode.CheckColumn)
            return new _aspxListBoxCheckSelectionHelper(this);
    },
    GetValue: function(){
        var selectedItem = this.GetSelectedItem();
        return selectedItem != null ? selectedItem.value : null;
    },
    SetValue: function(value){
        var index = this.GetItemIndexByValue(value);
        this.SetSelectedIndex(index);
    },
    GetSelectedItem: function(){
        var index = this.GetSelectedIndex();
        return this.GetItem(index);
    },
    GetSelectedIndex: function(){
        if(!this.isInitialized)
            return this.GetSelectedIndexInternal();
        return this.GetItemSelectionHelper().GetSelectedIndex();
    },
    SetSelectedItem: function(item){
        var index = (item != null) ? item.index : -1;
        this.SetSelectedIndex(index);
    },
    SetSelectedIndex: function(index){
        this.LockSelectionEvents();
        this.SetSelectedIndexCore(index);
        this.EnsureSelectedItemVisible(index);
        this.UnlockSelectionEvents();
    },
    SetSelectedIndexCore: function(index){
        this.GetItemSelectionHelper().SetSelectedIndex(index);
    },
    GetSelectedIndices: function(){
        return this.GetItemSelectionHelper().GetSelectedIndices();
    },
    GetSelectedValues: function(){ 
        return this.GetItemSelectionHelper().GetSelectedValues();
    },
    GetSelectedItems: function(){
        return this.GetItemSelectionHelper().GetSelectedItems();
    },
    SelectAll: function(){
        this.SelectIndices();
    },
    UnselectAll: function(){
        this.UnselectIndices();
    },
    SelectIndices: function(indices){
        this.LockSelectionEvents();
        this.GetItemSelectionHelper().SelectIndices(indices);
        this.UnlockSelectionEvents();
    },
    SelectItems: function(items){
        this.LockSelectionEvents();
        this.GetItemSelectionHelper().SelectItems(items);
        this.UnlockSelectionEvents();
    },
    SelectValues: function(values){
        this.LockSelectionEvents();
        this.GetItemSelectionHelper().SelectValues(values);
        this.UnlockSelectionEvents();
    },

    UnselectIndices: function(indices){
        this.LockSelectionEvents();
        this.GetItemSelectionHelper().UnselectIndices(indices);
        this.UnlockSelectionEvents();
    },
    UnselectItems: function(items){
        this.LockSelectionEvents();
        this.GetItemSelectionHelper().UnselectItems(items);
        this.UnlockSelectionEvents();
    },
    UnselectValues: function(values){
        this.LockSelectionEvents();
        this.GetItemSelectionHelper().UnselectValues(values);
        this.UnlockSelectionEvents();
    },
    GetIsItemSelected: function(index){
        return this.GetItemSelectionHelper().GetIsItemSelected(index);
    },
	SetSelectedIndexInternal: function(index){
		this.GetItemSelectionHelper().SetSelectedIndexCore(index);
	},
	GetFocusedIndex: function(){
	    return this.GetItemSelectionHelper().GetFocusedIndex();
	},
   
    UpdateInternalState: function(){
        this.UpdateHiddenInputs();
    },
    IsUpdateHiddenInputsLocked: function(){
        return this.GetItemSelectionHelper().IsUpdateInternalSelectionStateLocked();
    },
    UpdateHiddenInputs: function(){
        if(this.IsUpdateHiddenInputsLocked())
            return;
        if(this.MultiSelectionMode()){ // TODO remove it into to some helper
            var element = this.FindStateInputElement();
            if(_aspxIsExistsElement(element)) {
                var sb = new ASPxStringBuilder();
                var serialiser = this.GetSerializingHelper();
                var selectedIndices = this.GetSelectedIndices();
                for(var i = 0; i < selectedIndices.length; i++)
                    serialiser.SerializeAtomValue(sb, this.GetItemValue(selectedIndices[i]));
                element.value = sb.ToString();
            }
        } else 
            ASPxClientListBoxBase.prototype.UpdateHiddenInputs.call(this);
    },
    UseDelayedSpecialFocus: function() { 
        return true;
    },
    // LoadingPanel
    ShowLoadingPanel: function() {    
        if(!this.isComboBoxList){
            var loadingParentElement = this.GetScrollDivElement().parentNode;
            this.CreateLoadingDiv(loadingParentElement);
            this.CreateLoadingPanelWithAbsolutePosition(loadingParentElement);
        }
    },
    // CallbackMode
    ParseCallbackResult: function(result){
        var gottenEgdeOfCollection = false;
        var nothingToLoad = result == "";
        var isLoadindToTopByScroll = this.scrollHelper.IsScrolledToTopSpacer();
        if(!nothingToLoad){
            var deserializedItems = this.DeserializeItems(result);
            this.LoadItemsFromCallback(isLoadindToTopByScroll, deserializedItems);
            gottenEgdeOfCollection = deserializedItems.length != this.callbackPageSize;
        }
        var noMoreItemsForLoadThisDirection = nothingToLoad || gottenEgdeOfCollection;
        this.SetScrollSpacerVisibility(isLoadindToTopByScroll, !noMoreItemsForLoadThisDirection);
        this.scrollHelper.Reset();
    },
    LockSynchronizationOnInternalCallback: function(){
        if(!this.enableSyncOnPerfCallback)
            this.LockSynchronization();
    },
    UnlockSynchronizationOnInternalCallback: function (){
        if(!this.enableSyncOnPerfCallback)
            this.UnlockSynchronization();
    },
    LoadItemsFromCallback: function(isToTop, deserializedItems){
        this.LockSynchronizationOnInternalCallback();
        this.BeginUpdate();
        if(isToTop){
            var scrollHeightCorrection = 0;
            for(var i = deserializedItems.length - 1; i >= 0; i --){
                this.InsertItem(0, deserializedItems[i].texts, deserializedItems[i].value, deserializedItems[i].imageUrl);
                scrollHeightCorrection += this.GetItemHeight(0);
            } 
            this.GetScrollDivElement().scrollTop += scrollHeightCorrection;
            this.serverIndexOfFirstItem -= deserializedItems.length;
            if(this.serverIndexOfFirstItem < 0) this.serverIndexOfFirstItem = 0;
        } else {
            for(var i = 0; i < deserializedItems.length; i ++){
                this.AddItem(deserializedItems[i].texts, deserializedItems[i].value, deserializedItems[i].imageUrl);
            } 
        }
        if(this.changeSelectAfterCallback != 0) {
            var newIndex = this.GetSelectedIndex() + this.changeSelectAfterCallback;
            newIndex = this.GetAdjustedIndex(newIndex);
            this.SelectIndexSilent(newIndex);
            
            if(this.scrollHelper.isScrolledToTopSpacer)
                this.ScrollItemToTop(newIndex);
            else
                this.ScrollToItemVisible(newIndex);
        }
        this.EndUpdate();
        this.UnlockSynchronizationOnInternalCallback();
    },
    CreateSerializingHelper: function(){
        return new _aspxListBoxItemsSerializingHelper(this);
    },
    InCallback: function(){
        var callbackOwner = this.GetCallbackOwnerControl();
        if(callbackOwner != null)
            return callbackOwner.InCallback();
        return ASPxClientListEdit.prototype.InCallback.call(this);
    },
    GetItemsRangeForLoad: function(){
        return this.scrollHelper.GetItemsRangeForLoad();
    },
    GetScrollSpacerElement: function(isTop){
        return document.getElementById(this.name + (isTop ? __aspxLBTSIdSuffix : __aspxLBBSIdSuffix));
    },
    GetScrollSpacerVisibility: function(isTop){
        if(!this.clientEnabled)
            return false;
        return isTop ? this.isTopSpacerVisible : this.isBottomSpacerVisible;
    },
    SetScrollSpacerVisibility: function(isTop, visibility){
        this.LockScrollHandler();
        
        var spacer = this.GetScrollSpacerElement(isTop);
        if(_aspxIsExists(spacer)){
            if(visibility)
                spacer.style.height = this.GetScrollDivElement().clientHeight + "px";
            
            if(this.clientEnabled){
                if(isTop)
                    this.isTopSpacerVisible = visibility;
                else
                    this.isBottomSpacerVisible = visibility;
            }
                
            if(_aspxGetElementDisplay(spacer) != visibility){
                _aspxSetElementDisplay(spacer, visibility);
                _aspxGetElementVisibility(spacer, visibility);
            }
        }
        
        this.UnlockScrollHandler();
    },
    SetTopScrollSpacerVisibility: function(visibility){
        this.SetScrollSpacerVisibility(true, visibility);
    },
    SetBottomScrollSpacerVisibility: function(visibility){
        this.SetScrollSpacerVisibility(false, visibility);
    },
    GetTopScrollSpacerHeight: function(){
        return this.GetScrollSpacerVisibility(true) ? this.GetScrollSpacerElement(true).clientHeight : 0;
    },
    GetBottomScrollSpacerHeight: function(){
        return this.GetScrollSpacerVisibility(false) ? this.GetScrollSpacerElement(false).clientHeight : 0;
    },

    SendCallback: function(){
        if(!this.InCallback()){
            this.ShowLoadingPanel();
            var callbackOwner = this.GetCallbackOwnerControl();
            if(callbackOwner != null)
                callbackOwner.SendCallback();
             else {
                var argument = this.GetCallbackArguments();
                this.CreateCallback(argument);
            }
        }
    },
    OnCallback: function(result) {
        this.ParseCallbackResult(result);
        this.OnCallbackFinally();
    },
    OnCallbackError: function(result){
        ASPxClientListBoxBase.prototype.OnCallbackError.call(this, result);
        this.OnCallbackFinally();
    },
    OnCallbackFinally: function(){
        this.HideLoadingPanel();
        this.changeSelectAfterCallback = 0;
    },

    LockScrollHandler: function(){
        this.scrollHandlerLockCount ++;
    },
    UnlockScrollHandler: function(){
        this.scrollHandlerLockCount --;
    },
    IsScrollHandlerLocked: function(){
        return this.scrollHandlerLockCount > 0;
    },
    OnScroll: function(){
        if(this.IsScrollHandlerLocked()) return;
        
        if(this.IsVisible() && !this.InCallback() && ( this.GetScrollSpacerVisibility(true) || this.GetScrollSpacerVisibility(false))) {
            this.scrollHelper.OnScroll();
            if(this.scrollHelper.GetIsNeedToHideTopSpacer())
                this.SetTopScrollSpacerVisibility(false);
            if(this.scrollHelper.GetIsNeedCallback())
                this.SendCallback();
        }
    },
    OnResize: function(){
        var mainElement = this.GetMainElement();
        if(_aspxIsExistsElement(mainElement) && mainElement.style.width.indexOf("%") > -1 && this.IsVisible()){
            this.CorrectSize();
        }
    },
    // Keyboard support
    KeyboardSupportAllowed: function(){
        return !this.CheckColumnSelectionMode();
    },
    InitializeKeyHandlers: function() {
        if(this.KeyboardSupportAllowed()){
            this.AddKeyDownHandler(ASPxKey.PageUp, "OnPageUp");
            this.AddKeyDownHandler(ASPxKey.PageDown, "OnPageDown");
            this.AddKeyDownHandler(ASPxKey.End, "OnEndKeyDown");
            this.AddKeyDownHandler(ASPxKey.Home, "OnHomeKeyDown");
            this.AddKeyDownHandler(ASPxKey.Up, "OnArrowUp");
            this.AddKeyDownHandler(ASPxKey.Down, "OnArrowDown");
        }
    },
    OnArrowUp: function(evt){
        if(this.isInitialized)
            this.SelectNeighbour(-1);
        return true;
    },
    OnArrowDown: function(evt){
        if(this.isInitialized)
            this.SelectNeighbour(1);
        return true;
    },
    OnPageUp: function(evt){
        if(this.isInitialized)
            this.SelectNeighbour(-this.scrollPageSize);
        return true;
    },
    OnPageDown: function(evt){
        if(this.isInitialized)
            this.SelectNeighbour(this.scrollPageSize);
        return true;
    },
    OnHomeKeyDown: function(evt){
        if(this.isInitialized)
            this.SelectNeighbour(-this.GetItemCount());
        return true;
    },
    OnEndKeyDown: function(evt){
        if(this.isInitialized)
            this.SelectNeighbour(this.GetItemCount());
        return true;
    },
    
    GetAdjustedIndex: function(index){
        if(index < 0) index = 0;
        else{
            var itemCount = this.GetItemCount();
            if(index >= itemCount) index = itemCount - 1;
        }
        return index;
    },
    SelectNeighbour: function (step){
        var itemCount = this.GetItemCount();
        if(itemCount > 0){
            this.changeSelectAfterCallback = 0;
            var selectedIndex = this.GetFocusedIndex();
            var isFirstPageDown = selectedIndex == -1 && step == this.scrollPageSize;
            selectedIndex = isFirstPageDown ? step : selectedIndex + step;

            selectedIndex = this.GetAdjustedIndex(selectedIndex);
            this.LockAutoScroll();
            this.SetSelectedIndexCore(selectedIndex);
            this.UnlockAutoScroll();

            if(this.GetIsNeedToCallbackLoadItemsToTop(selectedIndex, step, itemCount)){
                this.LoadItemsOnCallback(true, selectedIndex);
            } else if(this.GetIsNeedToCallbackLoadItemsToBottom(selectedIndex, step, itemCount)){
                this.LoadItemsOnCallback(false, selectedIndex);
            }
            this.ScrollToItemVisible(selectedIndex);
        }
    },
    GetIsNeedToCallbackLoadItemsToTop: function(selectedIndex, step, itemCount){
        return this.isCallbackMode && this.GetScrollSpacerVisibility(true) && 
            this.serverIndexOfFirstItem > 0 && ((step < 0 && selectedIndex <= 0) || step <= -itemCount);
    },
    GetIsNeedToCallbackLoadItemsToBottom: function(selectedIndex, step, itemCount){
        return this.isCallbackMode && this.GetScrollSpacerVisibility(false) && 
            ((step > 0 && selectedIndex >= itemCount - 1) || step >= itemCount);
    },
    LoadItemsOnCallback: function(isToTop, index){
        this.changeSelectAfterCallback = index - this.GetSelectedIndex();
        this.scrollHelper.SetItemsRangeForLoad(isToTop);
        this.SendCallback();
    },
    FindInputElement: function(){
        return document.getElementById(this.name + "_KBS");
    },
    
    // TODO Refactor this function - coincide with ASPxMenu and ASPxNavBar
    SetHoverElement: function(element){
        aspxGetStateController().SetCurrentHoverElementBySrcElement(element);
    },
    InitOnContainerMadeVisible: function(){
        this.AdjustControl(false);
    },
    ClearItemsCore: function(){
        this.ClearListTableContent();
        this.SetSelectedIndexInternal(-1);
        this.SetValue(null);
    },
    CopyCellWidths: function(sourceRowIndex, destinationRowIndex){
        var cellCount = this.GetItemCellCount();
        var sourceRow = this.GetItemRow(sourceRowIndex);
        var destRow = this.GetItemRow(destinationRowIndex);
        for(var i = 0; i < cellCount; i++)
            destRow.cells[i].style.width = sourceRow.cells[i].style.width;
    },
    RemoveItem: function(index){
        if(index == 0 && this.GetItemCount() > 1)
            this.CopyCellWidths(0, 1);
            
        if(0 <= index && index < this.GetItemCount()){
            this.UpdateSyncArraysItemDeleted(this.GetItem(index), true);
            var row = this.GetItemRow(index);
            if(_aspxIsExistsElement(row))
                row.parentNode.removeChild(row);
                
            this.OnItemRemoved(index);
        }
    },
    GetItem: function(index){
        var listTable = this.GetListTable();
        if(!_aspxIsExists(listTable) || index < 0 || index >= listTable.rows.length)
            return null;
        
        var row = listTable.rows[index];
        var image = this.imageCellExists ? _aspxGetChildByTagName(row.cells[this.GetImageCellIndex()], "IMG", 0) : null;
        var src = image == null ? "" : ASPxImageUtils.GetImageSrc(image);
        
        var i = this.GetItemFirstTextCellIndex();
        var texts = [];
        for(;i < row.cells.length; i ++){
            var textCell = row.cells[i];
            
            if(typeof(textCell.attributes["DXText"]) != "undefined")
                texts.push(_aspxGetAttribute(textCell, "DXText"));
            else {
                var text = _aspxGetInnerText(textCell);
                text = text.replace(new RegExp(__aspxNbspChar, "g"), " ");
                texts.push(text);
            }
        }
        
        return new ASPxClientListBoxItem(this, index, texts, this.itemsValue[index], src, this.GetIsItemSelected(index));
    },
    
    PerformCallback: function(arg) {
        this.SetScrollSpacerVisibility(true, false);
        this.SetScrollSpacerVisibility(false, false);
        
        this.ClearItemsForPerformCallback();
        this.serverIndexOfFirstItem = 0;
        this.SetScrollSpacerVisibility(true, false);
        this.SetScrollSpacerVisibility(false, false);
        
        this.FormatAndSetCustomCallbackArg(arg);
        this.SendCallback();
    },

    GetTableRowParent: function(table){
        if(table.tBodies.length > 0)
            return table.tBodies[0];
        return table;
    },
    ProtectWhitespaceSerieses: function(text){
        if(text == "") 
            text = __aspxNbsp;
        else {
          if(text.charAt(0) == ' ')
                text = __aspxNbsp + text.slice(1);
            if(text.charAt(text.length - 1) == ' ')
                text = text.slice(0, -1) + __aspxNbsp;
            text = text.replace(new RegExp("  ", "g"), " &nbsp;");
        }
        return text;
    },

    CreateItem: function(index, texts, value, imageUrl){
        return new ASPxClientListBoxItem(this, index, texts, value, imageUrl);
    },
    InsertItemInternal: function(index, texts, value, imageUrl){
        if(!_aspxIsExists(texts) || texts.length == 0)
            texts = [""];
        else if(typeof(texts) == "string")
            texts = [ texts ];
            
        if(typeof(value) == "undefined")
            value = texts[0];
        if(!_aspxIsExists(imageUrl))
            imageUrl = "";
        
        var newItemRow = this.CreateNewItem();
        _aspxRemoveAttribute(newItemRow, "id");
        
        var listTable = this.GetListTable();
        var tbody = this.GetTableRowParent(listTable);
        var isAdd = listTable.rows.length <= index;
        if(isAdd)
            tbody.appendChild(newItemRow);
        else
            tbody.insertBefore(newItemRow, this.GetItemRow(index));
        
        var newIndex = this.FindFreeIndex();
        var newId = this.CreateItemId(newIndex);
        var newClientId = this.CreateItemClientId(newIndex);
        this.InitializeItemAttributes(newItemRow, newClientId, true);
        var sampleItemFirstTextCell = this.GetSampleItemFirstTextCell();
        var itemCellsIdPostfixes = this.GetItemCellsIdPostfixes();
        
        var styleController = aspxGetStateController();
        aspxAddHoverItems(this.name, this.CreateStyleClasses(newId, itemCellsIdPostfixes, 
            styleController.GetHoverElement(sampleItemFirstTextCell), __aspxHoverItemKind));
        aspxAddSelectedItems(this.name, this.CreateStyleClasses(newId, itemCellsIdPostfixes, 
            styleController.GetSelectedElement(sampleItemFirstTextCell), __aspxSelectedItemKind));
        aspxAddDisabledItems(this.name, this.CreateStyleClasses(newId, itemCellsIdPostfixes, 
            styleController.GetDisabledElement(sampleItemFirstTextCell), __aspxDisabledItemKind));
        
        _aspxRemoveAttribute(sampleItemFirstTextCell, __aspxCachedHoverItemKind);
        _aspxRemoveAttribute(sampleItemFirstTextCell, __aspxCachedSelectedItemKind);
        _aspxRemoveAttribute(sampleItemFirstTextCell, __aspxCachedDisabledItemKind);

        this.PrepareItem(newItemRow, texts, imageUrl); 
        
        _aspxArrayInsert(this.itemsValue, value, index);
        this.RegisterInsertedItem(index, texts, value, imageUrl);
        
        this.OnItemInserted(index);
    },
    PrepareItem: function(newItemRow, texts, imageUrl){ 
        var i = 0;
        if(this.GetIsCheckColumnExists())
            i ++;
        if(this.imageCellExists) {
            this.PrepareItemImage(newItemRow, i, imageUrl);
            i ++;
        }
        var cellCount = this.GetItemCellCount();
        for(var j = 0; i < cellCount; i++, j++)
            this.PrepareItemTextCell(newItemRow.cells[i], texts[j])
    },
    PrepareItemImage: function(newItemRow, imageCellIndex, imageUrl){
        var imageCell = newItemRow.cells[imageCellIndex];
        var image = _aspxGetChildByTagName(imageCell, "IMG", 0);
        if(!_aspxIsExists(image)){
            image = document.createElement("IMG");
            imageCell.innerHTML = "";
            imageCell.appendChild(image);
        }
        ASPxImageUtils.SetImageSrc(image, imageUrl);
    }, 
    PrepareItemTextCell: function(cell, text){
        if(!_aspxIsExists(text)) 
            text = "";
        
        cell.innerHTML = this.ProtectWhitespaceSerieses(text);
        if(text == "")
            _aspxSetAttribute(cell, "DXText", text);
    },
    ClearListTableContent: function(){
        var tBody = this.GetTableRowParent(this.GetListTable());
        if(__aspxIE)
            tBody.innerText = "";
        else
            tBody.innerHTML = "";
    },
    FormatText: function(texts){
        if(typeof(texts) == "string")
            return texts;
        else if(!this.IsMultiColumn())
            return texts[0];
        else
            return this.FormatTextCore(texts);
    },
    FormatTextCore: function(texts){
        if(this.isComboBoxList)
            return ASPxFormatter.Format(this.textFormatString, texts);
        else
            return texts.join("; ");
    },
    OnItemInserted: function(index){
        this.GetItemSelectionHelper().OnItemInserted(index);
    },
    OnItemRemoved: function(index){
        this.GetItemSelectionHelper().OnItemRemoved(index);
    },

    CreateItemId: function(index){
        return __aspxLBIIdSuffix + index;
    },
    CreateItemClientId: function(index){
        return this.name + "_" + __aspxLBIIdSuffix + index;
    },
    CreateNewItem: function(){
        var newItemRow = this.GetSampleItemRow();
        if (_aspxIsExistsElement(newItemRow)) 
            newItemRow = newItemRow.cloneNode(true);
        return newItemRow;
    },
    CreateStyleClasses: function(id, postfixes, item, kind){
        var classes = [];
        if(_aspxIsExists(item) && _aspxIsExists(item[kind])){
            classes[0] = [];
            classes[0][0] = item[kind].classNames;
            classes[0][1] = item[kind].cssTexts;
            classes[0][2] = [];
            classes[0][2][0] = id;
            classes[0][3] = postfixes;
        }
        return classes;
    },
    CorrectSizeByTimer: function(){
        if(this.APILockCount == 0 && this.IsDisplayed())
            _aspxSetTimeout("aspxLBCorrectSizeByTimer(\""+this.name+"\");", 0);
    },
    FindFreeIndex: function(){
        return this.freeUniqIndex ++;
    },
    GetSampleItemRowID: function(){
        return this.name + "_" + __aspxLBSIIdSuffix;
    },
    GetSampleItemRow: function(){
        if(this.SampleItem == null)
            this.SampleItem = _aspxGetElementById(this.GetSampleItemRowID());
        return this.SampleItem;
    },
    GetSampleItemFirstTextCell: function(){
        if(!_aspxIsExistsElement(this.sampleItemFirstTextCell)){
			var sampleItemRow = this.GetSampleItemRow();
			if(_aspxIsExistsElement(sampleItemRow))
			    this.sampleItemFirstTextCell = sampleItemRow.cells[this.imageCellExists ? 1 : 0];
		}
        return this.sampleItemFirstTextCell;
    },
    ChangeEnabledAttributes: function(enabled){
        this.ChangeListTableEvents(this.GetListTable(), _aspxChangeEventsMethod(enabled));
        var inputElement = this.GetInputElement();
        if(_aspxIsExists(inputElement)) 
            this.ChangeSpecialInputEnabledAttributes(inputElement, _aspxChangeEventsMethod(enabled));
    },
    ChangeEnabledStateItems: function(enabled){
        var controller = aspxGetStateController();
        controller.SetElementEnabled(this.GetMainElement(), enabled);

        var count = this.GetItemCount();
        var i = this.hasSampleItem ? -1 : 0 ;
        var checkColumnExists = this.GetIsCheckColumnExists();
        for(; i < count; i ++){
            var element = this.GetItemFirstTextCell(i);
            if(_aspxIsExists(element))
                controller.SetElementEnabled(element, enabled);
            if(checkColumnExists && i >= 0){
                var checkBox = this.GetItemCheckBoxElement(i);
                checkBox.disabled = !enabled;
            }
        }
    },
    ChangeListTableEvents: function(listTable, method){
        if(this.isComboBoxList){
            method(listTable, "mouseup", aspxLBIClick);
            if(__aspxFirefox)// FIX prevent to wront continues selection by item click
                method(listTable, "mousedown", _aspxPreventEvent); 
        }
        else{
            method(listTable, "click", aspxLBIClick);   
            method(listTable, "dblclick", aspxLBIClick);    
            if(this.MultiSelectionMode())
                _aspxAttachEventToElement(listTable, "selectstart", aspxLBTSelectStart);
        }
    },
    IsValueChanged: function(){
        return this.cachedValue != this.GetValue();
    },
    OnItemSelectionChanged: function(index, selected){
        if(this.CheckColumnSelectionMode()){
            var checkBox = this.GetItemCheckBoxElement(index);
            checkBox.checked = selected;
        }
        if (!this.IsSelectionEventsLocked()) {
            var valueChanged = this.IsValueChanged();
            if (valueChanged) {
                this.RaisePersonalStandardValidation();
                this.OnValueChanged();
            }
            this.RaiseSelectedIndexChanged(false, index, selected);
            if(!valueChanged && this.autoPostBack)
                this.SendPostBackInternal("");
        }
        this.CacheValue();
    },
    RaiseSelectedIndexChanged: function(processOnServer, index, selected){
        if(!this.SelectedIndexChanged.IsEmpty()){
            var args = new ASPxClientListEditItemSelectedChangedEventArgs(index, selected);
            this.SelectedIndexChanged.FireEvent(this, args);
            processOnServer = args.processOnServer;
        }
        return processOnServer;
    },
    RaiseValueChangedAdditionalEvents: function(processOnServer){
        return processOnServer;
    }
});

ASPxClientNativeListBox = _aspxCreateClass(ASPxClientListBoxBase, {
    constructor: function(name) {
        this.constructor.prototype.constructor.call(this, name);
    },
    
    SetMainElement: function(mainElement){
        this.mainElement = mainElement;
    },
    FindInputElement: function(){
        return this.GetMainElement();
    },    

    GetOptionCount: function(){
        return this.GetMainElement().options.length;
    },
    GetOption: function(index){
        return this.GetMainElement().options[index];
    },
    
    GetItemCount: function(){
        return this.GetOptionCount();
    },
    SelectIndexSilent: function(index){
        var selectedIndex = this.GetSelectedIndexInternal();
        var isValidIndex = (-1 <= index && index < this.GetItemCount());
        if((selectedIndex != index && isValidIndex) || !this.isInitialized){
            this.SetSelectedIndexInternal(index);
            return true;
        }
        return false;
    },
    GetSelectedIndexInternal: function(){
        return this.GetMainElement().selectedIndex; 
    },
    SetSelectedIndexInternal: function(index){
        this.GetMainElement().selectedIndex = index; 
    },
    ClearItemsCore: function(){
        this.GetMainElement().innerHTML = "";
    },
    RemoveItem: function(index){
        if(0 <= index && index < this.GetItemCount()){
            var oldSelectedIndex = this.GetSelectedIndexInternal();
            this.UpdateSyncArraysItemDeleted(this.GetItem(index), true);
            
            var option = this.GetOption(index);
            this.GetMainElement().removeChild(option);
            
            this.UpdateOptionValues();
            this.OnItemRemoved(oldSelectedIndex, index);
        }
    },
    OnItemRemoved: function(oldSelectedIndex, newSelectedIndex){
        if(newSelectedIndex == oldSelectedIndex && !this.MultiSelectionMode())
            this.SetSelectedIndexInternal(-1);
    },
    MultiSelectionMode: function(){
        return this.GetMainElement().multiple;
    },
    GetItem: function(index){
        if(0 <= index && index < this.GetOptionCount()) {
            var text = this.GetOption(index).text;
            if(_aspxIsExists(text))
                return new ASPxClientListEditItem(this, index, text, this.itemsValue[index], "");
        }
        return null;
    },
    PerformCallback: function(arg) {
        this.ClearItemsForPerformCallback();
        this.FormatAndSetCustomCallbackArg(arg);
        this.SendCallback();
    },
    SendCallback: function(){
        if(!this.InCallback()){
            var callbackOwner = this.GetCallbackOwnerControl();
            if(callbackOwner != null)
                callbackOwner.SendCallback();
             else {
                var argument = this.GetCallbackArguments();
                this.CreateCallback(argument);
            }
        }
    },
    ParseCallbackResult: function(result){
        var deserializedItems = this.DeserializeItems(result);
        this.LoadItemsFromCallback(true, deserializedItems);
    },
    
    InsertItemInternal: function(index, text, value, imageUrl){
        if(!_aspxIsExists(value))     
            value = text;
        var oldSelectedIndex = this.GetSelectedIndexInternal();
            
        var isAdd = this.GetOptionCount() <= index;
        var newOption = document.createElement("OPTION");
        if(isAdd)
            this.GetMainElement().appendChild(newOption);
        else
            this.GetMainElement().insertBefore(newOption, this.GetOption(index));
        newOption.innerHTML = text;
        this.UpdateOptionValues();
        
        _aspxArrayInsert(this.itemsValue, value, index);
        this.RegisterInsertedItem(index, text, value, imageUrl); // TODO make possible to remove
        if(index == oldSelectedIndex && index != -1)
            this.SetSelectedIndex(index + 1);
    },
    UpdateOptionValues: function() {
        for(var i = 0; i < this.GetOptionCount(); i++)
            this.GetOption(i).value = i;
    },
    ChangeEnabledAttributes: function(enabled){
        if(!this.isComboBoxList)
            this.GetMainElement().disabled = !enabled;
    },
    OnCallback: function(result) {
        this.ParseCallbackResult(result);
    },
    OnItemDblClick: function(){
        this.RaiseItemDoubleClick();
    },
    LoadItemsFromCallback: function(isToTop, deserializedItems){
        this.BeginUpdate();
        for(var i = deserializedItems.length - 1; i >= 0; i --)
            this.InsertItem(0, deserializedItems[i].text, deserializedItems[i].value, deserializedItems[i].imageUrl);
        this.EndUpdate();
    },
    // API
    GetSelectedIndices: function(){
        var selectedIndices = [];
        var mainElement = this.GetMainElement();
        for(var i = 0; i < mainElement.options.length; i++){
            if(mainElement.options[i].selected)
                selectedIndices.push(i);
        }
        return selectedIndices;
    },
    GetSelectedValues: function(){ 
        var selectedValues = [];
        var selectedIndices = this.GetSelectedIndices();
        for(var i = 0; i < selectedIndices.length; i++)
            selectedValues.push(this.GetItemValue(selectedIndices[i]));
        return selectedValues;
    },
    GetSelectedItems: function(){
        var selectedItems = [];
        var selectedIndices = this.GetSelectedIndices();
        for(var i = 0; i < selectedIndices.length; i++)
            selectedItems.push(this.GetItem(selectedIndices[i]));
        return selectedItems;
    },
    SelectAll: function(){
        this.SetAllItemsSelectedValue(true);
    },
    UnselectAll: function(){
        this.SetAllItemsSelectedValue(false);
    },
    SetAllItemsSelectedValue: function(selected){
        var mainElement = this.GetMainElement();
        for(var i = 0; i < mainElement.options.length; i++)
            mainElement.options[i].selected = selected;
    },
    SelectIndices: function(indices){
        this.SetIndicesSelectionState(indices, true);
    },
    UnselectIndices: function(indices){
        this.SetIndicesSelectionState(indices, false);
    },
    SetIndicesSelectionState: function(indices, selected){
        var mainElement = this.GetMainElement();
        for(var i = 0; i < indices.length; i++){
            mainElement.options[indices[i]].selected = selected;
        }
    },
    SelectItems: function(items){
        if(_aspxIsExists(items))
            this.SetItemsSelectionState(items, true);
        else
            this.SelectAll();
    },
    UnselectItems: function(items){
        if(_aspxIsExists(items))
            this.SetItemsSelectionState(items, false);
        else
            this.UnselectAll();
    },
    SetItemsSelectionState: function(items, selected){
        var mainElement = this.GetMainElement();
        for(var i = 0; i < items.length; i++){
            mainElement.options[items[i].index].selected = selected;
        }
    },
    SelectValues: function(values){
        this.SetValuesSelectedState(values, true);
    },
    UnselectValues: function(values){
        this.SetValuesSelectedState(values, false);
    },
    SetValuesSelectedState: function(values, selected){
        var mainElement = this.GetMainElement();
        var index;
        for(var i = 0; i < values.length; i++){
            index = this.GetItemIndexByValue(values[i]);
            mainElement.options[index].selected = selected;
        }
    }
});
ASPxClientRadioButtonList = _aspxCreateClass(ASPxClientListEdit, {
    constructor: function(name) {
        this.constructor.prototype.constructor.call(this, name);                                        
        
        this.items = [];
	},
	InlineInitialize: function() {
	    var selectedIndex = this.GetSelectedIndex();
	    this.UpdateHiddenInputs(selectedIndex);
	    this.SetSelectedIndex(this.GetSelectedIndex());//B134441
	    
	    ASPxClientListEdit.prototype.InlineInitialize.call(this);
	},
    SetFocus: function() {
        var index = this.GetSelectedIndexInternal();
        if(index == -1)
            index = 0;
        var itemElement = this.GetItemElement(index);
        if (itemElement != null && _aspxGetActiveElement() != itemElement && _aspxIsEditorFocusable(itemElement)) 
            _aspxSetFocus(itemElement);
    },
    GetInputElement: function() {
        var index = this.GetSelectedIndexInternal();
        return this.GetItemElement(index);
    },
    GetValueInputElement: function() {
        if(this.valueInput == null) {
            this.valueInput = _aspxCreateHiddenField(null, this.name + "_ValueInput");
            var stateInput = this.FindStateInputElement();
            stateInput.parentNode.insertBefore(this.valueInput, stateInput);
        }
        return this.valueInput;
    },
    GetValueInputToValidate: function() {
        return this.GetValueInputElement();
    },
    GetItemElement: function(index) {
        return this.GetChild("_RB" + index + "_I");
    },
    GetItemMainElement: function(index) {
        return this.GetChild("_RB" + index);
    },
    GetItemCount: function() {
        return this.items.length;
    },
    OnItemClick: function(index) {
        if(this.GetSelectedIndexInternal() != index) {
            this.SelectIndexSilent(index);
            this.RaisePersonalStandardValidation();
            this.OnValueChanged();
        }
    },
    OnItemClickReadonly: function() {
        var index = this.GetSelectedIndexInternal();
        this.SelectIndexSilent(index);
    },
    UpdateHiddenInputs: function(index) {
        var stateInput = this.FindStateInputElement();
        if(_aspxIsExistsElement(stateInput))
            stateInput.value = index;
        
        // Standard validation support
        var valueInput = this.GetValueInputElement();
        if(_aspxIsExistsElement(valueInput)) {
            // [Victor] Standard validation mechanism trying to receive a value of an editor doens't
            // treat empty value string as a value at all and continue searching. So, we must store
            // at least one whitespace character to force validators to use our value input.
            var value = this.GetValue();
            valueInput.value = _aspxIsExists(value) ? value : " ";
        }
    },
    SelectIndexSilent: function(index) {
        var itemCount = this.GetItemCount();
        var isValidIndex = (-1 <= index && index < itemCount);
        if(isValidIndex) {
            for(var i = 0; i < itemCount; i++) {
                if(_aspxIsExists(this.GetItemElement(i)))
                    this.GetItemElement(i).checked = (i == index);
            }
            this.SetSelectedIndexInternal(index);
            this.UpdateHiddenInputs(index);
        }
    },
        
    GetItemValue: function(index){
        if (index > -1 && index < this.items.length) {
            if (typeof(this.items[index].value) == "string" && this.items[index].value == "" && this.convertEmptyStringToNull)
                return null;
            else
                return this.items[index].value;
        }
        return null;
    },
    // value
    SetValue: function(value) {
        for (var i = 0; i < this.items.length; i++) {
            if(this.GetItemValue(i) == value) {            
                this.SelectIndexSilent(i);
                return;
            }
        } 
        this.SelectIndexSilent(-1);       
    },
    // API
    CreateItems: function(itemsProperties){
        for(var i = 0; i < itemsProperties.length; i ++)
            this.CreateItem(i, itemsProperties[i][0], itemsProperties[i][1], itemsProperties[i][2]);
    },
    CreateItem: function(index, text, value, imageUrl){
        var item = new ASPxClientListEditItem(this, index, text, value, imageUrl);
        _aspxArrayPush(this.items, item);
    },
    GetItem: function(index){
        return (0 <= index && index < this.items.length) ? this.items[index] : null;
    },
    
    ChangeEnabledAttributes: function(enabled){
        for(var i = 0; i < this.GetItemCount(); i++){        
            var element = this.GetItemElement(i);
            if(_aspxIsExists(element)){
                this.ChangeItemEnabledAttributes(element, _aspxChangeAttributesMethod(enabled));
                element.disabled = !enabled;
            }
        }
    },
    ChangeEnabledStateItems: function(enabled){
        aspxGetStateController().SetElementEnabled(this.GetMainElement(), enabled);
        for(var i = 0; i < this.GetItemCount(); i++){        
            var element = this.GetItemMainElement(i);
            if(_aspxIsExists(element))
                aspxGetStateController().SetElementEnabled(element, enabled);
        }
    },
	ChangeItemEnabledAttributes: function(element, method){
        method(element, "onclick");
	}
});
ASPxClientListEditItemSelectedChangedEventArgs = _aspxCreateClass(ASPxClientProcessingModeEventArgs, {
	constructor: function(index, isSelected){
	    this.constructor.prototype.constructor.call(this, false);
        this.index = index;
        this.isSelected = isSelected;
    }
});

ASPxClientListBoxCollection = _aspxCreateClass(ASPxClientControlCollection, {
    OnResize: function(){
        for(var name in this.elements){
            var control = this.elements[name];
            control.OnResize();
        }
    }
});
var __aspxListBoxCollection = null;
function aspxGetListBoxCollection(){
    if(__aspxListBoxCollection == null)
        __aspxListBoxCollection  = new ASPxClientListBoxCollection();
    return __aspxListBoxCollection;
}
_aspxAttachEventToElement(window, "resize", aspxLBWindowResize);
function aspxLBWindowResize(evt){
    aspxGetListBoxCollection().OnResize(evt);	
}

function aspxLBTSelectStart(evt){
    var element = _aspxGetEventSource(evt);
    var shiftPressed = evt.shiftKey;
    var ctrlKey = evt.ctrlKey || evt.metaKey;
    if(shiftPressed || ctrlKey){
        _aspxClearSelection();
        _aspxPreventEventAndBubble(evt);
    }
}
function aspxLBIClick(evt){
    var element = _aspxGetEventSource(evt);
    while(element != null && element.tagName != "BODY"){
        if(element.tagName == "TR"){
		    var table = element.offsetParent;
		    if(_aspxIsExists(table) && _aspxIsExists(table.ListBoxId)){
		        var lb = aspxGetControlCollection().Get(table.ListBoxId);
		        if(lb != null) {
		            var retValue;
		            if(evt.type == "dblclick") 
		                retValue =lb.OnItemDblClick();
		            else if(!lb.isComboBoxList || _aspxGetIsLeftButtonPressed(evt)) 
		                retValue = lb.OnItemClick(element.rowIndex, evt);
		            if(typeof(retValue) != "undefined")
		                return retValue;
		        }
        		break;
		    }
		}
        element = element.parentNode;
	}
}
function aspxNLBIDClick(evt){
    var element = _aspxGetEventSource(evt);
    if(element != null && element.tagName == "SELECT"){
		var lb = aspxGetControlCollection().Get(element.id);
		if(lb != null)
		    lb.OnItemDblClick();
	}
}

function aspxLBScroll(evt){
    var sourceId = _aspxGetEventSource(evt).id;
    if(sourceId.slice(-__aspxLBDSuffix.length) == __aspxLBDSuffix){
        var name = sourceId.slice(0, -2);
        var lb = aspxGetControlCollection().Get(name);
        if(lb != null && lb.isInitialized) 
            lb.OnScroll();
    }
}
function aspxLBCorrectSizeByTimer(name){
    var lb = aspxGetControlCollection().Get(name);
    if(lb != null)
        lb.OnCorrectSizeByTimer();
}

function aspxERBLIClick(name, index) {
    var list = aspxGetControlCollection().Get(name);
    if(list != null)
        list.OnItemClick(index);
}
function aspxERBLICancel(name) {
    var list = aspxGetControlCollection().Get(name);
    if(list != null)
        list.OnItemClickReadonly();
}
