<?xml version="1.0"?>
<!--
Based on Mozilla code; MPL licence
-->
<bindings
  xmlns="http://www.mozilla.org/xbl"
  xmlns:html="http://www.w3.org/1999/xhtml"  
  xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  <binding id="richtree" extends="chrome://global/content/bindings/tree.xml#tree-base">
    <resources>
      <stylesheet src="richtree.css"/>
    </resources>
    <content hidevscroll="true" hidehscroll="true" orient="vertical">
      <children includes="treecols"/>
      <xul:vbox collapsed="true" style="display:none;"> <children includes="richtreecells"/> </xul:vbox>
      <xul:hbox flex="1" >    
        <xul:scrollbox flex="1" anonid="treecontent">
          <xul:stack anonid="treebox" class="richtree-stack" flex="1" >
            <children/>
            <xul:textbox anonid="input" collapsed="true"/>
          </xul:stack>
        </xul:scrollbox>
        <xul:scrollbar anonid="vscroll" orient="vertical" increment="16"/>
      </xul:hbox>
      <xul:hbox collapsed="true">
        <xul:scrollbar orient="horizontal" flex="1" increment="16"/>
        <xul:scrollcorner/>
      </xul:hbox>
    </content>

    <implementation implements="nsIDOMXULMultiSelectControlElement, nsIAccessibleProvider">
      <!-- ///////////////// nsIDOMXULTreeElement ///////////////// -->

      <property name="columns"
                onget="return this.treeBoxObject.columns;"/>

      <property name="view"
                onget="return this.treeBoxObject.view;"
                onset="return this.treeBoxObject.view = val;"/>

      <property name="body"
                onget="return this.treeBoxObject.treeBody;"/>

      <property name="editable"
                onget="return this.hasAttribute('editable');"
                onset="if (val) this.setAttribute('editable', 'true');
                       else this.removeAttribute('editable'); return val;"/>

      <!-- ///////////////// nsIDOMXULSelectControlElement ///////////////// -->

      <!-- ///////////////// nsIDOMXULMultiSelectControlElement ///////////////// -->

      <property name="selType"
                onget="return this.getAttribute('seltype')"
                onset="this.setAttribute('seltype', val); return val;"/>

      <property name="currentIndex"
                onget="return this.view.selection.currentIndex;"
                onset="return this.view.selection.currentIndex = val;"/>

      <!-- ///////////////// nsIAccessibleProvider ///////////////// -->

      <property name="accessibleType" readonly="true">
        <getter>
          <![CDATA[
            return Components.interfaces.nsIAccessibleProvider.XULTree;
          ]]>
        </getter>
      </property>

      <!-- IMPLEMENTATION -->
      <property name="treeBoxObject" readonly="true">
        <getter><![CDATA[
          if (!this._treeBoxObject) {
            this._treeBoxObject = new TreeBoxObject(this, 7, this);
          }
          return this._treeBoxObject;
          ]]>
        </getter>
      </property>
       
      
      <property name="contentView"
                onget="return this.view;"
                readonly="true"/>
      <property name="builderView"
                onget="return this.view;"
                readonly="true"/>
      <field name="pageUpOrDownMovesSelection">true</field>
      <property name="enableColumnDrag"
                onget="return this.hasAttribute('enableColumnDrag');"
                onset="if (val) this.setAttribute('enableColumnDrag', 'true');
                       else this.removeAttribute('enableColumnDrag'); return val;"/>

      <field name="mInputField">null</field>
      
      <property name="inputField" readonly="true">
        <getter><![CDATA[
          if (!this.mInputField)
            this.mInputField = document.getAnonymousElementByAttribute(this, "anonid", "input");
          return this.mInputField;
        ]]></getter>
      </property>

      <property name="disableKeyNavigation"
                onget="return this.hasAttribute('disableKeyNavigation');"
                onset="if (val) this.setAttribute('disableKeyNavigation', 'true');
                       else this.removeAttribute('disableKeyNavigation'); return val;"/>

      <field name="_editingRow">-1</field>
      <field name="_editingColumn">null</field>

      <property name="editingRow" readonly="true"
                onget="return this._editingRow;"/>
      <property name="editingColumn" readonly="true"
                onget="return this._editingColumn;"/>

      <property name="_selectDelay" 
                onset="this.setAttribute('_selectDelay', val);"
                onget="return this.getAttribute('_selectDelay') || 50;"/>
      <field name="_columnsDirty">true</field>
      <field name="_lastKeyTime">0</field>
      <field name="_incrementalString">""</field>

      <method name="_ensureColumnOrder">
        <body><![CDATA[
          if (this._columnsDirty) {
            // update the ordinal position of each column to assure that it is
            // an odd number and 2 positions above its next sibling
            var cols = [];
            var i;
            for (var col = this.columns.getFirstColumn(); col; col = col.getNext())
              cols.push(col.element);
            for (i = 0; i < cols.length; ++i)
              cols[i].setAttribute("ordinal", (i*2)+1);

            // update the ordinal positions of splitters to even numbers, so that 
            // they are in between columns
            var splitters = this.getElementsByTagName("splitter");
            for (i = 0; i < splitters.length; ++i)
              splitters[i].setAttribute("ordinal", (i+1)*2);
            
            this._columnsDirty = false;
          }
        ]]></body>
      </method>

      <method name="_reorderColumn">
        <parameter name="aColMove"/>
        <parameter name="aColBefore"/>
        <parameter name="aBefore"/>
        <body><![CDATA[
          this._ensureColumnOrder();
          
          var i;
          var cols = [];
          var col = this.columns.getColumnFor(aColBefore);
          if (aColBefore.ordinal < aColMove.ordinal) {
            if (aBefore)
              cols.push(aColBefore);
            for (col = col.getNext(); col.element != aColMove;
                 col = col.getNext())
              cols.push(col.element);

            aColMove.ordinal = cols[0].ordinal;
            for (i = 0; i < cols.length; ++i)
              cols[i].ordinal += 2;
          } else {
            if (!aBefore)
              cols.push(aColBefore);
            for (col = col.getPrevious(); col.element != aColMove;
                 col = col.getPrevious())
              cols.push(col.element);

            aColMove.ordinal = cols[0].ordinal;
            for (i = 0; i < cols.length; ++i)
              cols[i].ordinal -= 2;
          }
        ]]></body>
      </method>
      
      <method name="_getColumnAtX">
        <parameter name="aX"/>
        <parameter name="aThresh"/>
        <parameter name="aPos"/>
        <body><![CDATA[
          if (aPos) aPos.value = "before";

          var col = this.columns.getFirstColumn();
          var lastCol = null;
          var currentX = this.boxObject.x;
          while (col) {
            var cw = col.element.boxObject.width;
            if (cw > 0) {
              currentX += cw;
              if (currentX - (cw * aThresh) > aX)
                return col.element;
            }
            lastCol = col;
            col = col.getNext();
          }

          if (aPos) aPos.value = "after";
          return lastCol.element;
        ]]></body>
      </method>

      <method name="changeOpenState">
        <parameter name="row"/>
        <!-- Optional parameter openState == true or false to set. 
             No openState param == toggle -->
        <parameter name="openState"/>
        <body><![CDATA[
          if (row < 0 || !this.view.isContainer(row)) {
            return false;
          }
          if (this.view.isContainerOpen(row) != openState) {
            this.view.toggleOpenState(row);
            if (row == this.currentIndex) {
              // Only fire event when current row is expanded or collapsed
              // because that's all the assistive technology really cares about.
              var event = document.createEvent('Events');
              event.initEvent('OpenStateChange', true, true);
              this.dispatchEvent(event);
            }
            return true;
          }
          return false;
        ]]></body>
      </method>

      <property name="_cellSelType">
        <getter>
          <![CDATA[
            var seltype = this.selType;
            if (seltype == "cell" || seltype == "text")
              return seltype;
            return null;
          ]]>
        </getter>
      </property>

      <method name="_getNextColumn">
        <parameter name="row"/>
        <parameter name="left"/>
        <body><![CDATA[
          var col = this.view.selection.currentColumn;
          if (col) {
            col = left ? col.getPrevious() : col.getNext();
          }
          else {
            col = this.columns.getKeyColumn();
          }
          while (col && (col.width == 0 || !col.selectable ||
                 !this.view.isSelectable(row, col)))
            col = left ? col.getPrevious() : col.getNext();
          return col;
        ]]></body>
      </method>

      <method name="keyNavigate">
        <parameter name="event"/>
        <body><![CDATA[
          var key = String.fromCharCode(event.charCode).toLowerCase();
          if (event.timeStamp - this._lastKeyTime > 1000)
            this._incrementalString = key;
          else
            this._incrementalString += key;
          this._lastKeyTime = event.timeStamp;

          var length = this._incrementalString.length;
          var incrementalString = this._incrementalString;
          var charIndex = 1;
          while (charIndex < length && incrementalString[charIndex] == incrementalString[charIndex - 1])
            charIndex++;
          // If all letters in incremental string are same, just try to match the first one
          if (charIndex == length) {
            length = 1;
            incrementalString = incrementalString.substring(0, length);
          }

          var keyCol = this.columns.getKeyColumn();
          var rowCount = this.view.rowCount;
          var start = 1;

          var c = this.currentIndex;
          if (length > 1) {
            start = 0;
            if (c < 0)
              c = 0;
          }

          for (var i = 0; i < rowCount; i++) {
            var l = (i + start + c) % rowCount;
            var cellText = this.view.getCellText(l, keyCol);
            cellText = cellText.substring(0, length).toLowerCase();
            if (cellText == incrementalString)
              return l;
          }
          return -1;
        ]]></body>
      </method>

      <method name="startEditing">
        <parameter name="row"/>
        <parameter name="column"/>
        <body>
          <![CDATA[
            if (row < 0 || row >= this.view.rowCount || !column)
              return;
            if (column.type != Components.interfaces.nsITreeColumn.TYPE_TEXT ||
                column.cycler || !this.view.isEditable(row, column))
              return;

            if (this._editingColumn)
              this.stopEditing();

            var input = this.inputField;
            input.hidden = false;

            var box = this.treeBoxObject;
            box.ensureCellIsVisible(row, column);

            var outx = {}, outy = {}, outwidth = {}, outheight = {};
            var coords = box.getCoordsForCellItem(row, column, "text",
                                                  outx, outy, outwidth, outheight);

            var style = window.getComputedStyle(input, "");
            var topadj = parseInt(style.borderTopWidth) + parseInt(style.paddingTop);
            input.top = outy.value - topadj;

            var left = outx.value;
            input.left = left;
            input.height = outheight.value + topadj +
                           parseInt(style.borderBottomWidth) +
                           parseInt(style.paddingBottom);

            coords = box.getCoordsForCellItem(row, column, "cell",
                                              outx, outy, outwidth, outheight);
            input.width = outwidth.value - (left - outx.value);

            input.value = this.view.getCellText(row, column);
            var selectText = function selectText() {
              input.select();
              input.inputField.focus();
            }
            setTimeout(selectText, 0);

            this._editingRow = row;
            this._editingColumn = column;

            this.setAttribute("editing", "true");
          ]]>
        </body>
      </method>

      <method name="stopEditing">
        <parameter name="accept"/>
        <body>
          <![CDATA[
            if (!this._editingColumn)
              return;

            var input = this.inputField;
            if (accept) {
              var value = input.value;
              this.view.setCellText(this._editingRow, this._editingColumn, value);
            }
            this._editingRow = -1;
            this._editingColumn = null;

            input.hidden = true;
            input.value = "";
            this.removeAttribute("editing");
          ]]>
        </body>
      </method>

      <method name="_moveByOffset">
        <parameter name="offset"/>
        <parameter name="edge"/>
        <parameter name="event"/>
        <body>
          <![CDATA[
            if (this._editingColumn || this.view.rowCount == 0)
              return;

            if (this._isAccelPressed(event) && this.view.selection.single) {
              this.treeBoxObject.scrollByLines(offset);
              return;
            }
   
            var c = this.currentIndex + offset;
            if (offset > 0 ? c > edge : c < edge) {
              if (this.view.selection.isSelected(edge) && this.view.selection.count <= 1)
                return;
              c = edge;
            }
   
            var cellSelType = this._cellSelType;
            if (cellSelType) {
              var column = this.view.selection.currentColumn;
              if (!column)
                return;
   
              while ((offset > 0 ? c <= edge : c >= edge) && !this.view.isSelectable(c, column))
                c += offset;
              if (offset > 0 ? c > edge : c < edge)
                return;
            }
   
            if (!this._isAccelPressed(event))
              this.view.selection.timedSelect(c, this._selectDelay);
            else // Ctrl+Up/Down moves the anchor without selecting
              this.currentIndex = c;
            this.treeBoxObject.ensureRowIsVisible(c);
          ]]>
        </body>
      </method>

      <method name="_moveByOffsetShift">
        <parameter name="offset"/>
        <parameter name="edge"/>
        <parameter name="event"/>
        <body>
          <![CDATA[
            if (this._editingColumn || this.view.rowCount == 0)
              return;

            if (this.view.selection.single) {
              this.treeBoxObject.scrollByLines(offset);
              return;
            }

            if (this.view.rowCount == 1 && !this.view.selection.isSelected(0)) {
              this.view.selection.timedSelect(0, this._selectDelay);
              return;
            }
      
            var c = this.currentIndex;
            if (c == -1)
                c = 0;

            if (c == edge) {
              if (this.view.selection.isSelected(c))
                return;
            }
      
            // Extend the selection from the existing pivot, if any
            this.view.selection.rangedSelect(-1, c + offset,
                                             this._isAccelPressed(event));
            this.treeBoxObject.ensureRowIsVisible(c + offset);

          ]]>
        </body>
      </method>

      <method name="_moveByPage">
        <parameter name="offset"/>
        <parameter name="edge"/>
        <parameter name="event"/>
        <body>
          <![CDATA[
            if (this._editingColumn || this.view.rowCount == 0)
              return;

            if (this.pageUpOrDownMovesSelection == this._isAccelPressed(event)) {
               this.treeBoxObject.scrollByPages(offset);
               return;
            }

            if (this.view.rowCount == 1 && !this.view.selection.isSelected(0)) {
              this.view.selection.timedSelect(0, this._selectDelay);
              return;
            }

            var c = this.currentIndex;
            if (c == -1)
              return;

            if (c == edge && this.view.selection.isSelected(c)) {
              this.treeBoxObject.ensureRowIsVisible(c);
              return;
            }
            var i = this.treeBoxObject.getFirstVisibleRow();
            var p = this.treeBoxObject.getPageLength();

            if (offset > 0) {
              i += p - 1;
              if (c >= i) {
                 i = c + p;
                 this.treeBoxObject.ensureRowIsVisible(i > edge ? edge : i);
              }
              i = i > edge ? edge : i;

            } else {
              if (c <= i) {
                 i = c <= p ? 0 : c - p;
                 this.treeBoxObject.ensureRowIsVisible(i);
              }
            }
            this.view.selection.timedSelect(i, this._selectDelay);
          ]]>
        </body>
      </method>

      <method name="_moveByPageShift">
        <parameter name="offset"/>
        <parameter name="edge"/>
        <parameter name="event"/>
        <body>
          <![CDATA[
            if (this._editingColumn || this.view.rowCount == 0)
              return;

            if (this.view.rowCount == 1 && !this.view.selection.isSelected(0) &&
                !(this.pageUpOrDownMovesSelection == this._isAccelPressed(event))) {
              this.view.selection.timedSelect(0, this._selectDelay);
              return;
            }

            if (this.view.selection.single)
              return;

            var c = this.currentIndex;
            if (c == -1)
              return;
            if (c == edge && this.view.selection.isSelected(c)) {
              this.treeBoxObject.ensureRowIsVisible(edge);
              return;
            }
            var i = this.treeBoxObject.getFirstVisibleRow();
            var p = this.treeBoxObject.getPageLength();

            if (offset > 0) {
              i += p - 1;
              if (c >= i) {
                 i = c + p;
                 this.treeBoxObject.ensureRowIsVisible(i > edge ? edge : i);
              }
              // Extend the selection from the existing pivot, if any
              this.view.selection.rangedSelect(-1, i > edge ? edge : i, this._isAccelPressed(event));

            } else {

              if (c <= i) {
                 i = c <= p ? 0 : c - p;
                 this.treeBoxObject.ensureRowIsVisible(i);
              }
              // Extend the selection from the existing pivot, if any
              this.view.selection.rangedSelect(-1, i, this._isAccelPressed(event));
            }

          ]]>
        </body>
      </method>

      <method name="_moveToEdge">
        <parameter name="edge"/>
        <parameter name="event"/>
        <body>
          <![CDATA[
            if (this._editingColumn || this.view.rowCount == 0)
              return;

            if (this.view.selection.isSelected(edge) && this.view.selection.count == 1) {
              this.currentIndex = edge;
              return;
            }

            // Normal behaviour is to select the first/last row
            if (!this._isAccelPressed(event))
              this.view.selection.timedSelect(edge, this._selectDelay);

            // In a multiselect tree Ctrl+Home/End moves the anchor
            else if (!this.view.selection.single)
              this.currentIndex = edge;

            this.treeBoxObject.ensureRowIsVisible(edge);
          ]]>
        </body>
      </method>

      <method name="_moveToEdgeShift">
        <parameter name="edge"/>
        <parameter name="event"/>
        <body>
          <![CDATA[
            if (this._editingColumn || this.view.rowCount == 0)
              return;

            if (this.view.rowCount == 1 && !this.view.selection.isSelected(0)) {
              this.view.selection.timedSelect(0, this._selectDelay);
              return;
            }

            if (this.view.selection.single ||
                (this.view.selection.isSelected(edge)) && this.view.selection.isSelected(this.currentIndex))
              return;

            // Extend the selection from the existing pivot, if any.
            // -1 doesn't work here, so using currentIndex instead
            this.view.selection.rangedSelect(this.currentIndex, edge, this._isAccelPressed(event));

            this.treeBoxObject.ensureRowIsVisible(edge);
          ]]>
        </body>
      </method>
    </implementation>
    
    <handlers>
      <handler event="DOMMouseScroll" phase="capturing">
        <![CDATA[
          if (this._editingColumn)
            return;

          var rows = event.detail;
          if (rows == NSUIEvent.SCROLL_PAGE_UP)
            this.treeBoxObject.scrollByPages(-1);
          else if (rows == NSUIEvent.SCROLL_PAGE_DOWN)
            this.treeBoxObject.scrollByPages(1);
          else
            this.treeBoxObject.scrollByLines(rows);
        ]]>
      </handler>
      <handler event="select" phase="target"
               action="if (event.originalTarget == this) this.stopEditing(true);"/>
      <handler event="focus">
        <![CDATA[
          this.treeBoxObject.focused = true;
          if (this.currentIndex == -1 && this.view.rowCount > 0) {
            this.currentIndex = this.treeBoxObject.getFirstVisibleRow();
          }
          if (this._cellSelType && !this.view.selection.currentColumn) {
            var col = this._getNextColumn(this.currentIndex, false);
            this.view.selection.currentColumn = col;
          }
        ]]>
      </handler>
      <handler event="blur" action="this.treeBoxObject.focused = false;"/>
      <handler event="blur" phase="capturing"
               action="if (event.originalTarget == this.inputField.inputField) this.stopEditing(true);"/>
      <handler event="keypress" keycode="VK_ENTER">
        <![CDATA[
          if (this._editingColumn) {
            this.stopEditing(true);
            this.focus();
            event.stopPropagation();
          }
          else {
            this.changeOpenState(this.currentIndex);
          }
        ]]>
      </handler>
      <handler event="keypress" keycode="VK_RETURN">
        <![CDATA[
          if (this._editingColumn) {
            this.stopEditing(true);
            this.focus();
            event.stopPropagation();
          }
          else {
            this.changeOpenState(this.currentIndex);
          }
        ]]>
      </handler>
      <handler event="keypress" keycode="VK_ESCAPE">
        <![CDATA[
          if (this._editingColumn) {
            this.stopEditing(false);
            this.focus();
            event.stopPropagation();
          }
        ]]>
      </handler>
      <handler event="keypress" keycode="VK_LEFT">
        <![CDATA[
         if (this._editingColumn)
           return;

         var row = this.currentIndex;
         if (row < 0)
           return;

         var cellSelType = this._cellSelType;
         var checkContainers = true;

         var currentColumn;
         if (cellSelType) {
           currentColumn = this.view.selection.currentColumn;
           if (currentColumn && !currentColumn.primary)
             checkContainers = false;
         }

         if (checkContainers) {
           if (this.changeOpenState(this.currentIndex, false))
             return;
           else {
             var parentIndex = this.view.getParentIndex(this.currentIndex);
             if (parentIndex >= 0) {
               if (cellSelType && !this.view.isSelectable(parentIndex, currentColumn)) {
                 return;
               }
               this.view.selection.select(parentIndex);
               this.treeBoxObject.ensureRowIsVisible(parentIndex);
               return;
             }
           }
         }

         if (cellSelType) {
           var col = this._getNextColumn(row, true);
           if (col) {
             this.view.selection.currentColumn = col;
             this.treeBoxObject.ensureCellIsVisible(row, col);
           }
         }
        ]]>
      </handler>
      <handler event="keypress" keycode="VK_RIGHT">
        <![CDATA[
         if (this._editingColumn)
           return;

          var row = this.currentIndex;
          if (row < 0)
            return;

          var cellSelType = this._cellSelType;
          var checkContainers = true;

          var currentColumn;
          if (cellSelType) {
            currentColumn = this.view.selection.currentColumn;
            if (currentColumn && !currentColumn.primary)
              checkContainers = false;
          }

          if (checkContainers) {
            if (this.changeOpenState(row, true))
              return;
            else {
              var c = row + 1;
              var view = this.view;
              if (c < view.rowCount &&
                  view.getParentIndex(c) == row) {
                // If already opened, select the first child.
                // The getParentIndex test above ensures that the children
                // are already populated and ready.
                if (cellSelType && !this.view.isSelectable(c , currentColumn)) {
                  var col = this._getNextColumn(c, false);
                  if (col) {
                    this.view.selection.currentColumn = col;
                  }
                }
                this.view.selection.timedSelect(c, this._selectDelay);
                this.treeBoxObject.ensureRowIsVisible(c);
                return;
              }
            }
          }

          if (cellSelType) {
            var col = this._getNextColumn(row, false);
            if (col) {
              this.view.selection.currentColumn = col;
              this.treeBoxObject.ensureCellIsVisible(row, col);
            }
          }
        ]]>
      </handler>
      <handler event="keypress" keycode="VK_UP"
               modifiers="accel any" action="_moveByOffset(-1, 0, event);"/>
      <handler event="keypress" keycode="VK_DOWN"
               modifiers="accel any" action="_moveByOffset(1, this.view.rowCount - 1, event);"/>
      <handler event="keypress" keycode="VK_UP"
               modifiers="accel any, shift" action="_moveByOffsetShift(-1, 0, event);"/>
      <handler event="keypress" keycode="VK_DOWN"
               modifiers="accel any, shift" action="_moveByOffsetShift(1, this.view.rowCount - 1, event);"/>
      <handler event="keypress" keycode="VK_PAGE_UP"
               modifiers="accel any" action="_moveByPage(-1, 0, event);"/>
      <handler event="keypress" keycode="VK_PAGE_DOWN"
               modifiers="accel any" action="_moveByPage(1, this.view.rowCount - 1, event);"/>
      <handler event="keypress" keycode="VK_PAGE_UP"
               modifiers="accel any, shift" action="_moveByPageShift(-1, 0, event);"/>
      <handler event="keypress" keycode="VK_PAGE_DOWN"
               modifiers="accel any, shift" action="_moveByPageShift(1, this.view.rowCount - 1, event);"/>
      <handler event="keypress" keycode="VK_HOME"
               modifiers="accel any" action="_moveToEdge(0, event);"/>
      <handler event="keypress" keycode="VK_END"
               modifiers="accel any" action="_moveToEdge(this.view.rowCount - 1, event);"/>
      <handler event="keypress" keycode="VK_HOME"
               modifiers="accel any, shift" action="_moveToEdgeShift(0, event);"/>
      <handler event="keypress" keycode="VK_END"
               modifiers="accel any, shift" action="_moveToEdgeShift(this.view.rowCount - 1, event);"/>
      <handler event="keypress">
        <![CDATA[
         if (this._editingColumn)
           return;

         if (event.charCode == ' '.charCodeAt(0)) {
           var c = this.currentIndex;
           if (!this.view.selection.isSelected(c) ||
               (!this.view.selection.single && this._isAccelPressed(event))) {
             this.view.selection.toggleSelect(c);
           }
         }
         else if (!this.disableKeyNavigation && event.charCode > 0 &&
                  !event.altKey && !this._isAccelPressed(event) &&
                  !event.metaKey) {
           var l = this.keyNavigate(event);
           if (l >= 0) {
             this.view.selection.timedSelect(l, this._selectDelay);
             this.treeBoxObject.ensureRowIsVisible(l);
           }
          }
         ]]>
      </handler>
    </handlers>    
  </binding>
  
  
</bindings>