docs: function(node, addSelected, dragElements) {
        if (!addSelected)
        {
          var parents = node.parents();
  
          // do not process descendants for this node,
          // because those will be handled for the topmost selected parent
          for (var i=0; i < parents.size(); i++)
          {
              if (parents[i]._private.selected)
              {
                return;
              }
          }
        }
  
        var innerNodes = node.descendants();
  
        var hasNonAutoParent = function(ele){
          while( ele.parent().nonempty() && ele.parent().id() !== node.id() ){
            parent = ele.parent()[0];
            var pstyle = parent._private.style;
  
            if( pstyle.width.value !== 'auto' || pstyle.height.value !== 'auto' ){
              return true;
            }
  
            ele = ele.parent();
          }
  
          return false;
        };
  
        // TODO do not drag hidden children & children of hidden children?
        for (var i=0; i < innerNodes.size(); i++)
        {
          // if addSelected is true, then add node in any case,
          // if not, then add only non-selected nodes
          if ( (addSelected || !innerNodes[i]._private.selected) )
          {
            innerNodes[i]._private.rscratch.inDragLayer = true;
            //innerNodes[i].trigger(new $$.Event(e, {type: 'grab'}));
            //innerNodes[i].trigger(event);
            dragElements.push(innerNodes[i]);
  
            for (var j=0; j < innerNodes[i]._private.edges.length; j++)
            {
              innerNodes[i]._private.edges[j]._private.rscratch.inDragLayer = true;
            }
          }
        }
      }