code: function filter(tree, query, options) {
      var compiledQuery = _.isFunction(query) ? query : _.matches(query);
  
      var settings = _.defaults(options, {
        childNode: ['children']
      });
  
      settings.childNode = _.castArray(settings.childNode);
  
      var seekDown = function seekDown(tree) {
        return tree.filter(function (branch, index) {
          return compiledQuery(branch, index);
        }).map(function (branch) {
          settings.childNode.some(function (key) {
            if (_.has(branch, key)) {
              if (_.isArray(branch[key])) {
                branch[key] = seekDown(branch[key]);
              } else {
                delete branch[key];
              }
            }
          });
          return branch;
        });
      };
  
      if (_.isArray(tree)) {
        return seekDown(tree, []) || [];
      } else {
        return seekDown([tree], [])[0] || {};
      }
    }
docs: Return a copy of the tree with all non-matching nodes removed
  
  NOTE: This function seeks downwards, so any parent that does not match will also omit its child nodes
  
  @param {Object|array} tree The tree structure to search (assumed to be a collection)
  @param {Object|function} query A valid lodash query to run (anything valid via _.find()) or a matching function to be run on each node
  @param {Object} [options] Options object
  @param {array|string} [options.childNode="children"] Node or nodes to examine to discover the child elements