Demo for query storing

Change-Id: I947bcac841992c3f6cfd01ab337c265b0d01cb70
diff --git a/node_modules/hooker/LICENSE-MIT b/node_modules/hooker/LICENSE-MIT
new file mode 100644
index 0000000..90c336c
--- /dev/null
+++ b/node_modules/hooker/LICENSE-MIT
@@ -0,0 +1,22 @@
+Copyright (c) 2012 "Cowboy" Ben Alman
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/node_modules/hooker/README.md b/node_modules/hooker/README.md
new file mode 100644
index 0000000..138943a
--- /dev/null
+++ b/node_modules/hooker/README.md
@@ -0,0 +1,186 @@
+# JavaScript Hooker
+
+Monkey-patch (hook) functions for debugging and stuff.
+
+## Getting Started
+
+This code should work just fine in Node.js:
+
+First, install the module with: `npm install hooker`
+
+```javascript
+var hooker = require('hooker');
+hooker.hook(Math, "max", function() {
+  console.log(arguments.length + " arguments passed");
+});
+Math.max(5, 6, 7) // logs: "3 arguments passed", returns 7
+```
+
+Or in the browser:
+
+```html
+<script src="dist/ba-hooker.min.js"></script>
+<script>
+hook(Math, "max", function() {
+  console.log(arguments.length + " arguments passed");
+});
+Math.max(5, 6, 7) // logs: "3 arguments passed", returns 7
+</script>
+```
+
+In the browser, you can attach Hooker's methods to any object.
+
+```html
+<script>
+this.exports = Bocoup.utils;
+</script>
+<script src="dist/ba-hooker.min.js"></script>
+<script>
+Bocoup.utils.hook(Math, "max", function() {
+  console.log(arguments.length + " arguments passed");
+});
+Math.max(5, 6, 7) // logs: "3 arguments passed", returns 7
+</script>
+```
+
+## Documentation
+
+### hooker.hook
+Monkey-patch (hook) one or more methods of an object.
+#### Signature:
+`hooker.hook(object, [ props, ] [options | prehookFunction])`
+#### `props`
+The optional `props` argument can be a method name, array of method names or null. If null (or omitted), all enumerable methods of `object` will be hooked.
+#### `options`
+* `pre` - (Function) a pre-hook function to be executed before the original function. Arguments passed into the method will be passed into the pre-hook function as well.
+* `post` - (Function) a post-hook function to be executed after the original function. The original function's result is passed into the post-hook function as its first argument, followed by the method arguments.
+* `once` - (Boolean) if true, auto-unhook the function after the first execution.
+* `passName` - (Boolean) if true, pass the name of the method into the pre-hook function as its first arg (preceding all other arguments), and into the post-hook function as the second arg (after result but preceding all other arguments).
+
+#### Returns:
+An array of hooked method names.
+
+### hooker.unhook
+Un-monkey-patch (unhook) one or more methods of an object.
+#### Signature:
+`hooker.unhook(object [, props ])`
+#### `props`
+The optional `props` argument can be a method name, array of method names or null. If null (or omitted), all methods of `object` will be unhooked.
+#### Returns:
+An array of unhooked method names.
+
+### hooker.orig
+Get a reference to the original method from a hooked function.
+#### Signature:
+`hooker.orig(object, props)`
+
+### hooker.override
+When a pre- or post-hook returns the result of this function, the value
+passed will be used in place of the original function's return value. Any
+post-hook override value will take precedence over a pre-hook override value.
+#### Signature:
+`hooker.override(value)`
+
+### hooker.preempt
+When a pre-hook returns the result of this function, the value passed will
+be used in place of the original function's return value, and the original
+function will NOT be executed.
+#### Signature:
+`hooker.preempt(value)`
+
+### hooker.filter
+When a pre-hook returns the result of this function, the context and
+arguments passed will be applied into the original function.
+#### Signature:
+`hooker.filter(context, arguments)`
+
+
+## Examples
+See the unit tests for more examples.
+
+```javascript
+var hooker = require('hooker');
+// Simple logging.
+hooker.hook(Math, "max", function() {
+  console.log(arguments.length + " arguments passed");
+});
+Math.max(5, 6, 7) // logs: "3 arguments passed", returns 7
+
+hooker.unhook(Math, "max"); // (This is assumed between all further examples)
+Math.max(5, 6, 7) // 7
+
+// Returning hooker.override(value) overrides the original value.
+hooker.hook(Math, "max", function() {
+  if (arguments.length === 0) {
+    return hooker.override(9000);
+  }
+});
+Math.max(5, 6, 7) // 7
+Math.max() // 9000
+
+// Auto-unhook after one execution.
+hooker.hook(Math, "max", {
+  once: true,
+  pre: function() {
+    console.log("Init something here");
+  }
+});
+Math.max(5, 6, 7) // logs: "Init something here", returns 7
+Math.max(5, 6, 7) // 7
+
+// Filter `this` and arguments through a pre-hook function.
+hooker.hook(Math, "max", {
+  pre: function() {
+    var args = [].map.call(arguments, function(num) {
+      return num * 2;
+    });
+    return hooker.filter(this, args); // thisValue, arguments
+  }
+});
+Math.max(5, 6, 7) // 14
+
+// Modify the original function's result with a post-hook function.
+hooker.hook(Math, "max", {
+  post: function(result) {
+    return hooker.override(result * 100);
+  }
+});
+Math.max(5, 6, 7) // 700
+
+// Hook every Math method. Note: if Math's methods were enumerable, the second
+// argument could be omitted. Since they aren't, an array of properties to hook
+// must be explicitly passed. Non-method properties will be skipped.
+// See a more generic example here: http://bit.ly/vvJlrS
+hooker.hook(Math, Object.getOwnPropertyNames(Math), {
+  passName: true,
+  pre: function(name) {
+    console.log("=> Math." + name, [].slice.call(arguments, 1));
+  },
+  post: function(result, name) {
+    console.log("<= Math." + name, result);
+  }
+});
+
+var result = Math.max(5, 6, 7);
+// => Math.max [ 5, 6, 7 ]
+// <= Math.max 7
+result // 7
+
+result = Math.ceil(3.456);
+// => Math.ceil [ 3.456 ]
+// <= Math.ceil 4
+result // 4
+```
+
+## Contributing
+In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [grunt](https://github.com/cowboy/grunt).
+
+_Also, please don't edit files in the "dist" subdirectory as they are generated via grunt. You'll find source code in the "lib" subdirectory!_
+
+## Release History
+2012/01/09 - v0.2.3 - First official release.
+
+## License
+Copyright (c) 2012 "Cowboy" Ben Alman  
+Licensed under the MIT license.  
+<http://benalman.com/about/license/>
diff --git a/node_modules/hooker/child.js b/node_modules/hooker/child.js
new file mode 100644
index 0000000..ae7dcf2
--- /dev/null
+++ b/node_modules/hooker/child.js
@@ -0,0 +1,101 @@
+var path = require('path');
+var fs = require('fs');
+var nodeunit = require('nodeunit');
+
+var filepaths = fs.readdirSync('test').map(function(filename) {
+  return path.join('test', filename);
+});
+
+var unfinished = {};
+var currentModule;
+function sendMessage(message) {
+  process.stdout.write(JSON.stringify(message) + '\n');
+}
+
+// If an exception is thrown, let the parent process know and exit.
+process.on('uncaughtException', function (e) {
+  sendMessage({error: [e.name, e.message, e.stack]});
+  process.exit();
+});
+
+// If Nodeunit explodes because a test was missing test.done(), handle it.
+var unfinished = {};
+process.on('exit', function (e) {
+  var len = Object.keys(unfinished).length
+  if (len > 0) {
+    sendMessage({exit: ['UNFINISHED']});
+    // process.reallyExit(len);
+  } else {
+    sendMessage({exit: ['finished']});
+  }
+  // process.exit();
+});
+
+nodeunit.reporters.test = {
+  run: function(files, options, callback) {
+    // Nodeunit needs absolute paths.
+    var paths = files.map(function (filepath) {
+      return path.resolve(filepath);
+    });
+    nodeunit.runFiles(paths, {
+      // No idea.
+      testspec: undefined,
+      // Executed when the first test in a file is run. If no tests exist in
+      // the file, this doesn't execute.
+      moduleStart: function(name) {
+        // Keep track of this so that moduleDone output can be suppressed in
+        // cases where a test file contains no tests.
+        currentModule = name;
+        // Send back to the parent process.
+        sendMessage({moduleStart: [name.toString()]});
+      },
+      // Executed after a file is done being processed. This executes whether
+      // tests exist in the file or not.
+      moduleDone: function(name) {
+        // Abort if no tests actually ran.
+        if (name !== currentModule) { return; }
+        // Send back to the parent process.
+        sendMessage({moduleDone: [name.toString()]});
+      },
+      // Executed before each test is run.
+      testStart: function(name) {
+        // Keep track of the current test, in case test.done() was omitted
+        // and Nodeunit explodes.
+        unfinished[name] = name;
+        // Send back to the parent process.
+        sendMessage({testStart: [name.toString()]});
+      },
+      // Executed after each test and all its assertions are run.
+      testDone: function(name, assertions) {
+        delete unfinished[name];
+        // Send back to the parent process.
+        sendMessage({testDone: [
+          name.toString(),
+          assertions.failures(),
+          assertions.map(function(assertion) {
+            var e = assertion.error;
+            if (e) {
+              assertion.error = {
+                name: e.name,
+                message: e.message,
+                stack: e.stack
+              };
+            }
+            return assertion;
+          })
+        ]});
+      },
+      // Executed when everything is all done.
+      done: function (assertions) {
+        // Send back to the parent process.
+        sendMessage({done: [
+          assertions.failures(),
+          assertions.duration,
+          assertions
+        ]});
+      }
+    });
+  }
+}
+
+nodeunit.reporters.test.run(filepaths, {});
diff --git a/node_modules/hooker/dist/ba-hooker.js b/node_modules/hooker/dist/ba-hooker.js
new file mode 100644
index 0000000..d10a321
--- /dev/null
+++ b/node_modules/hooker/dist/ba-hooker.js
@@ -0,0 +1,169 @@
+/*! JavaScript Hooker - v0.2.3 - 1/29/2012
+* http://github.com/cowboy/javascript-hooker
+* Copyright (c) 2012 "Cowboy" Ben Alman; Licensed MIT */
+
+(function(exports) {
+  // Get an array from an array-like object with slice.call(arrayLikeObject).
+  var slice = [].slice;
+  // Get an "[object [[Class]]]" string with toString.call(value).
+  var toString = {}.toString;
+
+  // I can't think of a better way to ensure a value is a specific type other
+  // than to create instances and use the `instanceof` operator.
+  function HookerOverride(v) { this.value = v; }
+  function HookerPreempt(v) { this.value = v; }
+  function HookerFilter(c, a) { this.context = c; this.args = a; }
+
+  // When a pre- or post-hook returns the result of this function, the value
+  // passed will be used in place of the original function's return value. Any
+  // post-hook override value will take precedence over a pre-hook override
+  // value.
+  exports.override = function(value) {
+    return new HookerOverride(value);
+  };
+
+  // When a pre-hook returns the result of this function, the value passed will
+  // be used in place of the original function's return value, and the original
+  // function will NOT be executed.
+  exports.preempt = function(value) {
+    return new HookerPreempt(value);
+  };
+
+  // When a pre-hook returns the result of this function, the context and
+  // arguments passed will be applied into the original function.
+  exports.filter = function(context, args) {
+    return new HookerFilter(context, args);
+  };
+
+  // Execute callback(s) for properties of the specified object.
+  function forMethods(obj, props, callback) {
+    var prop;
+    if (typeof props === "string") {
+      // A single prop string was passed. Create an array.
+      props = [props];
+    } else if (props == null) {
+      // No props were passed, so iterate over all properties, building an
+      // array. Unfortunately, Object.keys(obj) doesn't work everywhere yet, so
+      // this has to be done manually.
+      props = [];
+      for (prop in obj) {
+        if (obj.hasOwnProperty(prop)) {
+          props.push(prop);
+        }
+      }
+    }
+    // Execute callback for every method in the props array.
+    var i = props.length;
+    while (i--) {
+      // If the property isn't a function...
+      if (toString.call(obj[props[i]]) !== "[object Function]" ||
+        // ...or the callback returns false...
+        callback(obj, props[i]) === false) {
+        // ...remove it from the props array to be returned.
+        props.splice(i, 1);
+      }
+    }
+    // Return an array of method names for which the callback didn't fail.
+    return props;
+  }
+
+  // Monkey-patch (hook) a method of an object.
+  exports.hook = function(obj, props, options) {
+    // If the props argument was omitted, shuffle the arguments.
+    if (options == null) {
+      options = props;
+      props = null;
+    }
+    // If just a function is passed instead of an options hash, use that as a
+    // pre-hook function.
+    if (typeof options === "function") {
+      options = {pre: options};
+    }
+
+    // Hook the specified method of the object.
+    return forMethods(obj, props, function(obj, prop) {
+      // The original (current) method.
+      var orig = obj[prop];
+      // The new hooked function.
+      function hooked() {
+        var result, origResult, tmp;
+
+        // Get an array of arguments.
+        var args = slice.call(arguments);
+
+        // If passName option is specified, prepend prop to the args array,
+        // passing it as the first argument to any specified hook functions.
+        if (options.passName) {
+          args.unshift(prop);
+        }
+
+        // If a pre-hook function was specified, invoke it in the current
+        // context with the passed-in arguments, and store its result.
+        if (options.pre) {
+          result = options.pre.apply(this, args);
+        }
+
+        if (result instanceof HookerFilter) {
+          // If the pre-hook returned hooker.filter(context, args), invoke the
+          // original function with that context and arguments, and store its
+          // result.
+          origResult = result = orig.apply(result.context, result.args);
+        } else if (result instanceof HookerPreempt) {
+          // If the pre-hook returned hooker.preempt(value) just use the passed
+          // value and don't execute the original function.
+          origResult = result = result.value;
+        } else {
+          // Invoke the original function in the current context with the
+          // passed-in arguments, and store its result.
+          origResult = orig.apply(this, arguments);
+          // If the pre-hook returned hooker.override(value), use the passed
+          // value, otherwise use the original function's result.
+          result = result instanceof HookerOverride ? result.value : origResult;
+        }
+
+        if (options.post) {
+          // If a post-hook function was specified, invoke it in the current
+          // context, passing in the result of the original function as the
+          // first argument, followed by any passed-in arguments.
+          tmp = options.post.apply(this, [origResult].concat(args));
+          if (tmp instanceof HookerOverride) {
+            // If the post-hook returned hooker.override(value), use the passed
+            // value, otherwise use the previously computed result.
+            result = tmp.value;
+          }
+        }
+
+        // Unhook if the "once" option was specified.
+        if (options.once) {
+          exports.unhook(obj, prop);
+        }
+
+        // Return the result!
+        return result;
+      }
+      // Re-define the method.
+      obj[prop] = hooked;
+      // Fail if the function couldn't be hooked.
+      if (obj[prop] !== hooked) { return false; }
+      // Store a reference to the original method as a property on the new one.
+      obj[prop]._orig = orig;
+    });
+  };
+
+  // Get a reference to the original method from a hooked function.
+  exports.orig = function(obj, prop) {
+    return obj[prop]._orig;
+  };
+
+  // Un-monkey-patch (unhook) a method of an object.
+  exports.unhook = function(obj, props) {
+    return forMethods(obj, props, function(obj, prop) {
+      // Get a reference to the original method, if it exists.
+      var orig = exports.orig(obj, prop);
+      // If there's no original method, it can't be unhooked, so fail.
+      if (!orig) { return false; }
+      // Unhook the method.
+      obj[prop] = orig;
+    });
+  };
+}(typeof exports === "object" && exports || this));
diff --git a/node_modules/hooker/dist/ba-hooker.min.js b/node_modules/hooker/dist/ba-hooker.min.js
new file mode 100644
index 0000000..2bcdb54
--- /dev/null
+++ b/node_modules/hooker/dist/ba-hooker.min.js
@@ -0,0 +1,4 @@
+/*! JavaScript Hooker - v0.2.3 - 1/29/2012
+* http://github.com/cowboy/javascript-hooker
+* Copyright (c) 2012 "Cowboy" Ben Alman; Licensed MIT */
+(function(a){function d(a){this.value=a}function e(a){this.value=a}function f(a,b){this.context=a,this.args=b}function g(a,b,d){var e;if(typeof b=="string")b=[b];else if(b==null){b=[];for(e in a)a.hasOwnProperty(e)&&b.push(e)}var f=b.length;while(f--)(c.call(a[b[f]])!=="[object Function]"||d(a,b[f])===!1)&&b.splice(f,1);return b}var b=[].slice,c={}.toString;a.override=function(a){return new d(a)},a.preempt=function(a){return new e(a)},a.filter=function(a,b){return new f(a,b)},a.hook=function(c,h,i){return i==null&&(i=h,h=null),typeof i=="function"&&(i={pre:i}),g(c,h,function(c,g){function j(){var j,k,l,m=b.call(arguments);return i.passName&&m.unshift(g),i.pre&&(j=i.pre.apply(this,m)),j instanceof f?k=j=h.apply(j.context,j.args):j instanceof e?k=j=j.value:(k=h.apply(this,arguments),j=j instanceof d?j.value:k),i.post&&(l=i.post.apply(this,[k].concat(m)),l instanceof d&&(j=l.value)),i.once&&a.unhook(c,g),j}var h=c[g];c[g]=j;if(c[g]!==j)return!1;c[g]._orig=h})},a.orig=function(a,b){return a[b]._orig},a.unhook=function(b,c){return g(b,c,function(b,c){var d=a.orig(b,c);if(!d)return!1;b[c]=d})}})(typeof exports=="object"&&exports||this)
\ No newline at end of file
diff --git a/node_modules/hooker/grunt.js b/node_modules/hooker/grunt.js
new file mode 100644
index 0000000..c695148
--- /dev/null
+++ b/node_modules/hooker/grunt.js
@@ -0,0 +1,47 @@
+/*global config:true, task:true*/
+config.init({
+  pkg: '<json:package.json>',
+  meta: {
+    name: 'JavaScript Hooker',
+    banner: '/*! <%= meta.name %> - v<%= pkg.version %> - <%= template.today("m/d/yyyy") %>\n' +
+            '* <%= pkg.homepage %>\n' +
+            '* Copyright (c) <%= template.today("yyyy") %> <%= pkg.author.name %>;' +
+            ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */'
+  },
+  concat: {
+    'dist/ba-hooker.js': ['<banner>', '<file_strip_banner:lib/hooker.js>']
+  },
+  min: {
+    'dist/ba-hooker.min.js': ['<banner>', 'dist/ba-hooker.js']
+  },
+  test: {
+    files: ['test/**/*.js']
+  },
+  lint: {
+    files: ['grunt.js', 'lib/**/*.js', 'test/**/*.js']
+  },
+  watch: {
+    files: '<config:lint.files>',
+    tasks: 'lint:files test:files'
+  },
+  jshint: {
+    options: {
+      curly: true,
+      eqeqeq: true,
+      immed: true,
+      latedef: true,
+      newcap: true,
+      noarg: true,
+      sub: true,
+      undef: true,
+      eqnull: true
+    },
+    globals: {
+      exports: true
+    }
+  },
+  uglify: {}
+});
+
+// Default task.
+task.registerTask('default', 'lint:files test:files concat min');
diff --git a/node_modules/hooker/lib/hooker.js b/node_modules/hooker/lib/hooker.js
new file mode 100644
index 0000000..1ff9764
--- /dev/null
+++ b/node_modules/hooker/lib/hooker.js
@@ -0,0 +1,174 @@
+/*
+ * JavaScript Hooker
+ * http://github.com/cowboy/javascript-hooker
+ *
+ * Copyright (c) 2012 "Cowboy" Ben Alman
+ * Licensed under the MIT license.
+ * http://benalman.com/about/license/
+ */
+
+(function(exports) {
+  // Get an array from an array-like object with slice.call(arrayLikeObject).
+  var slice = [].slice;
+  // Get an "[object [[Class]]]" string with toString.call(value).
+  var toString = {}.toString;
+
+  // I can't think of a better way to ensure a value is a specific type other
+  // than to create instances and use the `instanceof` operator.
+  function HookerOverride(v) { this.value = v; }
+  function HookerPreempt(v) { this.value = v; }
+  function HookerFilter(c, a) { this.context = c; this.args = a; }
+
+  // When a pre- or post-hook returns the result of this function, the value
+  // passed will be used in place of the original function's return value. Any
+  // post-hook override value will take precedence over a pre-hook override
+  // value.
+  exports.override = function(value) {
+    return new HookerOverride(value);
+  };
+
+  // When a pre-hook returns the result of this function, the value passed will
+  // be used in place of the original function's return value, and the original
+  // function will NOT be executed.
+  exports.preempt = function(value) {
+    return new HookerPreempt(value);
+  };
+
+  // When a pre-hook returns the result of this function, the context and
+  // arguments passed will be applied into the original function.
+  exports.filter = function(context, args) {
+    return new HookerFilter(context, args);
+  };
+
+  // Execute callback(s) for properties of the specified object.
+  function forMethods(obj, props, callback) {
+    var prop;
+    if (typeof props === "string") {
+      // A single prop string was passed. Create an array.
+      props = [props];
+    } else if (props == null) {
+      // No props were passed, so iterate over all properties, building an
+      // array. Unfortunately, Object.keys(obj) doesn't work everywhere yet, so
+      // this has to be done manually.
+      props = [];
+      for (prop in obj) {
+        if (obj.hasOwnProperty(prop)) {
+          props.push(prop);
+        }
+      }
+    }
+    // Execute callback for every method in the props array.
+    var i = props.length;
+    while (i--) {
+      // If the property isn't a function...
+      if (toString.call(obj[props[i]]) !== "[object Function]" ||
+        // ...or the callback returns false...
+        callback(obj, props[i]) === false) {
+        // ...remove it from the props array to be returned.
+        props.splice(i, 1);
+      }
+    }
+    // Return an array of method names for which the callback didn't fail.
+    return props;
+  }
+
+  // Monkey-patch (hook) a method of an object.
+  exports.hook = function(obj, props, options) {
+    // If the props argument was omitted, shuffle the arguments.
+    if (options == null) {
+      options = props;
+      props = null;
+    }
+    // If just a function is passed instead of an options hash, use that as a
+    // pre-hook function.
+    if (typeof options === "function") {
+      options = {pre: options};
+    }
+
+    // Hook the specified method of the object.
+    return forMethods(obj, props, function(obj, prop) {
+      // The original (current) method.
+      var orig = obj[prop];
+      // The new hooked function.
+      function hooked() {
+        var result, origResult, tmp;
+
+        // Get an array of arguments.
+        var args = slice.call(arguments);
+
+        // If passName option is specified, prepend prop to the args array,
+        // passing it as the first argument to any specified hook functions.
+        if (options.passName) {
+          args.unshift(prop);
+        }
+
+        // If a pre-hook function was specified, invoke it in the current
+        // context with the passed-in arguments, and store its result.
+        if (options.pre) {
+          result = options.pre.apply(this, args);
+        }
+
+        if (result instanceof HookerFilter) {
+          // If the pre-hook returned hooker.filter(context, args), invoke the
+          // original function with that context and arguments, and store its
+          // result.
+          origResult = result = orig.apply(result.context, result.args);
+        } else if (result instanceof HookerPreempt) {
+          // If the pre-hook returned hooker.preempt(value) just use the passed
+          // value and don't execute the original function.
+          origResult = result = result.value;
+        } else {
+          // Invoke the original function in the current context with the
+          // passed-in arguments, and store its result.
+          origResult = orig.apply(this, arguments);
+          // If the pre-hook returned hooker.override(value), use the passed
+          // value, otherwise use the original function's result.
+          result = result instanceof HookerOverride ? result.value : origResult;
+        }
+
+        if (options.post) {
+          // If a post-hook function was specified, invoke it in the current
+          // context, passing in the result of the original function as the
+          // first argument, followed by any passed-in arguments.
+          tmp = options.post.apply(this, [origResult].concat(args));
+          if (tmp instanceof HookerOverride) {
+            // If the post-hook returned hooker.override(value), use the passed
+            // value, otherwise use the previously computed result.
+            result = tmp.value;
+          }
+        }
+
+        // Unhook if the "once" option was specified.
+        if (options.once) {
+          exports.unhook(obj, prop);
+        }
+
+        // Return the result!
+        return result;
+      }
+      // Re-define the method.
+      obj[prop] = hooked;
+      // Fail if the function couldn't be hooked.
+      if (obj[prop] !== hooked) { return false; }
+      // Store a reference to the original method as a property on the new one.
+      obj[prop]._orig = orig;
+    });
+  };
+
+  // Get a reference to the original method from a hooked function.
+  exports.orig = function(obj, prop) {
+    return obj[prop]._orig;
+  };
+
+  // Un-monkey-patch (unhook) a method of an object.
+  exports.unhook = function(obj, props) {
+    return forMethods(obj, props, function(obj, prop) {
+      // Get a reference to the original method, if it exists.
+      var orig = exports.orig(obj, prop);
+      // If there's no original method, it can't be unhooked, so fail.
+      if (!orig) { return false; }
+      // Unhook the method.
+      obj[prop] = orig;
+    });
+  };
+}(typeof exports === "object" && exports || this));
diff --git a/node_modules/hooker/package.json b/node_modules/hooker/package.json
new file mode 100644
index 0000000..21649bc
--- /dev/null
+++ b/node_modules/hooker/package.json
@@ -0,0 +1,67 @@
+{
+  "_from": "hooker@~0.2.3",
+  "_id": "hooker@0.2.3",
+  "_inBundle": false,
+  "_integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=",
+  "_location": "/hooker",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "range",
+    "registry": true,
+    "raw": "hooker@~0.2.3",
+    "name": "hooker",
+    "escapedName": "hooker",
+    "rawSpec": "~0.2.3",
+    "saveSpec": null,
+    "fetchSpec": "~0.2.3"
+  },
+  "_requiredBy": [
+    "/grunt-legacy-log",
+    "/grunt-legacy-util"
+  ],
+  "_resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz",
+  "_shasum": "b834f723cc4a242aa65963459df6d984c5d3d959",
+  "_spec": "hooker@~0.2.3",
+  "_where": "C:\\Users\\marcr\\Desktop\\KorAp\\Git\\Kalamar\\node_modules\\grunt-legacy-log",
+  "author": {
+    "name": "\"Cowboy\" Ben Alman",
+    "url": "http://benalman.com/"
+  },
+  "bugs": {
+    "url": "https://github.com/cowboy/javascript-hooker/issues"
+  },
+  "bundleDependencies": false,
+  "dependencies": {},
+  "deprecated": false,
+  "description": "Monkey-patch (hook) functions for debugging and stuff.",
+  "devDependencies": {
+    "grunt": "~0.2.1"
+  },
+  "engines": {
+    "node": "*"
+  },
+  "homepage": "http://github.com/cowboy/javascript-hooker",
+  "keywords": [
+    "patch",
+    "hook",
+    "function",
+    "debug",
+    "aop"
+  ],
+  "licenses": [
+    {
+      "type": "MIT",
+      "url": "https://github.com/cowboy/javascript-hooker/blob/master/LICENSE-MIT"
+    }
+  ],
+  "main": "lib/hooker",
+  "name": "hooker",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/cowboy/javascript-hooker.git"
+  },
+  "scripts": {
+    "test": "grunt test"
+  },
+  "version": "0.2.3"
+}
diff --git a/node_modules/hooker/parent.js b/node_modules/hooker/parent.js
new file mode 100644
index 0000000..c4a055e
--- /dev/null
+++ b/node_modules/hooker/parent.js
@@ -0,0 +1,17 @@
+var spawn = require('child_process').spawn;
+
+function loop() {
+  console.log('starting');
+  console.log(this);
+  //var child = spawn('./node_modules/nodeunit/bin/nodeunit', ['test']);
+  var child = spawn('node', ['child.js']);
+  child.stdout.on('data', function(buffer) {
+    process.stdout.write(buffer);
+  });
+  child.on('exit', this.async());
+}
+
+var context = {
+  async: function() { return loop.bind(context); }
+};
+loop.call(context);
\ No newline at end of file
diff --git a/node_modules/hooker/test/hooker_test.js b/node_modules/hooker/test/hooker_test.js
new file mode 100644
index 0000000..dc5910a
--- /dev/null
+++ b/node_modules/hooker/test/hooker_test.js
@@ -0,0 +1,435 @@
+/*global require:true */
+var hooker = require('../lib/hooker');
+
+exports['hook'] = {
+  setUp: function(done) {
+    this.order = [];
+    this.track = function() {
+      [].push.apply(this.order, arguments);
+    };
+
+    this.prop = 1;
+    this.add = function(a, b) {
+      this.track("add", this.prop, a, b);
+      return this.prop + a + b;
+    };
+
+    this.obj = {
+      that: this,
+      prop: 1,
+      add1: function(a, b) {
+        this.that.track("add1", this.prop, a, b);
+        return this.prop + a + b;
+      },
+      add2: function(a, b) {
+        this.that.track("add2", this.prop, a, b);
+        return this.prop + a + b;
+      },
+      add3: function(a, b) {
+        this.that.track("add3", this.prop, a, b);
+        return this.prop + a + b;
+      }
+    };
+
+    done();
+  },
+  'orig': function(test) {
+    test.expect(1);
+    var orig = this.add;
+    hooker.hook(this, "add", function() {});
+    test.strictEqual(hooker.orig(this, "add"), orig, "should return a refernce to the original function.");
+    test.done();
+  },
+  'once': function(test) {
+    test.expect(5);
+    var orig = this.add;
+    hooker.hook(this, "add", {
+      once: true,
+      pre: function(a, b) {
+        // Arguments are passed into pre-hook as specified.
+        this.track("before", this.prop, a, b);
+      }
+    });
+    test.strictEqual(this.add(2, 3), 6, "should return the original function's result.");
+    test.deepEqual(this.order, ["before", 1, 2, 3, "add", 1, 2, 3], "functions should execute in-order.");
+    test.strictEqual(this.add, orig, "should automatically unhook when once is specified.");
+    this.order = [];
+    test.strictEqual(this.add(2, 3), 6, "should return the original function's result.");
+    test.deepEqual(this.order, ["add", 1, 2, 3], "only the original function should execute.");
+    test.done();
+  },
+  'pre-hook (simple syntax)': function(test) {
+    test.expect(3);
+    // Pre-hook.
+    var result = hooker.hook(this, "add", function(a, b) {
+      // Arguments are passed into pre-hook as specified.
+      this.track("before", this.prop, a, b);
+    });
+    test.deepEqual(result, ["add"], "add should have been hooked.");
+    test.strictEqual(this.add(2, 3), 6, "should return the original function's result.");
+    test.deepEqual(this.order, ["before", 1, 2, 3, "add", 1, 2, 3], "functions should execute in-order.");
+    test.done();
+  },
+  'pre-hook': function(test) {
+    test.expect(3);
+    // Pre-hook.
+    var result = hooker.hook(this, "add", {
+      pre: function(a, b) {
+        // Arguments are passed into pre-hook as specified.
+        this.track("before", this.prop, a, b);
+      }
+    });
+    test.deepEqual(result, ["add"], "add should have been hooked.");
+    test.strictEqual(this.add(2, 3), 6, "should return the original function's result.");
+    test.deepEqual(this.order, ["before", 1, 2, 3, "add", 1, 2, 3], "functions should execute in-order.");
+    test.done();
+  },
+  'post-hook': function(test) {
+    test.expect(3);
+    // Post-hook.
+    var result = hooker.hook(this, "add", {
+      post: function(result, a, b) {
+        // Arguments to post-hook are the original function's return value,
+        // followed by the specified function arguments.
+        this.track("after", this.prop, a, b, result);
+      }
+    });
+    test.deepEqual(result, ["add"], "add should have been hooked.");
+    test.strictEqual(this.add(2, 3), 6, "should return the original function's result.");
+    test.deepEqual(this.order, ["add", 1, 2, 3, "after", 1, 2, 3, 6], "functions should execute in-order.");
+    test.done();
+  },
+  'pre- & post-hook': function(test) {
+    test.expect(2);
+    // Pre- & post-hook.
+    hooker.hook(this, "add", {
+      pre: function(a, b) {
+        // Arguments are passed into pre-hook as specified.
+        this.track("before", this.prop, a, b);
+      },
+      post: function(result, a, b) {
+        // Arguments to post-hook are the original function's return value,
+        // followed by the specified function arguments.
+        this.track("after", this.prop, a, b, result);
+      }
+    });
+    test.strictEqual(this.add(2, 3), 6, "should return the original function's result.");
+    test.deepEqual(this.order, ["before", 1, 2, 3, "add", 1, 2, 3, "after", 1, 2, 3, 6], "functions should execute in-order.");
+    test.done();
+  },
+
+  'pre-hook, return value override': function(test) {
+    test.expect(2);
+    // Pre-hook.
+    hooker.hook(this, "add", {
+      pre: function(a, b) {
+        // Arguments are passed into pre-hook as specified.
+        this.track("before", this.prop, a, b);
+        // This return value will override the original function's return value.
+        return hooker.override("b" + this.prop + a + b);
+      }
+    });
+    test.strictEqual(this.add(2, 3), "b123", "should return the overridden result.");
+    test.deepEqual(this.order, ["before", 1, 2, 3, "add", 1, 2, 3], "functions should execute in-order.");
+    test.done();
+  },
+  'post-hook, return value override': function(test) {
+    test.expect(2);
+    // Post-hook.
+    hooker.hook(this, "add", {
+      post: function(result, a, b) {
+        // Arguments to post-hook are the original function's return value,
+        // followed by the specified function arguments.
+        this.track("after", this.prop, a, b, result);
+        // This return value will override the original function's return value.
+        return hooker.override("a" + this.prop + a + b + result);
+      }
+    });
+    test.strictEqual(this.add(2, 3), "a1236", "should return the post-hook overridden result.");
+    test.deepEqual(this.order, ["add", 1, 2, 3, "after", 1, 2, 3, 6], "functions should execute in-order.");
+    test.done();
+  },
+  'pre- & post-hook, return value override': function(test) {
+    test.expect(2);
+    // Pre- & post-hook.
+    hooker.hook(this, "add", {
+      pre: function(a, b) {
+        // Arguments are passed into pre-hook as specified.
+        this.track("before", this.prop, a, b);
+        // This return value will override the original function's return value.
+        return hooker.override("b" + this.prop + a + b);
+      },
+      post: function(result, a, b) {
+        // Arguments to post-hook are the original function's return value,
+        // followed by the specified function arguments.
+        this.track("after", this.prop, a, b, result);
+        // This return value will override the original function's return value
+        // AND the pre-hook's return value.
+        return hooker.override("a" + this.prop + a + b + result);
+      }
+    });
+    test.strictEqual(this.add(2, 3), "a1236", "should return the overridden result, and post-hook result should take precedence over pre-hook result.");
+    test.deepEqual(this.order, ["before", 1, 2, 3, "add", 1, 2, 3, "after", 1, 2, 3, 6], "functions should execute in-order.");
+    test.done();
+  },
+
+  'pre-hook, filtering arguments': function(test) {
+    test.expect(2);
+    // Pre-hook.
+    hooker.hook(this, "add", {
+      pre: function(a, b) {
+        // Arguments are passed into pre-hook as specified.
+        this.track("before", this.prop, a, b);
+        // Return hooker.filter(context, arguments) and they will be passed into
+        // the original function. The "track" and "order" propterites are just
+        // set here for the same of this unit test.
+        return hooker.filter({prop: "x", track: this.track, order: this.order}, ["y", "z"]);
+      }
+    });
+    test.strictEqual(this.add(2, 3), "xyz", "should return the original function's result, given filtered context and arguments.");
+    test.deepEqual(this.order, ["before", 1, 2, 3, "add", "x", "y", "z"], "functions should execute in-order.");
+    test.done();
+  },
+  'pre- & post-hook, filtering arguments': function(test) {
+    test.expect(2);
+    // Pre- & post-hook.
+    hooker.hook(this, "add", {
+      pre: function(a, b) {
+        // Arguments are passed into pre-hook as specified.
+        this.track("before", this.prop, a, b);
+        // Return hooker.filter(context, arguments) and they will be passed into
+        // the original function. The "track" and "order" propterites are just
+        // set here for the same of this unit test.
+        return hooker.filter({prop: "x", track: this.track, order: this.order}, ["y", "z"]);
+      },
+      post: function(result, a, b) {
+        // Arguments to post-hook are the original function's return value,
+        // followed by the specified function arguments.
+        this.track("after", this.prop, a, b, result);
+      }
+    });
+    test.strictEqual(this.add(2, 3), "xyz", "should return the original function's result, given filtered context and arguments.");
+    test.deepEqual(this.order, ["before", 1, 2, 3, "add", "x", "y", "z", "after", 1, 2, 3, "xyz"], "functions should execute in-order.");
+    test.done();
+  },
+  'pre- & post-hook, filtering arguments, return value override': function(test) {
+    test.expect(2);
+    // Pre- & post-hook.
+    hooker.hook(this, "add", {
+      pre: function(a, b) {
+        // Arguments are passed into pre-hook as specified.
+        this.track("before", this.prop, a, b);
+        // Return hooker.filter(context, arguments) and they will be passed into
+        // the original function. The "track" and "order" propterites are just
+        // set here for the same of this unit test.
+        return hooker.filter({prop: "x", track: this.track, order: this.order}, ["y", "z"]);
+      },
+      post: function(result, a, b) {
+        // Arguments to post-hook are the original function's return value,
+        // followed by the specified function arguments.
+        this.track("after", this.prop, a, b, result);
+        // This return value will override the original function's return value
+        // AND the pre-hook's return value.
+        return hooker.override("a" + this.prop + a + b + result);
+      }
+    });
+    test.strictEqual(this.add(2, 3), "a123xyz", "should return the post-hook overridden result.");
+    test.deepEqual(this.order, ["before", 1, 2, 3, "add", "x", "y", "z", "after", 1, 2, 3, "xyz"], "functions should execute in-order.");
+    test.done();
+  },
+
+  'pre-hook, preempt original function': function(test) {
+    test.expect(2);
+    // Pre-hook.
+    hooker.hook(this, "add", {
+      pre: function(a, b) {
+        // Arguments are passed into pre-hook as specified.
+        this.track("before", this.prop, a, b);
+        // Returning hooker.preempt will prevent the original function from being
+        // invoked and optionally set a return value.
+        return hooker.preempt();
+      }
+    });
+    test.strictEqual(this.add(2, 3), undefined, "should return the value passed to preempt.");
+    test.deepEqual(this.order, ["before", 1, 2, 3], "functions should execute in-order.");
+    test.done();
+  },
+  'pre-hook, preempt original function with value': function(test) {
+    test.expect(2);
+    // Pre-hook.
+    hooker.hook(this, "add", {
+      pre: function(a, b) {
+        // Arguments are passed into pre-hook as specified.
+        this.track("before", this.prop, a, b);
+        // Returning hooker.preempt will prevent the original function from being
+        // invoked and optionally set a return value.
+        return hooker.preempt(9000);
+      }
+    });
+    test.strictEqual(this.add(2, 3), 9000, "should return the value passed to preempt.");
+    test.deepEqual(this.order, ["before", 1, 2, 3], "functions should execute in-order.");
+    test.done();
+  },
+  'pre- & post-hook, preempt original function with value': function(test) {
+    test.expect(2);
+    // Pre- & post-hook.
+    hooker.hook(this, "add", {
+      pre: function(a, b) {
+        // Arguments are passed into pre-hook as specified.
+        this.track("before", this.prop, a, b);
+        // Returning hooker.preempt will prevent the original function from being
+        // invoked and optionally set a return value.
+        return hooker.preempt(9000);
+      },
+      post: function(result, a, b) {
+        // Arguments to post-hook are the original function's return value,
+        // followed by the specified function arguments.
+        this.track("after", this.prop, a, b, result);
+      }
+    });
+    test.strictEqual(this.add(2, 3), 9000, "should return the value passed to preempt.");
+    test.deepEqual(this.order, ["before", 1, 2, 3, "after", 1, 2, 3, 9000], "functions should execute in-order.");
+    test.done();
+  },
+  'pre- & post-hook, preempt original function with value, return value override': function(test) {
+    test.expect(2);
+    // Pre- & post-hook.
+    hooker.hook(this, "add", {
+      pre: function(a, b) {
+        // Arguments are passed into pre-hook as specified.
+        this.track("before", this.prop, a, b);
+        // Returning hooker.preempt will prevent the original function from being
+        // invoked and optionally set a return value.
+        return hooker.preempt(9000);
+      },
+      post: function(result, a, b) {
+        // Arguments to post-hook are the original function's return value,
+        // followed by the specified function arguments.
+        this.track("after", this.prop, a, b, result);
+        // This return value will override any preempt value set in pre-hook.
+        return hooker.override("a" + this.prop + a + b + result);
+      }
+    });
+    test.strictEqual(this.add(2, 3), "a1239000", "should return the overridden result, and post-hook result should take precedence over preempt value.");
+    test.deepEqual(this.order, ["before", 1, 2, 3, "after", 1, 2, 3, 9000], "functions should execute in-order.");
+    test.done();
+  },
+  'pre- & post-hook, some properties': function(test) {
+    test.expect(7);
+    // Pre- & post-hook.
+    var result = hooker.hook(this.obj, ["add1", "add2"], {
+      pre: function(a, b) {
+        // Arguments are passed into pre-hook as specified.
+        this.that.track("before", this.prop, a, b);
+      },
+      post: function(result, a, b) {
+        // Arguments to post-hook are the original function's return value,
+        // followed by the specified function arguments.
+        this.that.track("after", this.prop, a, b, result);
+      }
+    });
+    test.deepEqual(result.sort(), ["add1", "add2"], "both functions should have been hooked.");
+    test.strictEqual(this.obj.add1(2, 3), 6, "should return the original function's result.");
+    test.deepEqual(this.order, ["before", 1, 2, 3, "add1", 1, 2, 3, "after", 1, 2, 3, 6], "functions should execute in-order.");
+    this.order = [];
+    test.strictEqual(this.obj.add2(2, 3), 6, "should return the original function's result.");
+    test.deepEqual(this.order, ["before", 1, 2, 3, "add2", 1, 2, 3, "after", 1, 2, 3, 6], "functions should execute in-order.");
+    this.order = [];
+    test.strictEqual(this.obj.add3(2, 3), 6, "should return the original function's result.");
+    test.deepEqual(this.order, ["add3", 1, 2, 3], "functions should execute in-order.");
+    test.done();
+  },
+  'pre- & post-hook, all properties': function(test) {
+    test.expect(7);
+    // Pre- & post-hook.
+    var result = hooker.hook(this.obj, {
+      pre: function(a, b) {
+        // Arguments are passed into pre-hook as specified.
+        this.that.track("before", this.prop, a, b);
+      },
+      post: function(result, a, b) {
+        // Arguments to post-hook are the original function's return value,
+        // followed by the specified function arguments.
+        this.that.track("after", this.prop, a, b, result);
+      }
+    });
+    test.deepEqual(result.sort(), ["add1", "add2", "add3"], "all functions should have been hooked.");
+    test.strictEqual(this.obj.add1(2, 3), 6, "should return the original function's result.");
+    test.deepEqual(this.order, ["before", 1, 2, 3, "add1", 1, 2, 3, "after", 1, 2, 3, 6], "functions should execute in-order.");
+    this.order = [];
+    test.strictEqual(this.obj.add2(2, 3), 6, "should return the original function's result.");
+    test.deepEqual(this.order, ["before", 1, 2, 3, "add2", 1, 2, 3, "after", 1, 2, 3, 6], "functions should execute in-order.");
+    this.order = [];
+    test.strictEqual(this.obj.add3(2, 3), 6, "should return the original function's result.");
+    test.deepEqual(this.order, ["before", 1, 2, 3, "add3", 1, 2, 3, "after", 1, 2, 3, 6], "functions should execute in-order.");
+    test.done();
+  },
+  'pre- & post-hook, all properties, passName': function(test) {
+    test.expect(6);
+    // Pre- & post-hook.
+    hooker.hook(this.obj, {
+      passName: true,
+      pre: function(name, a, b) {
+        // Arguments are passed into pre-hook as specified.
+        this.that.track("before", this.prop, name, a, b);
+      },
+      post: function(result, name, a, b) {
+        // Arguments to post-hook are the original function's return value,
+        // followed by the specified function arguments.
+        this.that.track("after", this.prop, name, a, b, result);
+      }
+    });
+    test.strictEqual(this.obj.add1(2, 3), 6, "should return the original function's result.");
+    test.deepEqual(this.order, ["before", 1, "add1", 2, 3, "add1", 1, 2, 3, "after", 1, "add1", 2, 3, 6], "functions should execute in-order.");
+    this.order = [];
+    test.strictEqual(this.obj.add2(2, 3), 6, "should return the original function's result.");
+    test.deepEqual(this.order, ["before", 1, "add2", 2, 3, "add2", 1, 2, 3, "after", 1, "add2", 2, 3, 6], "functions should execute in-order.");
+    this.order = [];
+    test.strictEqual(this.obj.add3(2, 3), 6, "should return the original function's result.");
+    test.deepEqual(this.order, ["before", 1, "add3", 2, 3, "add3", 1, 2, 3, "after", 1, "add3", 2, 3, 6], "functions should execute in-order.");
+    test.done();
+  },
+  'unhook one property': function(test) {
+    test.expect(5);
+    var orig = this.add;
+    hooker.hook(this, "add", function() {});
+    var result = hooker.unhook(this, "add");
+    test.deepEqual(result, ["add"], "one function should have been unhooked.");
+    test.strictEqual(this.add, orig, "should have unhooked, restoring the original function");
+    result = hooker.unhook(this, "add");
+    test.deepEqual(result, [], "nothing should have been unhooked.");
+    test.strictEqual(this.add, orig, "shouldn't explode if already unhooked");
+    test.strictEqual(this.add.orig, undefined, "original function shouldn't have an orig property");
+    test.done();
+  },
+  'unhook some properties': function(test) {
+    test.expect(6);
+    var add1 = this.obj.add1;
+    var add2 = this.obj.add2;
+    hooker.hook(this.obj, ["add1", "add2"], function() {});
+    test.strictEqual(hooker.orig(this.obj, "add1"), add1, "should return a refernce to the original function");
+    test.strictEqual(hooker.orig(this.obj, "add2"), add2, "should return a refernce to the original function");
+    test.strictEqual(hooker.orig(this.obj, "add3"), undefined, "should not have been hooked, so should not have an original function");
+    var result = hooker.unhook(this.obj, ["add1", "add2"]);
+    test.deepEqual(result.sort(), ["add1", "add2"], "both functions should have been unhooked.");
+    test.strictEqual(this.obj.add1, add1, "should have unhooked, restoring the original function");
+    test.strictEqual(this.obj.add2, add2, "should have unhooked, restoring the original function");
+    test.done();
+  },
+  'unhook all properties': function(test) {
+    test.expect(7);
+    var add1 = this.obj.add1;
+    var add2 = this.obj.add2;
+    var add3 = this.obj.add3;
+    hooker.hook(this.obj, function() {});
+    test.strictEqual(hooker.orig(this.obj, "add1"), add1, "should return a refernce to the original function");
+    test.strictEqual(hooker.orig(this.obj, "add2"), add2, "should return a refernce to the original function");
+    test.strictEqual(hooker.orig(this.obj, "add3"), add3, "should return a refernce to the original function");
+    var result = hooker.unhook(this.obj);
+    test.deepEqual(result.sort(), ["add1", "add2", "add3"], "all functions should have been unhooked.");
+    test.strictEqual(this.obj.add1, add1, "should have unhooked, restoring the original function");
+    test.strictEqual(this.obj.add2, add2, "should have unhooked, restoring the original function");
+    test.strictEqual(this.obj.add3, add3, "should have unhooked, restoring the original function");
+    test.done();
+  }
+};