code: function traverseDepthFirst(rootNode, options) {
    options = extend({
      subnodesAccessor: function(node) { return node.subnodes; },
      userdataAccessor: function(node, userdata) { return userdata; },
      onNode: function(node, callback, userdata) { callback(); },
      onComplete: function(rootNode) {},
      userdata: null
    }, options);
  
    var stack = [];
    stack.push([rootNode, options.userdata]);
  
    (function next() {
      if (stack.length == 0) {
        options.onComplete(rootNode);
        return;
      }
  
      var top = stack.pop();
      var node = top[0];
      var data = top[1];
  
      options.onNode(node, function() {
        var subnodeData = options.userdataAccessor(node, data);
        var subnodes = options.subnodesAccessor(node);
        async.eachSeries(subnodes,
          function(subnode, nextNode) {
            stack.push([subnode, subnodeData]);
            async.setImmediate(nextNode);
          },
          function() {
            async.setImmediate(next);
          }
        );
      }, data);
    })();
  }
docs: Asynchronously traverses the tree depth first.