Demo for query storing

Change-Id: I947bcac841992c3f6cfd01ab337c265b0d01cb70
diff --git a/node_modules/error/.istanbul.yml b/node_modules/error/.istanbul.yml
new file mode 100644
index 0000000..a685158
--- /dev/null
+++ b/node_modules/error/.istanbul.yml
@@ -0,0 +1,11 @@
+instrumentation:
+    default-excludes: false
+    include-all-sources: true
+    excludes:
+        - '**/test/**'
+        - '**/coverage/**'
+        - '**/example/**'
+        - '**/test.js'
+        - '**/node_modules/istanbul/**'
+        - '**/node_modules/tape/**'
+        - '**/node_modules/uber-standard/**'
diff --git a/node_modules/error/MIGRATION.md b/node_modules/error/MIGRATION.md
new file mode 100644
index 0000000..b02c35c
--- /dev/null
+++ b/node_modules/error/MIGRATION.md
@@ -0,0 +1,58 @@
+## Migration
+
+## Version 7
+
+The `message` parameter to `TypedError` is now
+required. Previously `message` was optional
+for `TypedError`.
+
+## Version 6
+
+The `WrappedError` class now exposes the error that
+is being wrapped as a `cause` field instead of an
+`original` field.
+
+The following properties have been reserver on the
+wrapped error class: `cause`, `fullType`, `causeMessage`
+
+## Version 5
+
+There were no breaking changes...
+
+## Version 4
+
+The `TypedError` function now has mandatory arguments.
+The `type` and `message` arguments for `TypedError`
+are required.
+
+## Version 3
+
+The `TypedError` class now uses `string-template` for
+message formatting.
+
+Previously:
+
+```js
+var FooError = TypedError({
+  type: 'foo.x'
+  message: 'Got an error %s'
+});
+
+FooError('Oops');
+```
+
+Currently:
+
+```js
+var FooError = TypedError({
+  type: 'foo.x',
+  message: 'Got an error {ctx}',
+  ctx: null
+});
+
+FooError({ ctx: 'Oops' });
+```
+
+## Version 2
+
+Original version
diff --git a/node_modules/error/README.md b/node_modules/error/README.md
new file mode 100644
index 0000000..d88e8ad
--- /dev/null
+++ b/node_modules/error/README.md
@@ -0,0 +1,93 @@
+# error
+
+<!--
+    [![build status][1]][2]
+    [![NPM version][3]][4]
+    [![Coverage Status][5]][6]
+    [![gemnasium Dependency Status][7]][8]
+    [![Davis Dependency status][9]][10]
+-->
+
+<!-- [![browser support][11]][12] -->
+
+Custom errors
+
+## Typed Error
+
+```js
+var TypedError = require("error/typed")
+
+var ServerError = TypedError({
+    type: 'server.5xx',
+    message: '{title} server error, status={statusCode}',
+    title: null,
+    statusCode: null
+});
+var ClientError = TypedError({
+    type: 'client.4xx',
+    message: '{title} client error, status={statusCode}',
+    title: null,
+    statusCode: null
+});
+
+var error = ServerError({
+    title:'some title',
+    statusCode: 500
+});
+var error2 = ClientError({
+    title: 'some title',
+    statusCode: 404
+});
+```
+
+## Wrapped Errors
+
+```js
+var net = require('net');
+var WrappedError = require('error/wrapped');
+
+var ServerListenError = WrappedError({
+    message: 'server: {origMessage}',
+    type: 'server.listen-failed',
+    requestedPort: null,
+    host: null
+});
+
+var server = net.createServer();
+
+server.on('error', function onError(err) {
+    if (err.code === 'EADDRINUSE') {
+        throw ServerListenError(err, {
+            requestedPort: 3000,
+            host: null
+        });
+    } else {
+        throw err;
+    }
+});
+
+server.listen(3000);
+```
+
+## Installation
+
+`npm install error`
+
+## Contributors
+
+ - Raynos
+
+## MIT Licenced
+
+  [1]: https://secure.travis-ci.org/Raynos/error.png
+  [2]: https://travis-ci.org/Raynos/error
+  [3]: https://badge.fury.io/js/error.png
+  [4]: https://badge.fury.io/js/error
+  [5]: https://coveralls.io/repos/Raynos/error/badge.png
+  [6]: https://coveralls.io/r/Raynos/error
+  [7]: https://gemnasium.com/Raynos/error.png
+  [8]: https://gemnasium.com/Raynos/error
+  [9]: https://david-dm.org/Raynos/error.png
+  [10]: https://david-dm.org/Raynos/error
+  [11]: https://ci.testling.com/Raynos/error.png
+  [12]: https://ci.testling.com/Raynos/error
diff --git a/node_modules/error/docs.mli b/node_modules/error/docs.mli
new file mode 100644
index 0000000..7a1dac7
--- /dev/null
+++ b/node_modules/error/docs.mli
@@ -0,0 +1,26 @@
+type OptionError<T> := {
+    option: T | null,
+    message: String,
+    type: "OptionError"
+}
+
+type TypedError<T> := {
+    message: String,
+    type: T
+}
+
+type ValidationError := {
+    errors: Array<Error>,
+    message: String,
+    type: "ValidationError"
+}
+
+error/option := (String, T) => OptionError<T>
+
+error/typed := (args: {
+    message: String,
+    type: String,
+    name?: String
+}) => (opts: Object) => TypedError<String>
+
+error/validation := (Array<Error>) => ValidationError
diff --git a/node_modules/error/io.js b/node_modules/error/io.js
new file mode 100644
index 0000000..76661ce
--- /dev/null
+++ b/node_modules/error/io.js
@@ -0,0 +1,21 @@
+'use strict';
+
+module.exports = IOError;
+
+function IOError(cause, prefix) {
+    var err = new Error(prefix + ': ' + cause.message);
+
+    Object.defineProperty(err, 'type', {
+        value: 'error.IOError',
+        configurable: true,
+        enumerable: true
+    });
+    err.name = 'WrappedIOError';
+    err.statusCode = 500;
+    Object.defineProperty(err, 'cause', {
+        value: cause,
+        configurable: true,
+        enumerable: false
+    });
+    return err;
+}
diff --git a/node_modules/error/option.js b/node_modules/error/option.js
new file mode 100644
index 0000000..273894f
--- /dev/null
+++ b/node_modules/error/option.js
@@ -0,0 +1,19 @@
+module.exports = OptionError
+
+function OptionError(message, options) {
+    var result = new Error()
+
+    Object.defineProperty(result, "type", {
+        value: result.type,
+        enumerable: true,
+        writable: true,
+        configurable: true
+    })
+
+    result.option = options || null
+    result.message = message
+    result.type = "OptionError"
+
+    return result
+}
+
diff --git a/node_modules/error/package.json b/node_modules/error/package.json
new file mode 100644
index 0000000..a65135e
--- /dev/null
+++ b/node_modules/error/package.json
@@ -0,0 +1,89 @@
+{
+  "_from": "error@^7.0.0",
+  "_id": "error@7.2.1",
+  "_inBundle": false,
+  "_integrity": "sha512-fo9HBvWnx3NGUKMvMwB/CBCMMrfEJgbDTVDEkPygA3Bdd3lM1OyCd+rbQ8BwnpF6GdVeOLDNmyL4N5Bg80ZvdA==",
+  "_location": "/error",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "range",
+    "registry": true,
+    "raw": "error@^7.0.0",
+    "name": "error",
+    "escapedName": "error",
+    "rawSpec": "^7.0.0",
+    "saveSpec": null,
+    "fetchSpec": "^7.0.0"
+  },
+  "_requiredBy": [
+    "/body"
+  ],
+  "_resolved": "https://registry.npmjs.org/error/-/error-7.2.1.tgz",
+  "_shasum": "eab21a4689b5f684fc83da84a0e390de82d94894",
+  "_spec": "error@^7.0.0",
+  "_where": "C:\\Users\\marcr\\Desktop\\KorAp\\Git\\Kalamar\\node_modules\\body",
+  "author": {
+    "name": "Raynos",
+    "email": "raynos2@gmail.com"
+  },
+  "bugs": {
+    "url": "https://github.com/Raynos/error/issues",
+    "email": "raynos2@gmail.com"
+  },
+  "bundleDependencies": false,
+  "contributors": [
+    {
+      "name": "Raynos"
+    }
+  ],
+  "dependencies": {
+    "string-template": "~0.2.1"
+  },
+  "deprecated": false,
+  "description": "Custom errors",
+  "devDependencies": {
+    "istanbul": "0.3.13",
+    "tape": "^3.5.0",
+    "uber-standard": "3.6.4"
+  },
+  "homepage": "https://github.com/Raynos/error",
+  "keywords": [],
+  "licenses": [
+    {
+      "type": "MIT",
+      "url": "http://github.com/Raynos/error/raw/master/LICENSE"
+    }
+  ],
+  "main": "index",
+  "name": "error",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/Raynos/error.git"
+  },
+  "scripts": {
+    "cover": "istanbul cover --report none --print detail ./test/index.js",
+    "lint": "standard -v .",
+    "test": "npm run lint && node test/index.js",
+    "test-browser": "testem-browser ./test/browser/index.js",
+    "testem": "testem-both -b=./test/browser/index.js",
+    "travis-test": "istanbul cover ./test/index.js && ((cat coverage/lcov.info | coveralls) || exit 0)",
+    "view-cover": "istanbul report html && google-chrome ./coverage/index.html"
+  },
+  "testling": {
+    "files": "test/index.js",
+    "browsers": [
+      "ie/8..latest",
+      "firefox/16..latest",
+      "firefox/nightly",
+      "chrome/22..latest",
+      "chrome/canary",
+      "opera/12..latest",
+      "opera/next",
+      "safari/5.1..latest",
+      "ipad/6.0..latest",
+      "iphone/6.0..latest",
+      "android-browser/4.2..latest"
+    ]
+  },
+  "version": "7.2.1"
+}
diff --git a/node_modules/error/test/index.js b/node_modules/error/test/index.js
new file mode 100644
index 0000000..9b3433b
--- /dev/null
+++ b/node_modules/error/test/index.js
@@ -0,0 +1,4 @@
+'use strict';
+
+require('./typed.js');
+require('./wrapped.js');
diff --git a/node_modules/error/test/typed.js b/node_modules/error/test/typed.js
new file mode 100644
index 0000000..fae9fcf
--- /dev/null
+++ b/node_modules/error/test/typed.js
@@ -0,0 +1,66 @@
+'use strict';
+
+var test = require('tape');
+
+var TypedError = require('../typed.js');
+
+test('a server error', function t(assert) {
+    var ServerError = TypedError({
+        type: 'server.5xx.error',
+        message: '{title} server error, status={statusCode}'
+    });
+
+    var error = ServerError({
+        title: 'some title',
+        statusCode: 500
+    });
+
+    assert.equal(ServerError.type, 'server.5xx.error');
+
+    assert.equal(error.type, 'server.5xx.error');
+    assert.equal(error.fullType, 'server.5xx.error');
+    assert.equal(error.statusCode, 500);
+    assert.equal(error.message, 'some title server error, status=500');
+    assert.equal(error.toString(),
+        'Server5xxErrorError: some title server error, status=500')
+
+    assert.end();
+});
+
+test('null fields', function t(assert) {
+    var NullError = TypedError({
+        type: 'myError',
+        message: 'myError',
+        length: null,
+        buffer: null,
+        state: null,
+        expecting: null
+    })
+
+    var e = NullError()
+    assert.equal(e.type, 'myError')
+    assert.equal(NullError.type, 'myError')
+
+    assert.end()
+})
+
+test('a client error', function t(assert) {
+    var ClientError = TypedError({
+        type: 'client.4xx.error',
+        message: '{title} client error, status={statusCode}'
+    });
+
+    var error2 = ClientError({
+        title: 'some title',
+        statusCode: 404
+    });
+
+    assert.equal(error2.type, 'client.4xx.error');
+    assert.equal(error2.fullType, 'client.4xx.error');
+    assert.equal(error2.statusCode, 404);
+    assert.equal(error2.message, 'some title client error, status=404');
+    assert.equal(error2.toString(),
+        'Client4xxErrorError: some title client error, status=404')
+
+    assert.end();
+});
diff --git a/node_modules/error/test/wrapped.js b/node_modules/error/test/wrapped.js
new file mode 100644
index 0000000..6dcf635
--- /dev/null
+++ b/node_modules/error/test/wrapped.js
@@ -0,0 +1,206 @@
+'use strict';
+
+var test = require('tape');
+var net = require('net');
+
+var WrappedError = require('../wrapped.js');
+
+test('can create a wrapped error', function t(assert) {
+    var ServerListenError = WrappedError({
+        name: 'SomeError',
+        message: 'server: {causeMessage}',
+        type: 'server.listen-failed',
+        requestedPort: null,
+        host: null
+    });
+
+    var err = new Error('listen EADDRINUSE');
+    err.code = 'EADDRINUSE';
+
+    var err2 = ServerListenError(err, {
+        requestedPort: 3426,
+        host: 'localhost'
+    });
+
+    assert.equal(ServerListenError.type, 'server.listen-failed');
+
+    assert.equal(err2.message, 'server: listen EADDRINUSE');
+    assert.equal(err2.requestedPort, 3426);
+    assert.equal(err2.host, 'localhost');
+    assert.equal(err2.code, 'EADDRINUSE');
+
+    assert.equal(err2.cause, err);
+
+    assert.equal(err2.toString(),
+        'ServerListenFailedError: server: listen EADDRINUSE');
+
+    assert.equal(JSON.stringify(err2), JSON.stringify({
+        type: 'server.listen-failed',
+        name: 'ServerListenFailedError',
+        message: 'server: listen EADDRINUSE',
+        requestedPort: 3426,
+        host: 'localhost',
+        causeMessage: 'listen EADDRINUSE',
+        origMessage: 'listen EADDRINUSE',
+        code: 'EADDRINUSE',
+        fullType: 'server.listen-failed~!~error.wrapped-unknown'
+    }));
+
+    assert.end();
+});
+
+test('can create wrapped error with syscall', function t(assert) {
+    var SysCallError = WrappedError({
+        'message': 'tchannel socket error ({code} from ' +
+            '{syscall}): {origMessage}',
+        type: 'syscall.error'
+    });
+
+    var err = new Error('listen EADDRINUSE');
+    err.code = 'EADDRINUSE';
+    err.syscall = 'listen';
+
+    var err2 = SysCallError(err);
+
+    assert.equal(err2.message, 'tchannel socket error ' +
+        '(EADDRINUSE from listen): listen EADDRINUSE');
+    assert.equal(err2.syscall, 'listen');
+    assert.equal(err2.code, 'EADDRINUSE');
+    assert.equal(err2.type, 'syscall.error');
+
+    assert.end();
+});
+
+test('wrapping twice', function t(assert) {
+    var ReadError = WrappedError({
+        type: 'my.read-error',
+        message: 'read: {causeMessage}'
+    });
+
+    var DatabaseError = WrappedError({
+        type: 'my.database-error',
+        message: 'db: {causeMessage}'
+    });
+
+    var BusinessError = WrappedError({
+        type: 'my.business-error',
+        message: 'business: {causeMessage}'
+    });
+
+    var err = BusinessError(
+        DatabaseError(
+            ReadError(
+                new Error('oops')
+            )
+        )
+    );
+    assert.ok(err);
+
+    assert.equal(err.message, 'business: db: read: oops');
+    assert.equal(err.type, 'my.business-error');
+    assert.equal(err.fullType, 'my.business-error~!~' +
+        'my.database-error~!~' +
+        'my.read-error~!~' +
+        'error.wrapped-unknown');
+
+    assert.end();
+});
+
+test('handles bad recursive strings', function t(assert) {
+    var ReadError = WrappedError({
+        type: 'wat.wat',
+        message: 'read: {causeMessage}'
+    });
+
+    var err2 = ReadError(new Error('hi {causeMessage}'));
+
+    assert.ok(err2);
+    assert.equal(err2.message,
+        'read: hi $INVALID_CAUSE_MESSAGE_LITERAL');
+
+    assert.end();
+});
+
+test('can wrap real IO errors', function t(assert) {
+    var ServerListenError = WrappedError({
+        message: 'server: {causeMessage}',
+        type: 'server.listen-failed',
+        requestedPort: null,
+        host: null
+    });
+
+    var otherServer = net.createServer();
+    otherServer.once('listening', onPortAllocated);
+    otherServer.listen(0);
+
+    function onPortAllocated() {
+        var port = otherServer.address().port;
+
+        var server = net.createServer();
+        server.on('error', onError);
+
+        server.listen(port);
+
+        function onError(cause) {
+            var err = ServerListenError(cause, {
+                host: 'localhost',
+                requestedPort: port
+            });
+
+            otherServer.close();
+            assertOnError(err, cause, port);
+        }
+    }
+
+    function assertOnError(err, cause, port) {
+        assert.ok(err.message.indexOf('server: ') >= 0)
+        assert.ok(err.message.indexOf('listen EADDRINUSE') >= 0)
+        assert.equal(err.requestedPort, port);
+        assert.equal(err.host, 'localhost');
+        assert.equal(err.code, 'EADDRINUSE');
+
+        assert.equal(err.cause, cause);
+
+        assert.ok(err.toString().indexOf('ServerListenFailedError: ') >= 0)
+        assert.ok(err.toString().indexOf('server: ') >= 0)
+        assert.ok(err.toString().indexOf('listen EADDRINUSE') >= 0)
+
+        var expectedMessage = err.message
+        var expectedOrigMessage = err.origMessage
+
+        assert.ok(err.origMessage.indexOf('listen EADDRINUSE') >= 0)
+        assert.ok(err.origMessage.indexOf('server: ') === -1)
+
+        assert.equal(JSON.stringify(err), JSON.stringify({
+            type: 'server.listen-failed',
+            name: 'ServerListenFailedError',
+            message: expectedMessage,
+            requestedPort: port,
+            host: 'localhost',
+            causeMessage: expectedOrigMessage,
+            origMessage: expectedOrigMessage,
+            code: 'EADDRINUSE',
+            errno: 'EADDRINUSE',
+            syscall: 'listen',
+            fullType: 'server.listen-failed~!~' +
+                'error.wrapped-io.listen.EADDRINUSE'
+        }));
+
+        assert.end();
+    }
+});
+
+test('can wrap assert errors', function t(assert) {
+  var TestError = WrappedError({
+      message: 'error: {origMessage}',
+      type: 'error'
+  });
+
+  var assertError;
+  try { require('assert').equal('a', 'b'); }
+  catch (_err) { assertError = _err; }
+
+  var err = TestError(assertError);
+  assert.equal(err.cause.actual, 'a');
+  assert.end();
+})
diff --git a/node_modules/error/typed.js b/node_modules/error/typed.js
new file mode 100644
index 0000000..e533a59
--- /dev/null
+++ b/node_modules/error/typed.js
@@ -0,0 +1,86 @@
+'use strict';
+
+var template = require('string-template');
+var assert = require('assert');
+
+var hasOwnProperty = Object.prototype.hasOwnProperty;
+var isWordBoundary = /[_.-](\w|$)/g;
+
+var FUNCTION_FIELD_WHITELIST = Object.getOwnPropertyNames(TypedError)
+
+module.exports = TypedError;
+
+function TypedError(args) {
+    assert(args, 'TypedError: must specify options');
+    assert(args.type, 'TypedError: must specify options.type');
+    assert(args.message, 'TypedError: must specify options.message');
+
+    assert(!has(args, 'fullType'),
+        'TypedError: fullType field is reserved');
+
+    var message = args.message;
+    var funcName = args.name
+    if (!funcName) {
+        var errorName = camelCase(args.type) + 'Error';
+        funcName = errorName[0].toUpperCase() + errorName.substr(1);
+    }
+
+    var copyArgs = {}
+    extend(copyArgs, args)
+    for (var i = 0; i < FUNCTION_FIELD_WHITELIST.length; i++) {
+        delete copyArgs[FUNCTION_FIELD_WHITELIST[i]]
+    }
+
+    extend(createError, copyArgs);
+    createError._name = funcName;
+
+    return createError;
+
+    function createError(opts) {
+        var result = new Error();
+
+        Object.defineProperty(result, 'type', {
+            value: result.type,
+            enumerable: true,
+            writable: true,
+            configurable: true
+        });
+
+        var options = {}
+        extend(options, args)
+        extend(options, opts)
+        if (!options.fullType) {
+            options.fullType = options.type;
+        }
+
+        result.name = funcName
+        extend(result, options);
+        if (opts && opts.message) {
+            result.message = template(opts.message, options);
+        } else if (message) {
+            result.message = template(message, options);
+        }
+
+        return result;
+    }
+}
+
+function extend(target, source) {
+    for (var key in source) {
+        if (hasOwnProperty.call(source, key)) {
+            target[key] = source[key]
+        }
+    }
+}
+
+function camelCase(str) {
+    return str.replace(isWordBoundary, upperCase);
+}
+
+function upperCase(_, x) {
+    return x.toUpperCase();
+}
+
+function has(obj, key) {
+    return Object.prototype.hasOwnProperty.call(obj, key);
+}
diff --git a/node_modules/error/validation.js b/node_modules/error/validation.js
new file mode 100644
index 0000000..b20d19e
--- /dev/null
+++ b/node_modules/error/validation.js
@@ -0,0 +1,19 @@
+module.exports = ValidationError
+
+function ValidationError(errors) {
+    var result = new Error()
+
+    Object.defineProperty(result, "type", {
+        value: result.type,
+        enumerable: true,
+        writable: true,
+        configurable: true
+    })
+
+    result.errors = errors
+    result.message = errors[0].message
+    result.type = "ValidationError"
+
+    return result
+}
+
diff --git a/node_modules/error/wrapped.js b/node_modules/error/wrapped.js
new file mode 100644
index 0000000..f890a65
--- /dev/null
+++ b/node_modules/error/wrapped.js
@@ -0,0 +1,124 @@
+'use strict';
+
+var assert = require('assert');
+var util = require('util');
+
+var TypedError = require('./typed.js');
+
+var objectToString = Object.prototype.toString;
+var ERROR_TYPE = '[object Error]';
+var causeMessageRegex = /\{causeMessage\}/g;
+var origMessageRegex = /\{origMessage\}/g;
+var hasOwnProperty = Object.prototype.hasOwnProperty;
+
+var FUNCTION_FIELD_WHITELIST = Object.getOwnPropertyNames(WrappedError)
+
+module.exports = WrappedError;
+
+function WrappedError(options) {
+    assert(options, 'WrappedError: must specify options');
+    assert(options.type, 'WrappedError: must specify type');
+    assert(options.message, 'WrappedError: must specify message');
+
+    assert(!has(options, 'cause'),
+        'WrappedError: cause field is reserved');
+    assert(!has(options, 'fullType'),
+        'WrappedError: fullType field is reserved');
+    assert(!has(options, 'causeMessage'),
+        'WrappedError: causeMessage field is reserved');
+    assert(!has(options, 'origMessage'),
+        'WrappedError: origMessage field is reserved');
+
+    var copyArgs = {}
+    extend(copyArgs, options)
+    for (var i = 0; i < FUNCTION_FIELD_WHITELIST.length; i++) {
+        delete copyArgs[FUNCTION_FIELD_WHITELIST[i]]
+    }
+
+    var createTypedError = TypedError(options);
+    extend(createError, copyArgs);
+    createError._name = options.name;
+
+    return createError;
+
+    function createError(cause, opts) {
+        /*eslint max-statements: [2, 25]*/
+        assert(cause, 'an error is required');
+        assert(isError(cause),
+            'WrappedError: first argument must be an error');
+
+        var causeMessage = cause.message;
+        if (causeMessage.indexOf('{causeMessage}') >= 0) {
+            // recover
+            causeMessage = causeMessage.replace(
+                causeMessageRegex,
+                '$INVALID_CAUSE_MESSAGE_LITERAL'
+            );
+        }
+        if (causeMessage.indexOf('{origMessage}') >= 0) {
+            causeMessage = causeMessage.replace(
+                origMessageRegex,
+                '$INVALID_ORIG_MESSAGE_LITERAL'
+            );
+        }
+
+        var nodeCause = false;
+        var errOptions = {}
+        extend(errOptions, opts)
+        extend(errOptions, {
+            causeMessage: causeMessage,
+            origMessage: causeMessage
+        });
+
+        if (has(cause, 'code') && !has(errOptions, 'code')) {
+            errOptions.code = cause.code;
+        }
+
+        if (has(cause, 'errno') && !has(errOptions, 'errno')) {
+            errOptions.errno = cause.errno;
+            nodeCause = true;
+        }
+
+        if (has(cause, 'syscall') && !has(errOptions, 'syscall')) {
+            errOptions.syscall = cause.syscall;
+            nodeCause = true;
+        }
+
+        var causeType = cause.type;
+        if (!causeType && nodeCause) {
+            causeType = 'error.wrapped-io.' +
+                (cause.syscall || 'unknown') + '.' +
+                (cause.errno || 'unknown');
+        } else {
+            causeType = 'error.wrapped-unknown';
+        }
+
+        errOptions.fullType = options.type + '~!~' +
+            (cause.fullType || cause.type || causeType);
+
+        var err = createTypedError(errOptions);
+
+        Object.defineProperty(err, 'cause', {
+            value: cause,
+            configurable: true,
+            enumerable: false
+        });
+        return err;
+    }
+}
+
+function has(obj, key) {
+    return Object.prototype.hasOwnProperty.call(obj, key);
+}
+
+function isError(err) {
+    return util.isError(err) || objectToString.call(err) === ERROR_TYPE;
+}
+
+function extend(target, source) {
+    for (var key in source) {
+        if (hasOwnProperty.call(source, key)) {
+            target[key] = source[key]
+        }
+    }
+}