setValue = function(path, value) {
      var key = path.pop();
      var node = self.value(obj, path);
      if (!node) {
        setValue(path.concat(), typeof key === 'string' ? {} : []);
        node = self.value(obj, path);
      }
      node[key] = value;
    }
/) {
  switch($avoiding_name_collisions) {
  case 0:return 4
  break;
  case 1:return 14
  break;
  case 2:return 12
  break;
  case 3:return 15
  break;
  case 4:return 16
  break;
  case 5:return 22
  break;
  case 6:return 24
  break;
  case 7:return 28
  break;
  case 8:return 30
  break;
  case 9:return 18
  break;
  case 10:yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2); return 32;
  break;
  case 11:yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2); return 33;
  break;
  case 12:return 17
  break;
  case 13:return 31
  break;
  }
  },
  rules: [/^(?:\$)/,/^(?:\.\.)/,/^(?:\.)/,/^(?:\*)/,/^(?:[a-zA-Z_]+[a-zA-Z0-9_]*)/,/^(?:\[)/,/^(?:\])/,/^(?:,)/,/^(?:((-?(?:0|[1-9][0-9]*)))?\:((-?(?:0|[1-9][0-9]*)))?(\:((-?(?:0|[1-9][0-9]*)))?)?)/,/^(?:(-?(?:0|[1-9][0-9]*)))/,/^(?:"(?:\\["bfnrt/\\]|\\u[a-fA-F0-9]{4}|[^"\\])*")/,/^(?:'(?:\\['bfnrt/\\]|\\u[a-fA-F0-9]{4}|[^'\\])*')/,/^(?:\(.+?\)(?=\]))/,/^(?:\?\(.+?\)(?=\]))/],
  conditions: {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13],"inclusive":true}}
  };
  return lexer;
  })();
  parser.lexer = lexer;
  function Parser () {
    this.yy = {};
  }
  Parser.prototype = parser;parser.Parser = Parser;
  return new Parser;
  })();


  if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
  exports.parser = parser;
  exports.Parser = parser.Parser;
  exports.parse = function () { return parser.parse.apply(parser, arguments); };
  exports.main = function commonjsMain(args) {
      if (!args[1]) {
          console.log('Usage: '+args[0]+' FILE');
          process.exit(1);
      }
      var source = require('fs').readFileSync(require('path').normalize(args[1]), "utf8");
      return exports.parser.parse(source);
  };
  if (typeof module !== 'undefined' && require.main === module) {
    exports.main(process.argv.slice(1));
  }
  }

  }).call(this,require('_process'));
  },{"_process":12,"fs":8,"path":11}],2:[function(require,module,exports){
  module.exports = {
    identifier: "[a-zA-Z_]+[a-zA-Z0-9_]*",
    integer: "-?(?:0|[1-9][0-9]*)",
    qq_string: "\"(?:\\\\[\"bfnrt/\\\\]|\\\\u[a-fA-F0-9]{4}|[^\"\\\\])*\"",
    q_string: "'(?:\\\\[\'bfnrt/\\\\]|\\\\u[a-fA-F0-9]{4}|[^\'\\\\])*'"
  };

  },{}],3:[function(require,module,exports){
  var dict = require('./dict');
  var fs = require('fs');
  var grammar = {

      lex: {

          macros: {
              esc: "\\\\",
              int: dict.integer
          },

          rules: [
              ["\\$", "return 'DOLLAR'"],
              ["\\.\\.", "return 'DOT_DOT'"],
              ["\\.", "return 'DOT'"],
              ["\\*", "return 'STAR'"],
              [dict.identifier, "return 'IDENTIFIER'"],
              ["\\[", "return '['"],
              ["\\]", "return ']'"],
              [",", "return ','"],
              ["({int})?\\:({int})?(\\:({int})?)?", "return 'ARRAY_SLICE'"],
              ["{int}", "return 'INTEGER'"],
              [dict.qq_string, "yytext = yytext.substr(1,yyleng-2); return 'QQ_STRING';"],
              [dict.q_string, "yytext = yytext.substr(1,yyleng-2); return 'Q_STRING';"],
              ["\\(.+?\\)(?=\\])", "return 'SCRIPT_EXPRESSION'"],
              ["\\?\\(.+?\\)(?=\\])", "return 'FILTER_EXPRESSION'"]
          ]
      },

      start: "JSON_PATH",

      bnf: {

          JSON_PATH: [
                  [ 'DOLLAR',                 'yy.ast.set({ expression: { type: "root", value: $1 } }); yy.ast.unshift(); return yy.ast.yield()' ],
                  [ 'DOLLAR PATH_COMPONENTS', 'yy.ast.set({ expression: { type: "root", value: $1 } }); yy.ast.unshift(); return yy.ast.yield()' ],
                  [ 'LEADING_CHILD_MEMBER_EXPRESSION',                 'yy.ast.unshift(); return yy.ast.yield()' ],
                  [ 'LEADING_CHILD_MEMBER_EXPRESSION PATH_COMPONENTS', 'yy.ast.set({ operation: "member", scope: "child", expression: { type: "identifier", value: $1 }}); yy.ast.unshift(); return yy.ast.yield()' ] ],

          PATH_COMPONENTS: [
                  [ 'PATH_COMPONENT',                 '' ],
                  [ 'PATH_COMPONENTS PATH_COMPONENT', '' ] ],

          PATH_COMPONENT: [
                  [ 'MEMBER_COMPONENT',    'yy.ast.set({ operation: "member" }); yy.ast.push()' ],
                  [ 'SUBSCRIPT_COMPONENT', 'yy.ast.set({ operation: "subscript" }); yy.ast.push() ' ] ],

          MEMBER_COMPONENT: [
                  [ 'CHILD_MEMBER_COMPONENT',      'yy.ast.set({ scope: "child" })' ],
                  [ 'DESCENDANT_MEMBER_COMPONENT', 'yy.ast.set({ scope: "descendant" })' ] ],

          CHILD_MEMBER_COMPONENT: [
                  [ 'DOT MEMBER_EXPRESSION', '' ] ],

          LEADING_CHILD_MEMBER_EXPRESSION: [
                  [ 'MEMBER_EXPRESSION', 'yy.ast.set({ scope: "child", operation: "member" })' ] ],

          DESCENDANT_MEMBER_COMPONENT: [
                  [ 'DOT_DOT MEMBER_EXPRESSION', '' ] ],

          MEMBER_EXPRESSION: [
                  [ 'STAR',              'yy.ast.set({ expression: { type: "wildcard", value: $1 } })' ],
                  [ 'IDENTIFIER',        'yy.ast.set({ expression: { type: "identifier", value: $1 } })' ],
                  [ 'SCRIPT_EXPRESSION', 'yy.ast.set({ expression: { type: "script_expression", value: $1 } })' ],
                  [ 'INTEGER',           'yy.ast.set({ expression: { type: "numeric_literal", value: parseInt($1) } })' ],
                  [ 'END',               '' ] ],

          SUBSCRIPT_COMPONENT: [
                  [ 'CHILD_SUBSCRIPT_COMPONENT',      'yy.ast.set({ scope: "child" })' ],
                  [ 'DESCENDANT_SUBSCRIPT_COMPONENT', 'yy.ast.set({ scope: "descendant" })' ] ],

          CHILD_SUBSCRIPT_COMPONENT: [
                  [ '[ SUBSCRIPT ]', '' ] ],

          DESCENDANT_SUBSCRIPT_COMPONENT: [
                  [ 'DOT_DOT [ SUBSCRIPT ]', '' ] ],

          SUBSCRIPT: [
                  [ 'SUBSCRIPT_EXPRESSION', '' ],
                  [ 'SUBSCRIPT_EXPRESSION_LIST', '$1.length > 1? yy.ast.set({ expression: { type: "union", value: $1 } }) : $$ = $1' ] ],

          SUBSCRIPT_EXPRESSION_LIST: [
                  [ 'SUBSCRIPT_EXPRESSION_LISTABLE', '$$ = [$1]'],
                  [ 'SUBSCRIPT_EXPRESSION_LIST , SUBSCRIPT_EXPRESSION_LISTABLE', '$$ = $1.concat($3)' ] ],

          SUBSCRIPT_EXPRESSION_LISTABLE: [
                  [ 'INTEGER',           '$$ = { expression: { type: "numeric_literal", value: parseInt($1) } }; yy.ast.set($$)' ],
                  [ 'STRING_LITERAL',    '$$ = { expression: { type: "string_literal", value: $1 } }; yy.ast.set($$)' ],
                  [ 'ARRAY_SLICE',       '$$ = { expression: { type: "slice", value: $1 } }; yy.ast.set($$)' ] ],

          SUBSCRIPT_EXPRESSION: [
                  [ 'STAR',              '$$ = { expression: { type: "wildcard", value: $1 } }; yy.ast.set($$)' ],
                  [ 'SCRIPT_EXPRESSION', '$$ = { expression: { type: "script_expression", value: $1 } }; yy.ast.set($$)' ],
                  [ 'FILTER_EXPRESSION', '$$ = { expression: { type: "filter_expression", value: $1 } }; yy.ast.set($$)' ] ],

          STRING_LITERAL: [
                  [ 'QQ_STRING', "$$ = $1" ],
                  [ 'Q_STRING',  "$$ = $1" ] ]
      }
  };
  if (fs.readFileSync) {
    grammar.moduleInclude = fs.readFileSync(require.resolve("../include/module.js"));
    grammar.actionInclude = fs.readFileSync(require.resolve("../include/action.js"));
  }

  module.exports = grammar;

  },{"./dict":2,"fs":8}],4:[function(require,module,exports){
  var aesprim = require('./aesprim');
  var slice = require('./slice');
  var _evaluate = require('static-eval');
  var _uniq = require('underscore').uniq;

  var Handlers = function() {
    return this.initialize.apply(this, arguments);
  };

  Handlers.prototype.initialize = function() {
    this.traverse = traverser(true);
    this.descend = traverser();
  };

  Handlers.prototype.keys = Object.keys;

  Handlers.prototype.resolve = function(component) {

    var key = [ component.operation, component.scope, component.expression.type ].join('-');
    var method = this._fns[key];

    if (!method) throw new Error("couldn't resolve key: " + key);
    return method.bind(this);
  };

  Handlers.prototype.register = function(key, handler) {

    if (!handler instanceof Function) {
      throw new Error("handler must be a function");
    }

    this._fns[key] = handler;
  };

  Handlers.prototype._fns = {

    'member-child-identifier': function(component, partial) {
      var key = component.expression.value;
      var value = partial.value;
      if (value instanceof Object && key in value) {
        return [ { value: value[key], path: partial.path.concat(key) } ]
      }
    },

    'member-descendant-identifier':
      _traverse(function(key, value, ref) { return key == ref }),

    'subscript-child-numeric_literal':
      _descend(function(key, value, ref) { return key === ref }),

    'member-child-numeric_literal':
      _descend(function(key, value, ref) { return String(key) === String(ref) }),

    'subscript-descendant-numeric_literal':
      _traverse(function(key, value, ref) { return key === ref }),

    'member-child-wildcard':
      _descend(function() { return true }),

    'member-descendant-wildcard':
      _traverse(function() { return true }),

    'subscript-descendant-wildcard':
      _traverse(function() { return true }),

    'subscript-child-wildcard':
      _descend(function() { return true }),

    'subscript-child-slice': function(component, partial) {
      if (is_array(partial.value)) {
        var args = component.expression.value.split(':').map(_parse_nullable_int);
        var values = partial.value.map(function(v, i) { return { value: v, path: partial.path.concat(i) } });
        return slice.apply(null, [values].concat(args));
      }
    },

    'subscript-child-union': function(component, partial) {
      var results = [];
      component.expression.value.forEach(function(component) {
        var _component = { operation: 'subscript', scope: 'child', expression: component.expression };
        var handler = this.resolve(_component);
        var _results = handler(_component, partial);
        if (_results) {
          results = results.concat(_results);
        }
      }, this);

      return unique(results);
    },

    'subscript-descendant-union': function(component, partial, count) {

      var jp = require('..');
      var self = this;

      var results = [];
      var nodes = jp.nodes(partial, '$..*').slice(1);

      nodes.forEach(function(node) {
        if (results.length >= count) return;
        component.expression.value.forEach(function(component) {
          var _component = { operation: 'subscript', scope: 'child', expression: component.expression };
          var handler = self.resolve(_component);
          var _results = handler(_component, node);
          results = results.concat(_results);
        });
      });

      return unique(results);
    },

    'subscript-child-filter_expression': function(component, partial, count) {

      // slice out the expression from ?(expression)
      var src = component.expression.value.slice(2, -1);
      var ast = aesprim.parse(src).body[0].expression;

      var passable = function(key, value) {
        return evaluate(ast, { '@': value });
      };

      return this.descend(partial, null, passable, count);

    },

    'subscript-descendant-filter_expression': function(component, partial, count) {

      // slice out the expression from ?(expression)
      var src = component.expression.value.slice(2, -1);
      var ast = aesprim.parse(src).body[0].expression;

      var passable = function(key, value) {
        return evaluate(ast, { '@': value });
      };

      return this.traverse(partial, null, passable, count);
    },

    'subscript-child-script_expression': function(component, partial) {
      var exp = component.expression.value.slice(1, -1);
      return eval_recurse(partial, exp, '$[{{value}}]');
    },

    'member-child-script_expression': function(component, partial) {
      var exp = component.expression.value.slice(1, -1);
      return eval_recurse(partial, exp, '$.{{value}}');
    },

    'member-descendant-script_expression': function(component, partial) {
      var exp = component.expression.value.slice(1, -1);
      return eval_recurse(partial, exp, '$..value');
    }
  };

  Handlers.prototype._fns['subscript-child-string_literal'] =
    Handlers.prototype._fns['member-child-identifier'];

  Handlers.prototype._fns['member-descendant-numeric_literal'] =
      Handlers.prototype._fns['subscript-descendant-string_literal'] =
      Handlers.prototype._fns['member-descendant-identifier'];

  function eval_recurse(partial, src, template) {

    var jp = require('./index');
    var ast = aesprim.parse(src).body[0].expression;
    var value = evaluate(ast, { '@': partial.value });
    var path = template.replace(/\{\{\s*value\s*\}\}/g, value);

    var results = jp.nodes(partial.value, path);
    results.forEach(function(r) {
      r.path = partial.path.concat(r.path.slice(1));
    });

    return results;
  }

  function is_array(val) {
    return Array.isArray(val);
  }

  function is_object(val) {
    // is this a non-array, non-null object?
    return val && !(val instanceof Array) && val instanceof Object;
  }

  function traverser(recurse) {

    return function(partial, ref, passable, count) {

      var value = partial.value;
      var path = partial.path;

      var results = [];

      var descend = function(value, path) {

        if (is_array(value)) {
          value.forEach(function(element, index) {
            if (results.length >= count) { return }
            if (passable(index, element, ref)) {
              results.push({ path: path.concat(index), value: element });
            }
          });
          value.forEach(function(element, index) {
            if (results.length >= count) { return }
            if (recurse) {
              descend(element, path.concat(index));
            }
          });
        } else if (is_object(value)) {
          this.keys(value).forEach(function(k) {
            if (results.length >= count) { return }
            if (passable(k, value[k], ref)) {
              results.push({ path: path.concat(k), value: value[k] });
            }
          });
          this.keys(value).forEach(function(k) {
            if (results.length >= count) { return }
            if (recurse) {
              descend(value[k], path.concat(k));
            }
          });
        }
      }.bind(this);
      descend(value, path);
      return results;
    }
  }

  function _descend(passable) {
    return function(component, partial, count) {
      return this.descend(partial, component.expression.value, passable, count);
    }
  }

  function _traverse(passable) {
    return function(component, partial, count) {
      return this.traverse(partial, component.expression.value, passable, count);
    }
  }

  function evaluate() {
    try { return _evaluate.apply(this, arguments) }
    catch (e) { }
  }

  function unique(results) {
    results = results.filter(function(d) { return d });
    return _uniq(
      results,
      function(r) { return r.path.map(function(c) { return String(c).replace('-', '--') }).join('-') }
    );
  }

  function _parse_nullable_int(val) {
    var sval = String(val);
    return sval.match(/^-?[0-9]+$/) ? parseInt(sval) : null;
  }

  module.exports = Handlers;

  },{"..":"jsonpath","./aesprim":"./aesprim","./index":5,"./slice":7,"static-eval":15,"underscore":8}],5:[function(require,module,exports){
  var assert = require('assert');
  var dict = require('./dict');
  var Parser = require('./parser');
  var Handlers = require('./handlers');

  var JSONPath = function() {
    this.initialize.apply(this, arguments);
  };

  JSONPath.prototype.initialize = function() {
    this.parser = new Parser();
    this.handlers = new Handlers();
  };

  JSONPath.prototype.parse = function(string) {
    assert.ok(_is_string(string), "we need a path");
    return this.parser.parse(string);
  };

  JSONPath.prototype.parent = function(obj, string) {

    assert.ok(obj instanceof Object, "obj needs to be an object");
    assert.ok(string, "we need a path");

    var node = this.nodes(obj, string)[0];
    var key = node.path.pop(); /* jshint unused:false