ASPxClientTreeList = _aspxCreateClass(ASPxClientControl, {
 constructor: function(name) {
  this.constructor.prototype.constructor.call(this, name);
  this.elementCache = { };  
  this.rowIdPrefix = this.name + "_" + this.RowIDSuffix;
  this.focusedKey = null;
  this.dragHelper = new ASPxClientTreeListDragHelper(this);
  this.lpTimer = -1;
  this.selectionDiff = { };
  this.syncLock = false;
  this.callbackHandlersPool = [ ];
  this.kbdHelper = null;
  this.selectionStartKey = null;
  this.enableFocusedNode = false;
  this.lpDelay = 300;  
  this.lpDisable = false;
  this.focusSendsCallback = false;
  this.selectionSendsCallback = false;
  this.recursiveSelection = false;
  this.columns = [ ];
  this.expandCollapseAction = this.ExpandCollapseAction.Button;
  this.focusOnExpandCollapse = true;
  this.confirmDeleteMsg = null;
  this.allowStylizeEditingNode = false;
  this.enableKeyboard = false;
  this.accessKey = null;
  this.maxVisibleLevel = -1;
  this.visibleColumnCount = 0;
  this.rowCount = 0;
  this.editingKey = null;
  this.isNewNodeEditing = false;
  this.pageIndex = -1;
  this.pageCount = 1;
  this.FocusedNodeChanged = new ASPxClientEvent();
  this.SelectionChanged = new ASPxClientEvent();
  this.CustomizationWindowCloseUp = new ASPxClientEvent();
  this.CustomDataCallback = new ASPxClientEvent();  
  this.NodeClick = new ASPxClientEvent();
  this.NodeDblClick = new ASPxClientEvent();
  this.ContextMenu = new ASPxClientEvent();
  this.StartDragNode = new ASPxClientEvent();
  this.EndDragNode = new ASPxClientEvent();  
  this.CustomButtonClick = new ASPxClientEvent();
  this.NodeFocusing = new ASPxClientEvent();
  this.NodeExpanding = new ASPxClientEvent();
  this.NodeCollapsing = new ASPxClientEvent();
 },
 InlineInitialize: function() {
  ASPxClientControl.prototype.InlineInitialize.call(this);
  this.EnsureIE8WideCellIsFilled();
  if(this.enableKeyboard) {
   this.kbdHelper = new ASPxTreeListKbdHelper(this);
   this.kbdHelper.Init();
   ASPxKbdHelper.RegisterAccessKey(this);
  }  
 },
 OnNodeSelecting: function(check) { 
  this.OnNodeSelectingCore(check);  
  if(this.RaiseSelectionChanged())
   this.SendDummyCommand();  
 },
 OnNodeSelectingCore: function(check) {
  var row = this.FindDataRow(check);  
  if(!_aspxIsExistsElement(row)) return;
  var nodeKey = this.GetNodeKeyByRow(row);   
  if(_aspxIsExists(this.selectionDiff[nodeKey]))
   delete this.selectionDiff[nodeKey];
  else
   this.selectionDiff[nodeKey] = 1;   
  this.PersistSelectionDiff();    
  this.UpdateRowStyle(nodeKey);  
 },
 OnSelectingAll: function(state) {
  var input = this.GetSelectAllMarkInput();
  if(!_aspxIsExistsElement(input))
   return;
  input.value = state ? "A" : "N";  
  this.SendDummyCommand();
  this.RaiseSelectionChanged();
 },
 OnFocusingNode: function(key, htmlEvent) {  
  var prevKey = this.GetFocusedNodeKey();
  if(prevKey != key && this.RaiseNodeFocusing(key, htmlEvent)) {
   this.SetFocusedNodeKey(key);
   return this.RaiseFocusedNodeChanged();
  }
  return false;
 },
 OnDataTableMouseDown: function(e) { 
  if(this.syncLock) return;
  if(!_aspxGetIsLeftButtonPressed(e)) return;
  e = _aspxGetEvent(e);
  var row = this.FindDataRow(_aspxGetEventSource(e));
  if(!_aspxIsExistsElement(row))
   return;
  var helper = this.dragHelper;  
  var canDrag = !this.IsEditing();  
  if(canDrag) {
   var nodeKey = this.GetNodeKeyByRow(row);
   var targets = this.GetAllDataRows();
   var header = this.GetHeaderRow();
   if(_aspxIsExistsElement(header))
    targets.push(header);
   canDrag = this.RaiseStartDragNode(nodeKey, e, targets);
   if(canDrag)
    helper.CreateNodeTargets(targets, row);
  }
  var drag = helper.CreateNodeDrag(row, e, canDrag);
 },
 OnDataTableClick: function(e) {
  if(this.syncLock) return;
  e = _aspxGetEvent(e);
  var source = _aspxGetEventSource(e);
  var sourceIsIndent = this.FindIndentCell(source) != null;
  var sourceIsCommandCell = this.FindCommandCell(source) != null;
  var row = this.FindDataRow(source);
  if(!_aspxIsExistsElement(row))
   return;
  var nodeKey = this.GetNodeKeyByRow(row);
  if(!sourceIsIndent && !sourceIsCommandCell) {
   if(!this.RaiseNodeClick(nodeKey, e))  
    return;
  }
  var tag = source.tagName;
  var className = source.className;
  this.selectionStartKey = nodeKey;
  if(tag == "IMG") {
   if(className.indexOf(this.ExpandButtonClassName) > -1) {
    if(this.enableFocusedNode && this.focusOnExpandCollapse)
     this.OnFocusingNode(nodeKey, e);
    if(this.RaiseNodeExpanding(nodeKey, e))
     this.ExpandNode(nodeKey);    
    return;
   }
   if(className.indexOf(this.CollapseButtonClassName) > -1) {
    if(this.enableFocusedNode && this.focusOnExpandCollapse)
     this.OnFocusingNode(nodeKey, e);
    if(this.RaiseNodeCollapsing(nodeKey, e))
     this.CollapseNode(nodeKey);
    return;   
   }
  }
  if(tag == "INPUT" && className == this.SelectionCheckClassName && !this.GetDataTable().onmousedown) {
   this.OnFocusingNode(nodeKey, e);
   this.OnNodeSelecting(source);
   return;
  }    
  if(!sourceIsIndent) {     
   var processOnServer = this.enableFocusedNode ? this.OnFocusingNode(nodeKey, e) : false;
   if(!sourceIsCommandCell 
    && this.expandCollapseAction == this.ExpandCollapseAction.NodeClick 
    && this.TryExpandCollapse(nodeKey, row))
    return;    
   if(processOnServer)
    this.SendDummyCommand();
  }
 },
 OnDataTableDblClick: function(e) {
  if(this.syncLock) return;
  e = _aspxGetEvent(e);  
  var source = _aspxGetEventSource(e);
  if(this.FindIndentCell(source) != null)
   return;  
  var row = this.FindDataRow(source);
  if(!_aspxIsExistsElement(row))
   return;
  var nodeKey = this.GetNodeKeyByRow(row);
  if(!this.IsEditing())
   _aspxClearSelection();    
  if(!this.RaiseNodeDblClick(nodeKey, e))
   return;
  if(this.expandCollapseAction == this.ExpandCollapseAction.NodeDblClick)
   this.TryExpandCollapse(nodeKey, row);
 },
 TryExpandCollapse: function(nodeKey, row) {
  var state = this.GetNodeState(nodeKey, row);
  if(state == "Expanded") {
   this.CollapseNode(nodeKey);
   return true;
  } else if(state == "Collapsed") {
   this.ExpandNode(nodeKey);
   return true;
  }
  return false;
 },  
 OnHeaderMouseDown: function(element, e) { 
  if(this.syncLock) return;
  if(!_aspxGetIsLeftButtonPressed(e)) return;
  var canDrag = element.id.indexOf(this.DragAndDropTargetMark) > -1;
  var drag = this.dragHelper.CreateHeaderDrag(element, e, canDrag);
  this.dragHelper.CreateHeaderTargets(drag, e);  
 },
 OnHeaderClick: function(element, shiftKey, ctrlKey) {
  if(this.syncLock) return;
  var index = this.GetLastNumberOfId(element);
  var column = this.GetColumnByIndex(index);
  if(column != null && column.canSort)
   this.SendSortCommand(index, ctrlKey ? "none" : "", !shiftKey && !ctrlKey);
 },
 OnColumnMoving: function(sourceIndex, targetIndex, before) {    
  this.SendCommand("MoveColumn", [sourceIndex, targetIndex, before]);
 },
 OnNodeDeleting: function(nodeKey) {
  if(this.confirmDeleteMsg != null && !confirm(this.confirmDeleteMsg))
   return;
  this.DeleteNode(nodeKey);
 },
 OnContextMenu: function(objectType, objectKey, htmlEvent) {
  var e = new ASPxClientTreeListContextMenuEventArgs(objectType, objectKey, htmlEvent);
  this.RaiseContextMenu(e);
  return e.cancel;
 }, 
 DoCallback: function(result) {
  ASPxClientControl.prototype.DoCallback.call(this, result);
  this.syncLock = false;
 }, 
 OnCallback: function(result) {
  this.ProcessCallbackResult(result);
  this.EnsureIE8WideCellIsFilled();
 },
 OnCallbackError: function(result, data) {
  if(result != ""){
   var cell = this.GetErrorCell();
   if(_aspxIsExistsElement(cell)) {
    _aspxSetElementDisplay(cell.parentNode, true);
    _aspxSetInnerHtml(cell, result);
   } 
   else 
    alert(result);
  }
 },
 SendCommand: function(command, args) {
  if(this.syncLock)
   return;   
  this.SerializeEditorValues();
  var id = this.CommandId[command];
  this.ShowLoadingPanel();  
  var monoArg = _aspxIsExists(args) ? ([id].concat(args)).join(this.SeparatorToken) : id;
  if(_aspxIsExists(this.callBack) && this.CanCreateCallback()) {   
   this.PurgeCaches();
   this.syncLock = true;
   this.CreateCallback(monoArg, command);
  } else 
   this.SendPostBack(monoArg);  
 },
 SendDummyCommand: function(sync) {
  this.SendCommand("Dummy");
  if(!sync)
   this.syncLock = false; 
 },
 SendSortCommand: function(columnIndex, order, reset) {
  this.SendCommand("Sort", [columnIndex, order, reset]);
 }, 
 SendPagerCommand: function(arg, fromKbd) {
  var list = [ arg ];
  if(fromKbd) list.push("k");
  this.SendCommand("Pager", list);
 },
 SendAsyncCommand: function(command, args) {
  if(!_aspxIsExists(this.callBack)) return;
  var monoArg = [this.CommandId[command], args].join(this.SeparatorToken);
  this.CreateCallback(monoArg, command);
 },
 SendGetNodeValuesCommand: function(handler, mode, nodeKey, fieldNames) {
  if(fieldNames === null) fieldNames = "";
  var index = this.GetCallbackHandlerIndex(handler);
  var monoArg = ([index, mode, nodeKey].concat(fieldNames)).join(this.SeparatorToken);
  this.SendAsyncCommand("GetNodeValues", monoArg);  
 },    
 ShowLoadingPanel: function() {
  if(this.lpDisable || this.lpTimer > -1)
   return;
  this.HideLoadingPanel();
  this.HideLoadingDiv();
  this.CreateLoadingDiv(this.GetUpdatableCell());   
  if(this.lpDelay > 10) {
   var js = "aspxTLShowLoadingPanel('" + this.name + "')";
   this.lpTimer = _aspxSetTimeout(js, this.lpDelay);
  } else {
   this.ShowLoadingPanelCore();
  }    
 },
 ShowLoadingPanelCore: function() {
  this.ClearLoadingPanelTimer();
  this.GetLoadingDiv().style.cursor = "wait";
  this.CreateLoadingPanelWithAbsolutePosition(this.GetUpdatableCell());
 },
 ClearLoadingPanelTimer: function() {
  this.lpTimer = _aspxClearTimer(this.lpTimer);  
 },
 HideLoadingPanel: function() {
  this.ClearLoadingPanelTimer();
  this.constructor.prototype.HideLoadingPanel.call(this);
 },
 ProcessCallbackResult: function(resultObj) {
  if(resultObj.customData) {   
   if(_aspxIsExists(resultObj.handler)) {
    var index = parseInt(resultObj.handler);
    var handler = this.callbackHandlersPool[index];
    this.callbackHandlersPool[index] = null;
    handler(resultObj.data);
   } else {
    this.RaiseCustomDataCallback(resultObj.arg, resultObj.data);
   }
   return;
  }      
  this.GetCallbackStateInput().value = resultObj.state;
  if(_aspxIsExists(resultObj.fkey))
   this.SetFocusedNodeKeyInternal(resultObj.fkey);
  var selectionInput = this.GetSelectionInput();
  if(_aspxIsExistsElement(selectionInput))
   selectionInput.value = "";
  var selectAllMarkInput = this.GetSelectAllMarkInput();
  if(_aspxIsExistsElement(selectAllMarkInput))
   selectAllMarkInput.value = "";
  if(_aspxIsExists(resultObj.pi))
   this.pageIndex = resultObj.pi;
  if(_aspxIsExists(resultObj.pc))
   this.pageCount = resultObj.pc;
  if(resultObj.cp) {   
   for(var name in resultObj.cp)
    this[name] = resultObj.cp[name];
  }
  if(_aspxIsExists(resultObj.partial))
   this.ProcessPartialCallbackResult(resultObj);
  else
   this.ProcessFullCallbackResult(resultObj);   
  this.maxVisibleLevel = resultObj.level;
  this.visibleColumnCount = resultObj.visColCount;
  this.rowCount = resultObj.rows;
  this.editingKey = _aspxIsExists(resultObj.editingKey) ? resultObj.editingKey : null;
  this.isNewNodeEditing = _aspxIsExists(resultObj.newNode);
 }, 
 ProcessPartialCallbackResult: function(resultObj) {
  this.UpdateFirstDataCellSpans(resultObj.level);
  var row = this.GetRowByNodeKey(resultObj.partial);
  if(!_aspxIsExistsElement(row))
   return;
  if(resultObj.remove)
   this.KillNextRows(row, resultObj.remove);
  var uid = "";
  var cell = this.GetUpdatableCell();
  var html = cell.innerHTML;
  do {
   uid = this.GenerateUID();
  } while(html.indexOf(uid) > -1);
  var placeholder = document.createTextNode(uid);  
  row.parentNode.insertBefore(placeholder, row);
  this.DestroyHtmlRow(row);  
  this.HideLoadingDiv();
  this.HideLoadingPanel();
  html = cell.innerHTML.replace(/<script(.|\s)*?\/script>/ig, "");  
  html = html.replace(uid, resultObj.data);
  _aspxSetInnerHtml(cell, html);
 },
 ProcessFullCallbackResult: function(resultObj) {
  _aspxSetInnerHtml(this.GetUpdatableCell(), resultObj.data);
 },
 GetCallbackStateInput:   function() { return this.GetCachedElementById("STATE"); },
 GetFocusedKeyInput:    function() { return this.GetCachedElementById("FKey"); },
 GetSelectionInput:    function() { return this.GetCachedElementById("Sel"); },
 GetSelectAllMarkInput:   function() { return this.GetCachedElementById("SAM"); },
 GetEditorValuesInput:   function() { return this.GetCachedElementById("EV"); },
 GetDataTable:     function() { return this.GetCachedElementById("D"); },
 GetUpdatableCell:    function() { return this.GetCachedElementById("U"); },   
 GetStyleTable:     function() { return this.GetCachedElementById("ST"); },
 GetDragAndDropArrowDownImage: function() { return this.GetCachedElementById("DAD"); },
 GetDragAndDropArrowUpImage:  function() { return this.GetCachedElementById("DAU"); },
 GetDragAndDropHideImage:  function() { return this.GetCachedElementById("DH"); },
 GetDragAndDropNodeImage:  function() { return this.GetCachedElementById("DN"); },
 GetErrorCell:     function() { return this.GetCachedElementById("Error"); },
 GetHeaderRow:     function() { return this.GetCachedElementById("HDR"); },
 GetIE8Row:       function() { return this.GetCachedElementById("IE8R"); },
 GetCustomizationWindow: function() { 
  return aspxGetControlCollection().Get(this.name + this.GetCustomizationWindowSuffix()); 
 },
 GetCustomizationWindowElement: function() {
  var win = this.GetCustomizationWindow();
  return win ? win.GetWindowElement(-1) : null;  
 },
 GetHeaderSuffix: function() { return this.DragAndDropTargetMark + "H-"; },
 GetCustomizationWindowSuffix: function() { return this.DragAndDropTargetMark + "CW"; },
 GetEmptyHeaderSuffix: function() { return this.DragAndDropTargetMark + "EH"; }, 
 CreateColumn: function(index, name, fieldName, canSort, showInCw) {
  var column = new ASPxClientTreeListColumn(index, name, fieldName);  
  column.canSort = canSort;
  column.showInCw = showInCw;
  this.columns.push(column);
 },
 FindColumn: function(id) {
  if(!_aspxIsExists(id)) return null;
  if(id.__dxColumnObject)
   return id;
  if(typeof id == "number")
   return this.GetColumnByIndex(id);
  var result = this.GetColumnByName(id);
  if(result == null)
   result = this.GetColumnByFieldName(id);
  return result;
 },
 UpdateRowStyle: function(nodeKey) {
  if(!this.allowStylizeEditingNode && nodeKey == this.editingKey)
   return;
  var row = this.GetRowByNodeKey(nodeKey);
  if(!_aspxIsExistsElement(row))
   return;
  var isFocused = this.focusedKey == nodeKey;
  var isSelected = this.IsRowSelected(row);
  if(isFocused) {
   this.ApplyRowStyle(row, 0);
  } else if(isSelected) {
   this.ApplyRowStyle(row, 1);
  } else {  
   var index = row.rowIndex;
   this.ApplyRowStyle(row, 2 + index);
  }
 }, 
 ApplyRowStyle: function(row, index) {
  var styledCells = this.GetStyleTable().rows[0].cells;
  var max = styledCells.length - 1;
  if(index > max)
   index = max; 
  row.className = styledCells[index].className;
  row.style.cssText = styledCells[index].innerHTML;
 },
 GetNodeKeyByRow: function(row) {
  return this.UnescapeNodeKey(row.id.substr(this.rowIdPrefix.length));
 },
 GetRowByNodeKey: function(nodeKey) {   
  var id = this.RowIDSuffix + this.EscapeNodeKey(nodeKey);  
  return this.GetCachedElementById(id);  
 },
 EscapeNodeKey: function(value) {
  return value.replace(/[^A-Za-z0-9]/g, function(match) { 
   return "_" + match.charCodeAt(0) + "_";
  });
 },
 UnescapeNodeKey: function(value) {
  return value.replace(/_\d+_/g, function(match) { 
   return String.fromCharCode(match.substr(1, match.length - 2));
  });
 },
 GetAllDataRows: function() {
  var result = [ ];
  var rows = this.GetDataTable().rows;
  for(var i = 0; i < rows.length; i++) {
   var row = rows[i];   
   if(!this.IsElementDataRow(row)) continue;
   result.push(row);
  }
  return result;
 },  
 IsElementEmptyHeader: function(element) {
  return element.id == this.name + this.GetEmptyHeaderSuffix();
 },
 IsElementDataRow: function(element) {
  return element.id.indexOf(this.rowIdPrefix) == 0;  
 }, 
 IsElementIndentCell: function(element) {
  return element.className.indexOf("dxtl__I") > -1;
 }, 
 IsElementCommandCell: function(element) {
  return element.className.indexOf("dxtl__cc") > -1;
 }, 
 FindDataRow:  function(element) { return this.FindElementUpwardsCore(element, this.IsElementDataRow); },
 FindIndentCell:  function(element) { return this.FindElementUpwardsCore(element, this.IsElementIndentCell); },
 FindCommandCell: function(element) { return this.FindElementUpwardsCore(element, this.IsElementCommandCell); },
 FindElementUpwardsCore: function(startElement, matchEvaluator) {
  var dataTable = this.GetDataTable();
  var element = startElement;
  while(_aspxIsExistsElement(element) && element != dataTable) {
   if(matchEvaluator.call(this, element))
    return element;
   element = element.parentNode;
  }
  return null;  
 },
 IsRowSelected: function(row) {
  var check = this.FindSelectionCheck(row);
  if(!_aspxIsExistsElement(check))
   return null;
  return check.checked;
 },
 FindSelectionCheck: function(row) {
  var elements = row.getElementsByTagName("INPUT");
  for(var i = 0; i < elements.length; i++) {
   var element = elements[i];
   if(element.type == "checkbox" && element.className == this.SelectionCheckClassName)
    return element;
  }
  return null;
 },
 PersistSelectionDiff: function() {
  var input = this.GetSelectionInput();
  if(!_aspxIsExistsElement(input))
   return;
  var list = [ ];
  for(var key in this.selectionDiff)
   list.push(key);
  input.value = list.join(this.SeparatorToken);
 },
 UpdateFirstDataCellSpans: function(newMaxVisibleLevel) {
  if(this.maxVisibleLevel == newMaxVisibleLevel) 
   return;
  var ie8row = this.GetIE8Row();
  var rows = this.GetDataTable().rows;
  var spanDiff = newMaxVisibleLevel - this.maxVisibleLevel;
  for(var i = ie8row ? 1 : 0; i < rows.length; i++) {
   var row = rows[i];
   var tempCell;
   var firstDataCell;
   var tempCell = row.cells[row.cells.length - 1];
   if(tempCell.colSpan > 1)
    firstDataCell = tempCell; 
   else 
    firstDataCell = row.cells[row.cells.length - this.GetColumnCellCount()];
   var newSpan = firstDataCell.colSpan + spanDiff;
   if(newSpan > 0)
    firstDataCell.colSpan = newSpan;
  }
  if(ie8row)
   ie8row.cells[0].colSpan += spanDiff;  
 },
 KillNextRows: function(row, count) {  
  while(count-- > 0) {
   var rowToKill = row.nextSibling;
   if(!_aspxIsExistsElement(rowToKill))
    break;   
   if(rowToKill.nodeType != 1) { 
    count++;
    _aspxRemoveElement(rowToKill);
   } else {
    this.DestroyHtmlRow(rowToKill);
   }   
  }
 },
 DestroyHtmlRow: function(row) {
  for(var i = row.cells.length - 1; i >= 0; i--)
   row.cells[i].innerHTML = "";
  _aspxRemoveElement(row);  
 },
 SetFocusedNodeKeyInternal: function(key) {
  this.focusedKey = key;
  this.GetFocusedKeyInput().value = key;
 }, 
 GetLastNumberOfId: function(element) {  
  var matches = element.id.match(/\d+/g);
  if(matches != null) {
   var count = matches.length;
   if(count > 0)
    return parseInt(matches[count - 1], 10);
  }
  return -1;
 },
 GetCachedElementById: function(id) {
  id = this.name + "_" + id;
  if(!_aspxIsExistsElement(this.elementCache[id]))
   this.elementCache[id] = _aspxGetElementById(id);
  return this.elementCache[id];
 },
 GenerateUID: function() {
  var result = "";
  for(var i = 0; i < 16; i++) {
   var num = Math.floor(10000 * (1 + Math.random()));
   result += num.toString(36);
  }
  return result;
 },
 PurgeCaches: function() {  
  this.elementCache = { };  
  this.focusedKey = null;
  this.selectionDiff = { };
 },
 GetColumnCellCount: function() {
  var count = this.visibleColumnCount;
  if(count < 1) count = 1; 
  return count;
 },
 GetCallbackHandlerIndex: function(handler) {
  for(var i = 0; i < this.callbackHandlersPool.length; i++) {
   if(this.callbackHandlersPool[i] == null) {
    this.callbackHandlersPool[i] = handler;
    return i;
   }
  }
  this.callbackHandlersPool.push(handler);
  return this.callbackHandlersPool.length - 1;
 },
 EnsureIE8WideCellIsFilled: function() {
  var row = this.GetIE8Row();
  if(!row)
   return;
  var wideCell = row.cells[1];
  if(_aspxTrim(wideCell.innerHTML).length > 0)
   return;
  var sb = new ASPxStringBuilder("<div style=\"overflow: hidden; height: 0;\">");
  var filler = "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ";
  for(var i = 0; i < 100; i++)
   sb.Append(filler);
  sb.Append("</div>");
  wideCell.innerHTML = sb.ToString();
 },
 GetEditorObjects: function() {
  var list = [ ];
  var clientObjects = aspxGetControlCollection().elements;  
  for(var name in clientObjects) {
   if(name.indexOf(this.name) != 0)
    continue;
   var pos = name.indexOf(this.EditorSuffix);
   if(pos < 0 || name.indexOf("_", pos) > -1)
    continue;
   var obj = clientObjects[name];
   if(!_aspxIsExists(obj.GetMainElement) || !_aspxIsExistsElement(obj.GetMainElement()))
    continue;   
   list.push(obj);
  }
  return list;
 },
 SerializeEditorValues: function() {
  var editors = this.GetEditorObjects();
  var count = editors.length;
  var result = [ count ];      
  for(var i = 0; i < count; i++) {
   var columnIndex = this.GetEditorColumnIndex(editors[i]);
   var value = editors[i].GetValueString();
   var length = -1;
   if(!_aspxIsExists(value)) {
    value = "";
   } else {
    value = value.toString();
    length = value.length;
   }
   result.push(columnIndex);
   result.push(length);
   result.push(value);
  }
  this.GetEditorValuesInput().value = result.join(this.SeparatorToken);  
 },
 GetEditorColumnIndex: function(editorObject) {
  var name = editorObject.name;
  return name.substr(name.lastIndexOf(this.EditorSuffix) + this.EditorSuffix.length);
 },
 SeparatorToken: " ",
 RowIDSuffix: "R-",
 EditorSuffix: "DXEDITOR",
 DragAndDropTargetMark: "_DX-DnD-",  
 ExpandButtonClassName: "dxtl__Expand",
 CollapseButtonClassName: "dxtl__Collapse",
 SelectionCheckClassName: "dxtl__Sel",
 CommandId: {
  Expand:    1,
  Collapse:   2,
  Pager:    3,
  CustomDataCallback: 4,
  MoveColumn:   5,
  Sort:    6,
  Dummy:    8,
  ExpandAll:   9,
  CollapseAll:  10,
  CustomCallback:  11,
  StartEdit:   12,
  UpdateEdit:   14,
  CancelEdit:   15,
  MoveNode:   16,
  DeleteNode:   17,
  StartEditNewNode: 18,
  GetNodeValues:  20
 }, 
 ExpandCollapseAction: {
  Button: 0,
  NodeClick: 1,
  NodeDblClick: 2
 },
 GetNodeValuesCommandMode: { 
  ByKey:    0,
  Visible:   1,
  SelectedAll:  2,
  SelectedVisible: 3
 },
 RaiseContextMenu: function(e) {
  if(!this.ContextMenu.IsEmpty())
   this.ContextMenu.FireEvent(this, e);
 },
 RaiseCustomButtonClick: function(nodeKey, buttonIndex, buttonID) {
  var handler = this.CustomButtonClick;
  if(handler.IsEmpty()) return false;
  handler.FireEvent(this, new ASPxClientTreeListCustomButtonEventArgs(nodeKey, buttonIndex, buttonID));
 },
 GetFocusedNodeKey: function() {
  if(!this.enableFocusedNode)
   return "";
  if(this.focusedKey === null)
   this.focusedKey = this.GetFocusedKeyInput().value;
  return this.focusedKey;
 },
 SetFocusedNodeKey: function(key) {
  if(!this.enableFocusedNode)
   return;
  var prevKey = this.GetFocusedNodeKey();  
  this.SetFocusedNodeKeyInternal(key);
  this.UpdateRowStyle(prevKey); 
  this.UpdateRowStyle(key);
 },
 RaiseNodeFocusing: function(nodeKey, htmlEvent) {
  if(this.NodeFocusing.IsEmpty()) return true;
  var args = new ASPxClientTreeListNodeEventArgs(nodeKey, htmlEvent);
  this.NodeFocusing.FireEvent(this, args);
  return !args.cancel;
 }, 
 RaiseFocusedNodeChanged: function() {
  var processOnServer = false;
  if(!this.FocusedNodeChanged.IsEmpty()) {
   var args = new ASPxClientProcessingModeEventArgs(processOnServer);
   this.FocusedNodeChanged.FireEvent(this, args);
   processOnServer = args.processOnServer;   
  }
  return this.focusSendsCallback || processOnServer;
 },
 RaiseSelectionChanged: function() {
  var processOnServer = false;
  if(!this.SelectionChanged.IsEmpty()) {
   var args = new ASPxClientProcessingModeEventArgs(processOnServer);
   this.SelectionChanged.FireEvent(this, args);
   processOnServer = args.processOnServer;
  }
  return this.selectionSendsCallback || processOnServer;
 },
 IsNodeSelected: function(nodeKey) {
  var row = this.GetRowByNodeKey(nodeKey);
  if(!_aspxIsExistsElement(row))
   return null;
  return this.IsRowSelected(row);
 },
 SelectNode: function(nodeKey, state) { 
  var row = this.GetRowByNodeKey(nodeKey);
  if(!_aspxIsExistsElement(row))
   return;   
  var check = this.FindSelectionCheck(row);
  if(!_aspxIsExistsElement(check) || check.checked == state)
   return;
  if(!_aspxIsExists(state))
   state = true;   
  check.checked = state;
  this.OnNodeSelectingCore(check);
 },
 GetVisibleSelectedNodeKeys: function() {
  var rows = this.GetAllDataRows();
  var result = [ ];
  for(var i = 0; i < rows.length; i++) {
   var key = this.GetNodeKeyByRow(rows[i]);
   if(this.IsNodeSelected(key))
    result.push(key);
  }
  return result;
 }, 
 IsCustomizationWindowVisible: function() {
  var win = this.GetCustomizationWindow();
  return win != null && win.IsVisible();
 },
 ShowCustomizationWindow: function(htmlElement) {
  var win = this.GetCustomizationWindow();
  if(win == null)
   return;
  if(!_aspxIsExistsElement(htmlElement))
   htmlElement = this.GetMainElement();
  win.ShowAtElement(htmlElement);
 },
 HideCustomizationWindow: function() {
  var win = this.GetCustomizationWindow();
  if(win != null)
   win.Hide();
 },
 RaiseCustomizationWindowCloseUp: function() {
  if(!this.CustomizationWindowCloseUp.IsEmpty())
   this.CustomizationWindowCloseUp.FireEvent(this, { } );
 },
 PerformCustomCallback: function(arg) {
  this.PerformCallback(arg);  
 },
 PerformCallback: function(args) {
  this.SendCommand("CustomCallback", [args]);
 },
 PerformCustomDataCallback: function(arg) {
  this.SendAsyncCommand("CustomDataCallback", arg);
 },
 RaiseCustomDataCallback: function(arg, result) {
  if(!this.CustomDataCallback.IsEmpty()) {
   var e = new ASPxClientTreeListCustomDataCallbackEventArgs(arg, result);
   this.CustomDataCallback.FireEvent(this, e);
  }  
 },
 GetNodeValues: function(nodeKey, fieldNames, onCallback) {
  this.SendGetNodeValuesCommand(onCallback, this.GetNodeValuesCommandMode.ByKey, nodeKey, fieldNames);
 }, 
 GetVisibleNodeValues: function(fieldNames, onCallback) {
  this.SendGetNodeValuesCommand(onCallback, this.GetNodeValuesCommandMode.Visible, "", fieldNames);
 },
 GetSelectedNodeValues: function(fieldNames, onCallback, visibleOnly) {
  var mode = visibleOnly 
   ? this.GetNodeValuesCommandMode.SelectedVisible 
   : this.GetNodeValuesCommandMode.SelectedAll; 
  this.SendGetNodeValuesCommand(onCallback, mode, "", fieldNames);
 },  
 GoToPage: function(index) {
  if(index < -1)
   return;
  this.SendPagerCommand("PN" + index);
 },
 PrevPage: function(fromKbd) {
  this.SendPagerCommand("PBP", fromKbd);
 }, 
 NextPage: function(fromKbd) {
  this.SendPagerCommand("PBN", fromKbd);
 },
 GetNodeState: function(nodeKey, row) {  
  if(!_aspxIsExists(row))
   row = this.GetRowByNodeKey(nodeKey);
  if(!_aspxIsExistsElement(row))
   return "NotFound";
  var children = row.getElementsByTagName("IMG");
  for(var i = 0; i < children.length; i++) {
   var name = children[i].className;
   if(name.indexOf(this.ExpandButtonClassName) > -1)
    return "Collapsed";
   if(name.indexOf(this.CollapseButtonClassName) > -1)
    return "Expanded";
  }
  return "Child";
 }, 
 ExpandAll: function() {
  this.SendCommand("ExpandAll");
 },
 CollapseAll: function() {
  this.SendCommand("CollapseAll");
 },
 ExpandNode: function(key) {
  this.SendCommand("Expand", [key]);
 },
 CollapseNode: function(key) {
  this.SendCommand("Collapse", [key]);
 },
 GetVisibleNodeKeys: function() {
  var rows = this.GetAllDataRows();
  var result = [ ];
  for(var i = 0; i < rows.length; i++)
   result.push(this.GetNodeKeyByRow(rows[i]));
  return result;
 },
 GetNodeHtmlElement: function(nodeKey) {
  return this.GetRowByNodeKey(nodeKey);
 },  
 RaiseNodeClick: function(nodeKey, htmlEvent) {
  if(this.NodeClick.IsEmpty()) return true;
  var e = new ASPxClientTreeListNodeEventArgs(nodeKey, htmlEvent);
  this.NodeClick.FireEvent(this, e);
  return !e.cancel;  
 },
 RaiseNodeDblClick: function(nodeKey, htmlEvent) {
  if(this.NodeDblClick.IsEmpty()) return true;
  var e = new ASPxClientTreeListNodeEventArgs(nodeKey, htmlEvent);
  this.NodeDblClick.FireEvent(this, e);
  return !e.cancel;
 },
 RaiseNodeExpanding: function(nodeKey, htmlEvent) {
  if(!this.NodeExpanding.IsEmpty()) {
   var e = new ASPxClientTreeListNodeEventArgs(nodeKey, htmlEvent);
   this.NodeExpanding.FireEvent(this, e);
   return !e.cancel;
  }
  return true;
 },
 RaiseNodeCollapsing: function(nodeKey, htmlEvent) {
  if(!this.NodeCollapsing.IsEmpty()) {
   var e = new ASPxClientTreeListNodeEventArgs(nodeKey, htmlEvent);
   this.NodeCollapsing.FireEvent(this, e);
   return !e.cancel;
  }
  return true;
 },
 RaiseStartDragNode: function(nodeKey, htmlEvent, targets) {
  if(this.StartDragNode.IsEmpty()) return true;
  var e = new ASPxClientTreeListStartDragNodeEventArgs(nodeKey, htmlEvent, targets);
  this.StartDragNode.FireEvent(this, e);
  return !e.cancel;
 },
 RaiseEndDragNode: function(nodeKey, htmlEvent, targetElement) {
  if(this.EndDragNode.IsEmpty()) return true;
  var e = new ASPxClientTreeListEndDragNodeEventArgs(nodeKey, htmlEvent, targetElement);
  this.EndDragNode.FireEvent(this, e);
  return !e.cancel;
 },
 GetVisibleColumnCount: function() {
  return this.visibleColumnCount;
 }, 
 GetColumnCount: function() {
  return this.columns.length;
 },
 GetColumnByIndex: function(index) {
  for(var i = 0; i < this.columns.length; i++) {
   if(this.columns[i].index == index)
    return this.columns[i];
  }
  return null;
 }, 
 GetColumnByName: function(name) {
  if(name == "")
   return null;
  for(var i = 0; i < this.columns.length; i++) {
   if(this.columns[i].name == name)
    return this.columns[i];
  }
  return null;
 },
 GetColumnByFieldName: function(fieldName) {
  if(fieldName == "")
   return null;
  for(var i = 0; i < this.columns.length; i++) {
   if(this.columns[i].fieldName == fieldName)
    return this.columns[i];
  }
  return null;
 },
 SortBy: function(columnId, order, reset) {
  var column = this.FindColumn(columnId);
  if(column == null)
   return;
  if(!_aspxIsExists(order)) order = "";
  if(!_aspxIsExists(reset)) reset = true;
  this.SendSortCommand(column.index, order, reset);
 },
 StartEdit: function(nodeKey) {
  this.SendCommand("StartEdit", [nodeKey]);
 },
 UpdateEdit: function() {
  if(!this.IsEditing()) return;
  var editors = this.GetEditorObjects();  
  for(var i = 0; i < editors.length; i++) {
   var editor = editors[i];
   editor.Validate();
   if(!editor.GetIsValid()) {
    if(editor.setFocusOnError)
     editor.Focus();
    return;
   }
  }
  this.SendCommand("UpdateEdit");
 },
 CancelEdit: function() {
  if(!this.IsEditing()) return;
  this.SendCommand("CancelEdit");
 },
 IsEditing: function() { 
  return this.editingKey != null || this.isNewNodeEditing;
 },
 GetEditingNodeKey: function() { 
  return this.editingKey; 
 },
 MoveNode: function(nodeKey, parentNodeKey) {
  this.SendCommand("MoveNode", [this.EscapeNodeKey(nodeKey), this.EscapeNodeKey(parentNodeKey)]);
 },
 DeleteNode: function(nodeKey) {
  this.SendCommand("DeleteNode", [nodeKey]);
 },
 StartEditNewNode: function(parentNodeKey) {
  if(!_aspxIsExists(parentNodeKey))
   parentNodeKey = "";
  this.SendCommand("StartEditNewNode", [parentNodeKey]);
 },
 GetEditor: function(columnId) {
  var column = this.FindColumn(columnId);
  if(column == null) return null;
  var editors = this.GetEditorObjects();
  for(var i = 0; i < editors.length; i++) {
   if(column.index == this.GetEditorColumnIndex(editors[i]))
    return editors[i];
  }
  return null;
 },
 GetEditValue: function(columnId) {
  var editor = this.GetEditor(columnId);
  if(editor == null) return null;
  return editor.GetValue();
 },
 SetEditValue: function(columnId, value) {
  var editor = this.GetEditor(columnId);
  if(editor != null)
   editor.SetValue(value);
 },
 FocusEditor: function(columnId) {
  var editor = this.GetEditor(columnId);
  if(editor != null && _aspxIsExists(editor.SetFocus))
   editor.SetFocus();
 }
});
ASPxClientTreeList.Cast = ASPxClientControl.Cast;
ASPxClientTreeListDragHelper = _aspxCreateClass(null, {
 constructor: function(treeList)  {
  this.treeList = treeList;  
 },
 CreateHeaderDrag: function(element, e, canDrag) {  
  e = _aspxGetEvent(e);
  var drag = new ASPxClientDragHelper(e, element, true);  
  drag.canDrag = canDrag;
  drag.ctrl = e.ctrlKey;
  drag.shift = e.shiftKey;
  drag.treeListHelper = this;  
  drag.onDoClick = this.OnHeaderClick;
  drag.onCloneCreating = this.OnHeaderCloneCreating;
  drag.onEndDrag = this.OnHeaderEndDrag;
  drag.onCancelDrag = this.OnHeaderCancelDrag;
  return drag;  
 },
 CreateHeaderTargets: function(drag, e) {
  if(!drag.canDrag)
   return;
  var targets = new ASPxClientCursorTargets();    
  targets.obj = drag.obj;
  targets.treeListHelper = this;
  targets.onTargetChanging = this.OnHeaderTargetChanging; 
  targets.onTargetChanged = this.OnHeaderTargetChanged;
  var tree = this.treeList;  
  targets.RegisterTargets(tree.GetDataTable().rows[tree.GetIE8Row() ? 1 : 0],
   [ tree.GetEmptyHeaderSuffix(), tree.GetHeaderSuffix() ]);
  var cw = tree.GetCustomizationWindowElement();
  if(cw != null) {
   var index = this.treeList.GetLastNumberOfId(drag.obj);
   var columnObj = this.treeList.FindColumn(index);
   if(columnObj && columnObj.showInCw)
    targets.RegisterTargets(cw, [ tree.GetCustomizationWindowSuffix() ]);
  }
 }, 
 OnHeaderClick: function(drag) {
  var treeList = drag.treeListHelper.treeList; 
  treeList.OnHeaderClick(drag.obj, drag.shift, drag.ctrl);
 },
 OnHeaderCloneCreating: function(clone) { 
  clone.colSpan = 1; 
  ASPxClientTreeListDragHelper.RestoreElementBorder(clone);  
  var table = document.createElement("table");
  table.cellSpacing = 0;
  var row = table.insertRow(-1);
  row.appendChild(clone);
  table.style.width = this.obj.offsetWidth + "px";
  table.style.opacity = 0.80;
  table.style.filter = "alpha(opacity=80)"; 
  return table;
 },  
 OnHeaderEndDrag: function(drag) {
  if(drag.targetElement == null) 
   return;  
  var treeList = drag.treeListHelper.treeList;
  var sourceIndex = treeList.GetLastNumberOfId(drag.obj);
  var targetIndex;
  var cwElement = treeList.GetCustomizationWindowElement();
  if(_aspxIsExists(cwElement) && drag.targetElement.id == cwElement.id) {
   targetIndex = -1;
  } else if(treeList.IsElementEmptyHeader(drag.targetElement)) {
   targetIndex = 0;
  } else {
   targetIndex = treeList.GetLastNumberOfId(drag.targetElement);
   if(sourceIndex == targetIndex)
    return;
  }  
  treeList.OnColumnMoving(sourceIndex, targetIndex, drag.targetTag);
 },  
 OnHeaderCancelDrag: function(drag) {
  if(drag.canDrag)
   drag.treeListHelper.HideHeaderDragImages();
 },
 OnHeaderTargetChanging: function(targets) {
  targets.targetTag = targets.isLeftPartOfElement();
 },  
 OnHeaderTargetChanged: function(targets) { 
  if(__aspxDragHelper == null) 
   return;
  var helper = targets.treeListHelper;
  helper.HideHeaderDragImages();
  if(targets.targetElement != null && targets.targetElement != __aspxDragHelper.obj) {   
   __aspxDragHelper.targetElement = targets.targetElement;
   __aspxDragHelper.targetTag = targets.targetTag;   
   var left = _aspxGetAbsoluteX(targets.targetElement);
   if(!targets.targetTag)
    left += targets.targetElement.offsetWidth;
   if(targets.targetElement == helper.treeList.GetCustomizationWindowElement()) {
    var hideImage = helper.treeList.GetDragAndDropHideImage();
    hideImage.style.top = "";
    __aspxDragHelper.addElementToDragDiv(hideImage);
   } else {
    helper.SetHeaderDragImagesPosition(targets.targetElement, left);
   }
  } else {
   __aspxDragHelper.targetElement = null;
  }
 },
 SetHeaderDragImagesPosition: function(element, left) {
  this.ShowHeaderDragImages();
  var arrowDown = this.treeList.GetDragAndDropArrowDownImage();
  var arrowUp = this.treeList.GetDragAndDropArrowUpImage();
  _aspxSetAbsoluteX(arrowDown, Math.ceil(left - arrowDown.offsetWidth / 2));
  _aspxSetAbsoluteX(arrowUp, Math.ceil(left - arrowUp.offsetWidth / 2));
  var top = _aspxGetAbsoluteY(element);
  _aspxSetAbsoluteY(arrowDown, top - arrowDown.offsetHeight);
  _aspxSetAbsoluteY(arrowUp, top + element.offsetHeight);
 },
 HideHeaderDragImages: function() {
  this.SetHeaderDragImagesVisibility("hidden");
  if(__aspxDragHelper != null)
   __aspxDragHelper.removeElementFromDragDiv();  
 },
 ShowHeaderDragImages: function() {
  this.SetHeaderDragImagesVisibility("visible");
 },
 SetHeaderDragImagesVisibility: function(value) {
  this.treeList.GetDragAndDropArrowDownImage().style.visibility = value;
  this.treeList.GetDragAndDropArrowUpImage().style.visibility = value;
 },
 CreateNodeDrag: function(row, e, canDrag) {
  e = _aspxGetEvent(e);
  var drag = new ASPxClientDragHelper(e, row, true);
  drag.__treeList = this.treeList;
  drag.__savedHtmlEvent = e;  
  drag.canDrag = canDrag;
  drag.onCloneCreating = this.OnNodeCloneCreating;
  drag.onCancelDrag = this.OnNodeCancelDrag;
  drag.onEndDrag = this.OnNodeEndDrag;
  drag.onDoClick = this.OnNodeClick;
  return drag;
 },
 CreateNodeTargets: function(targetElements, sourceElement) {
  var targets = new ASPxClientCursorTargets();
  targets.__treeList = this.treeList;
  for(var i = 0; i < targetElements.length; i++) {
   if(targetElements[i] == sourceElement) continue;
   targets.list.push(new ASPxClientCursorTarget(targetElements[i]));
  }
  targets.onTargetChanged = this.OnNodeTargetChanged;
 },
 OnNodeCloneCreating: function(row) {
  var treeList = __aspxDragHelper.__treeList;
  var table = document.createElement("table");
  table.cellSpacing = 0;  
  var tbody = document.createElement("tbody");
  table.appendChild(tbody);
  tbody.appendChild(row);
  var list = [ ];
  var thr = row.cells.length - treeList.GetColumnCellCount();
  var originalRow = __aspxDragHelper.obj;
  var removedWidth = 0;
  for(var i = 0; i < row.cells.length; i++) {
   var cell = row.cells[i];
   if(i < thr) {
    list.push(cell);
    removedWidth += originalRow.cells[i].offsetWidth;
   } else {
    ASPxClientTreeListDragHelper.RestoreElementBorder(cell, "top");
    ASPxClientTreeListDragHelper.RestoreElementBorder(cell, "bottom");
    if(i == thr)
     ASPxClientTreeListDragHelper.RestoreElementBorder(cell, "left");
    if(i == row.cells.length - 1)
     ASPxClientTreeListDragHelper.RestoreElementBorder(cell, "right");
   }    
  }
  for(var i = 0; i < list.length; i++)
   row.removeChild(list[i]);
  table.width = (originalRow.offsetWidth - removedWidth).toString() + "px";
  table.style.marginLeft = removedWidth + "px";
  table.style.opacity = 0.80;
  table.style.filter = "alpha(opacity=80)";
  return table;
 },
 OnNodeTargetChanged: function(targets) {
  if(__aspxDragHelper == null) return;
  var element = targets.targetElement;
  var hasTarget = _aspxIsExistsElement(element);
  targets.__treeList.dragHelper.SetNodeImageVisibility(hasTarget, element);
  __aspxDragHelper.targetElement = hasTarget ? targets.targetElement : null;
 },
 OnNodeCancelDrag: function(drag) {
  drag.__treeList.dragHelper.SetNodeImageVisibility(false);
 },
 OnNodeEndDrag: function(drag) {  
  if(drag.targetElement == null) 
   return;
  var sourceRow = drag.obj;
  var targetElement = drag.targetElement;
  if(sourceRow == targetElement)
   return;
  var treeList = drag.__treeList;
  var nodeKey = treeList.GetNodeKeyByRow(sourceRow);  
  if(!treeList.RaiseEndDragNode(nodeKey, drag.__savedHtmlEvent, targetElement))
   return;    
  if(treeList.IsElementDataRow(targetElement)) {
   var parentKey = treeList.GetNodeKeyByRow(targetElement);
   treeList.MoveNode(nodeKey, parentKey);
  } else if(targetElement == treeList.GetHeaderRow()) {
   treeList.MoveNode(nodeKey, "");
  } else {
   alert("Unprocessed custom target id=" + targetElement.id);
  }
 },
 OnNodeClick: function(drag) {
  drag.__treeList.OnDataTableClick(drag.__savedHtmlEvent);
 }, 
 SetNodeImageVisibility: function(visible, element) {
  if(element == document.body)
   visible = false;
  var img = this.treeList.GetDragAndDropNodeImage();
  img.style.visibility = visible ? "visible" : "hidden";
  if(!visible) return;
  if(element.cells && element.cells.length > 0) {   
   for(var i = element.cells.length - 1; i >= 0; i--) {
    if(element.cells[i].className.indexOf("dxtl__I") > -1) {    
     element = element.cells[1 + i];
     break;
    }
   }
  }
  _aspxSetAbsoluteX(img, _aspxGetAbsoluteX(element) - img.offsetWidth + 4);
  _aspxSetAbsoluteY(img, _aspxGetAbsoluteY(element) + Math.floor(0.5 * (element.clientHeight - img.clientHeight)));
 }
});
ASPxClientTreeListDragHelper.RestoreElementBorder = function(element, borderPart) {
 var ruleName = _aspxIsExists(borderPart) ? "border-" + borderPart + "-style" : "border-style";
 element.style.cssText += ";" + ruleName + ": solid!important;";
};
ASPxTreeListKbdHelper = _aspxCreateClass(ASPxKbdHelper, {
 HandleKeyDown: function(e) {
  var tree = this.control;
  var row = tree.GetRowByNodeKey(tree.GetFocusedNodeKey());
  var busy = tree.syncLock;
  switch(_aspxGetKeyCode(e)) {
   case ASPxKey.Down:
    if(!busy)
     this.TryMoveFocusDown(row, e.shiftKey);
    return true;
   case ASPxKey.Up:
    if(!busy)
     this.TryMoveFocusUp(row, e.shiftKey);
    return true;
   case ASPxKey.Right:
    if(!busy) {
     if(!this.TryExpand(row))
      this.TryMoveFocusDown(row, e.shiftKey);
    }
    return true;
   case ASPxKey.Left:
    if(!busy) {
     if(!this.TryCollapse(row))
      this.TryMoveFocusUp(row, e.shiftKey);
    }
    return true;
   case ASPxKey.PageDown:
    if(e.shiftKey) {
     if(!busy && tree.pageIndex < tree.pageCount - 1)
      tree.NextPage();
     return true; 
    }
    break;
   case ASPxKey.PageUp:
    if(e.shiftKey) {
     if(!busy && tree.pageIndex > 0)
      tree.PrevPage();
     return true; 
    }
    break;         
  }
  return false;
 },
 HandleKeyPress: function(e) {
  var tree = this.control;
  var key = tree.GetFocusedNodeKey();
  var busy = tree.syncLock;
  switch(_aspxGetKeyCode(e)) {
   case ASPxKey.Space:   
    if(!busy) {
     var state = tree.IsNodeSelected(key);
     if(state != null) {
      tree.SelectNode(key, !state);
      if(tree.RaiseSelectionChanged())
       tree.SendDummyCommand(true);
     }      
    }
    return true;
    case 43:   
    if(!busy)
     this.TryExpand(tree.GetRowByNodeKey(key));
    return true;
    case 45:    
    if(!busy)
     this.TryCollapse(tree.GetRowByNodeKey(key));
    return true;    
  }
  return false;
 },
 TryMoveFocusDown: function(row, select) {
  var tree = this.control;
  var nextRow = this.GetSiblingRow(row, 1);
  if(nextRow) {
   var processOnServer = tree.OnFocusingNode(tree.GetNodeKeyByRow(nextRow), {});
   if(select && !tree.recursiveSelection) {
    this.TrySelectNodes(row, nextRow);
   } else {
    tree.selectionStartKey = null;
   }
   if(processOnServer)
    tree.SendDummyCommand(true);
  } else if(tree.pageIndex > -1 && tree.pageIndex < tree.pageCount - 1) {
   tree.NextPage(true);
  }
 },
 TryMoveFocusUp: function(row, select) {
  var tree = this.control; 
  var prevRow = this.GetSiblingRow(row, -1);
  if(prevRow) {
   var processOnServer = tree.OnFocusingNode(tree.GetNodeKeyByRow(prevRow), {});
   if(select && !tree.recursiveSelection) {
    this.TrySelectNodes(row, prevRow);
   } else {
    tree.selectionStartKey = null;
   }
   if(processOnServer)
    tree.SendDummyCommand(true);
  } else if(tree.pageIndex > 0) {
   tree.PrevPage(true);
  } 
 },
 TryExpand: function(row) {
  var tree = this.control;
  if(tree.GetNodeState(null, row) == "Collapsed") {
   tree.ExpandNode(tree.GetNodeKeyByRow(row));
   return true;
  }
  return false;
 },
 TryCollapse: function(row) {
  var tree = this.control;
  if(tree.GetNodeState(null, row) == "Expanded") {
   tree.CollapseNode(tree.GetNodeKeyByRow(row));
   return true;
  }
  return false;
 },
 GetSiblingRow: function(row, offset) {
  var i = 0;
  while(i < Math.abs(offset)) {
   row = offset < 0 ? row.previousSibling : row.nextSibling;
   if(!row)
    return null;
   if(row.nodeType != 1)
    continue;
   i++;
  }
  return row;
 },
 TrySelectNodes: function(startRow, endRow) {
  var tree = this.control;
  if(tree.selectionStartKey != null)
   startRow = tree.GetRowByNodeKey(tree.selectionStartKey) || startRow;  
  tree.selectionStartKey = tree.GetNodeKeyByRow(startRow);
  if(!tree.FindSelectionCheck(tree.GetDataTable()))
   return ;
  var rows = tree.GetAllDataRows();
  var inside = false;
  var changed = false;
  for(var i = 0; i < rows.length; i++) {
   var hit = rows[i] == startRow || rows[i] == endRow;   
   if(hit && !inside) {
    inside = true;
    hit = false;
   }
   var key = tree.GetNodeKeyByRow(rows[i]);
   if(tree.IsNodeSelected(key) != inside)
    changed = true;
   tree.SelectNode(key, inside);
   if(inside && (hit || startRow == endRow))
    inside = false;
  }
  if(changed) {
   if(tree.RaiseSelectionChanged())
    tree.SendDummyCommand(true);
  }
 }   
});
function aspxTLPager(name, arg) {
 var treeList = aspxGetControlCollection().Get(name);
 if(treeList != null)
  treeList.SendPagerCommand(arg);
}
function aspxTLSelectAll(name, check) {
 var treeList = aspxGetControlCollection().Get(name);
 if(treeList != null)
  treeList.OnSelectingAll(check.checked);
}
function aspxTLClick(name, e) {
 var treeList = aspxGetControlCollection().Get(name);
 if(treeList)
  treeList.OnDataTableClick(e);
}
function aspxTLDblClick(name, e) {
 var treeList = aspxGetControlCollection().Get(name);
 if(treeList)
  treeList.OnDataTableDblClick(e);
}
function aspxTLHeaderDown(name, element, e) {
 var treeList = aspxGetControlCollection().Get(name);
 if(treeList)
  treeList.OnHeaderMouseDown(element, e);
}
function aspxTLShowLoadingPanel(name) {
 var treeList = aspxGetControlCollection().Get(name);
 if(treeList)
  treeList.ShowLoadingPanelCore();
}
function aspxTLCWCloseUp(name) {
 var treeList = aspxGetControlCollection().Get(name);
 if(treeList)
  treeList.RaiseCustomizationWindowCloseUp();
}
function aspxTLMouseDown(name, e) {
 var treeList = aspxGetControlCollection().Get(name);
 if(treeList)
  treeList.OnDataTableMouseDown(e);
}
function aspxTLSelecting(name, check) {
 var treeList = aspxGetControlCollection().Get(name);
 if(treeList)
  treeList.OnNodeSelecting(check); 
}
function aspxTLStartEdit(name, key) {
 var treeList = aspxGetControlCollection().Get(name);
 if(treeList)
  treeList.StartEdit(key); 
}
function aspxTLStartEditNewNode(name, parentKey) {
 var treeList = aspxGetControlCollection().Get(name);
 if(treeList)
  treeList.StartEditNewNode(parentKey); 
}
function aspxTLDeleteNode(name, key) {
 var treeList = aspxGetControlCollection().Get(name);
 if(treeList)
  treeList.OnNodeDeleting(key); 
}
function aspxTLUpdateEdit(name) {
 var treeList = aspxGetControlCollection().Get(name);
 if(treeList)
  treeList.UpdateEdit(); 
}
function aspxTLCancelEdit(name) {
 var treeList = aspxGetControlCollection().Get(name);
 if(treeList)
  treeList.CancelEdit(); 
}
function aspxTLCustomButton(name, nodeKey, index, id) {
 var treeList = aspxGetControlCollection().Get(name);
 if(treeList)
  treeList.RaiseCustomButtonClick(nodeKey, index, id);
}
function aspxTLMenu(name, objectType, objectKey, htmlEvent) {
 var treeList = aspxGetControlCollection().Get(name);
 if(treeList)
  return treeList.OnContextMenu(objectType, objectKey, htmlEvent);
 return true;
}
function aspxTLSort(name, columnIndex) {
 var treeList = aspxGetControlCollection().Get(name);
 if(treeList)
  treeList.SortBy(columnIndex);
}
function aspxTLExpand(name, nodeKey) {
 var treeList = aspxGetControlCollection().Get(name);
 if(treeList) {
  if(treeList.enableFocusedNode && treeList.focusOnExpandCollapse)
   treeList.OnFocusingNode(nodeKey, null);
  treeList.ExpandNode(nodeKey);
 }
}
function aspxTLCollapse(name, nodeKey) {
 var treeList = aspxGetControlCollection().Get(name);
 if(treeList) {
  if(treeList.enableFocusedNode && treeList.focusOnExpandCollapse)
   treeList.OnFocusingNode(nodeKey, null); 
  treeList.CollapseNode(nodeKey);
 }
}
ASPxClientTreeListColumn = _aspxCreateClass(null, { 
 constructor: function(index, name, fieldName) {
  this.index = index;
  this.name = name;
  this.fieldName = fieldName;
  this.canSort = false; 
  this.showInCw = true;   
 },
 __dxColumnObject: true
});
ASPxClientTreeListCustomDataCallbackEventArgs = _aspxCreateClass(ASPxClientEventArgs, {
 constructor: function(arg, result) {
  this.constructor.prototype.constructor.call(this);
  this.arg = arg;
  this.result = result;
 }
});
ASPxClientTreeListNodeEventArgs = _aspxCreateClass(ASPxClientEventArgs, {
 constructor: function(nodeKey, htmlEvent) {
  this.constructor.prototype.constructor.call(this);
  this.nodeKey = nodeKey;
  this.htmlEvent = htmlEvent;
  this.cancel = false;  
 }
});
ASPxClientTreeListContextMenuEventArgs = _aspxCreateClass(ASPxClientEventArgs, {
 constructor: function(objectType, objectKey, htmlEvent) {
  this.constructor.prototype.constructor.call(this);
  this.objectType = objectType;
  this.objectKey = objectKey;
  this.htmlEvent = htmlEvent;
  this.cancel = false;   
 }
});
ASPxClientTreeListStartDragNodeEventArgs = _aspxCreateClass(ASPxClientTreeListNodeEventArgs, {
 constructor: function(nodeKey, htmlEvent, targets) {
  this.constructor.prototype.constructor.call(this, nodeKey, htmlEvent);
  this.targets = targets;  
 }
});
ASPxClientTreeListEndDragNodeEventArgs = _aspxCreateClass(ASPxClientTreeListNodeEventArgs, {
 constructor: function(nodeKey, htmlEvent, targetElement) {
  this.constructor.prototype.constructor.call(this, nodeKey, htmlEvent);
  this.targetElement = targetElement;
 } 
});
ASPxClientTreeListCustomButtonEventArgs = _aspxCreateClass(ASPxClientEventArgs, {
 constructor: function(nodeKey, buttonIndex, buttonID) {
  this.constructor.prototype.constructor.call(this);
  this.nodeKey = nodeKey;
  this.buttonIndex = buttonIndex;
  this.buttonID = buttonID;
 } 
});

