diff --git a/.gitignore b/.gitignore
index 5c52516b725390e00723198b0b05a8e4c2b0360d..38607d4c434f1c491f4182693e0dd4c6f0a0c1c6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,10 @@
+/.nyc_output
+/.dacap-tmp
+/coverage
+/data
+/lib
 /node_modules
-/dist
 /public
-/data
 /site
-/coverage
+/test
 *.tgz
\ No newline at end of file
diff --git a/.nycrc b/.nycrc
new file mode 100644
index 0000000000000000000000000000000000000000..3a8d9d5914ddcf6592afcb43a37bfe3e5dbff2f3
--- /dev/null
+++ b/.nycrc
@@ -0,0 +1,11 @@
+{
+    "reporter": [
+      "html",
+      "text-summary",
+			"lcovonly"
+    ],
+    "cache": true,
+    "sourceMap": true,
+    "instrument": true
+
+}
\ No newline at end of file
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 440ff2558529aea963d4c893547db23fd003a112..4e98be11fd8de813b8a92e1c34fc1486bba8650f 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -1,6 +1,7 @@
 {
     "version": "0.2.0",
     "configurations": [
+
         {
             "type": "chrome",
             "request": "attach",
diff --git a/bin/dacap b/bin/dacap
index 3365fbde8279c33a638bf9c1fb84a239e56a3aef..851684a6fa4ca09f05435d7477eeb3335612eebb 100755
--- a/bin/dacap
+++ b/bin/dacap
@@ -3,7 +3,7 @@
 const debug = require('debug')('dacap');
 const pjson = require('../package.json');
 const path = require('path');
-const Server = require('../dist/server').Server;
+const Server = require('../lib/server').Server;
 
 const storagePath = process.env.data_dir || path.resolve(process.cwd(), 'data');
 const proxyPath = process.env.proxy_path || '/ep/';
diff --git a/docker-compose.yml b/docker-compose.yml
index 98fb24b7d7b5b32686b3a68c2b7043fd41940f4e..aba8b7a2e485e52c464386009a83fa92322943da 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -5,27 +5,15 @@ services:
     volumes:
       - ./:/app:z
       - npm-cache:/home/dev/.npm:z
-      - app-data:/var/lib/app:z
     ports:
       - 3000:3000
       - 127.0.0.1:9229:9229
-    networks:
-      cache-network:
-        aliases:
-          - api.ub.uni-leipzig.de
     environment:
       - npm_config_registry=https://services.ub.uni-leipzig.de/npm
       - NODE_ENV=development
-      - DEBUG=dacap:*
-      - APP_DATA_DIR=/var/lib/app
-      - APP_TMP_DIR=/tmp
       - DEBUG=*
     command:
       - npm run inspect-watch
-    hostname: api.ub.uni-leipzig.de
 
 volumes:
   npm-cache: {}
-  app-data: {}
-networks:
-  cache-network: {}
diff --git a/package-lock.json b/package-lock.json
index 8cf78e498d240e748bfc129d017c36a10770788a..32f63fd8d1a512dadff812e228a09d8a02cd4c74 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
 {
   "name": "dacap",
-  "version": "1.0.9",
+  "version": "1.0.10",
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
@@ -131,12 +131,28 @@
         "@types/node": "8.0.50"
       }
     },
+    "@types/glob": {
+      "version": "5.0.33",
+      "resolved": "https://services.ub.uni-leipzig.de/npm/@types%2fglob/-/glob-5.0.33.tgz",
+      "integrity": "sha512-BcD4yyWz+qmCggaYMSFF0Xn7GkO6tgwm3Fh9Gxk/kQmEU3Z7flQTnVlMyKBUNvXXNTCCyjqK4XT4/2hLd1gQ2A==",
+      "dev": true,
+      "requires": {
+        "@types/minimatch": "3.0.1",
+        "@types/node": "8.0.50"
+      }
+    },
     "@types/mime": {
       "version": "2.0.0",
       "resolved": "https://services.ub.uni-leipzig.de/npm/@types%2fmime/-/mime-2.0.0.tgz",
       "integrity": "sha512-A2TAGbTFdBw9azHbpVd+/FkdW2T6msN1uct1O9bH3vTerEHKZhTXJUQXy+hNq1B0RagfU8U+KBdqiZpxjhOUQA==",
       "dev": true
     },
+    "@types/minimatch": {
+      "version": "3.0.1",
+      "resolved": "https://services.ub.uni-leipzig.de/npm/@types%2fminimatch/-/minimatch-3.0.1.tgz",
+      "integrity": "sha512-rUO/jz10KRSyA9SHoCWQ8WX9BICyj5jZYu1/ucKEJKb4KzLZCKMURdYbadP157Q6Zl1x0vHsrU+Z/O0XlhYQDw==",
+      "dev": true
+    },
     "@types/mocha": {
       "version": "2.2.44",
       "resolved": "https://services.ub.uni-leipzig.de/npm/@types%2fmocha/-/mocha-2.2.44.tgz",
@@ -168,6 +184,16 @@
         "@types/node": "8.0.50"
       }
     },
+    "@types/rimraf": {
+      "version": "2.0.2",
+      "resolved": "https://services.ub.uni-leipzig.de/npm/@types%2frimraf/-/rimraf-2.0.2.tgz",
+      "integrity": "sha512-Hm/bnWq0TCy7jmjeN5bKYij9vw5GrDFWME4IuxV08278NtU/VdGbzsBohcCUJ7+QMqmUq5hpRKB39HeQWJjztQ==",
+      "dev": true,
+      "requires": {
+        "@types/glob": "5.0.33",
+        "@types/node": "8.0.50"
+      }
+    },
     "@types/serve-static": {
       "version": "1.13.0",
       "resolved": "https://services.ub.uni-leipzig.de/npm/@types%2fserve-static/-/serve-static-1.13.0.tgz",
@@ -986,6 +1012,32 @@
         "source-map": "0.5.7"
       }
     },
+    "cli": {
+      "version": "1.0.1",
+      "resolved": "https://services.ub.uni-leipzig.de/npm/cli/-/cli-1.0.1.tgz",
+      "integrity": "sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ=",
+      "dev": true,
+      "requires": {
+        "exit": "0.1.2",
+        "glob": "7.1.2"
+      },
+      "dependencies": {
+        "glob": {
+          "version": "7.1.2",
+          "resolved": "https://services.ub.uni-leipzig.de/npm/glob/-/glob-7.1.2.tgz",
+          "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+          "dev": true,
+          "requires": {
+            "fs.realpath": "1.0.0",
+            "inflight": "1.0.6",
+            "inherits": "2.0.3",
+            "minimatch": "3.0.4",
+            "once": "1.4.0",
+            "path-is-absolute": "1.0.1"
+          }
+        }
+      }
+    },
     "cliui": {
       "version": "2.1.0",
       "resolved": "https://services.ub.uni-leipzig.de/npm/cliui/-/cliui-2.1.0.tgz",
@@ -1921,6 +1973,12 @@
         "strip-eof": "1.0.0"
       }
     },
+    "exit": {
+      "version": "0.1.2",
+      "resolved": "https://services.ub.uni-leipzig.de/npm/exit/-/exit-0.1.2.tgz",
+      "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
+      "dev": true
+    },
     "expand-brackets": {
       "version": "2.1.4",
       "resolved": "https://services.ub.uni-leipzig.de/npm/expand-brackets/-/expand-brackets-2.1.4.tgz",
@@ -3151,6 +3209,82 @@
       "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
       "dev": true
     },
+    "jshint": {
+      "version": "2.9.5",
+      "resolved": "https://services.ub.uni-leipzig.de/npm/jshint/-/jshint-2.9.5.tgz",
+      "integrity": "sha1-HnJSkVzmgbQIJ+4UJIxG006apiw=",
+      "dev": true,
+      "requires": {
+        "cli": "1.0.1",
+        "console-browserify": "1.1.0",
+        "exit": "0.1.2",
+        "htmlparser2": "3.8.3",
+        "lodash": "3.7.0",
+        "minimatch": "3.0.4",
+        "shelljs": "0.3.0",
+        "strip-json-comments": "1.0.4"
+      },
+      "dependencies": {
+        "domhandler": {
+          "version": "2.3.0",
+          "resolved": "https://services.ub.uni-leipzig.de/npm/domhandler/-/domhandler-2.3.0.tgz",
+          "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=",
+          "dev": true,
+          "requires": {
+            "domelementtype": "1.3.0"
+          }
+        },
+        "entities": {
+          "version": "1.0.0",
+          "resolved": "https://services.ub.uni-leipzig.de/npm/entities/-/entities-1.0.0.tgz",
+          "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=",
+          "dev": true
+        },
+        "htmlparser2": {
+          "version": "3.8.3",
+          "resolved": "https://services.ub.uni-leipzig.de/npm/htmlparser2/-/htmlparser2-3.8.3.tgz",
+          "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=",
+          "dev": true,
+          "requires": {
+            "domelementtype": "1.3.0",
+            "domhandler": "2.3.0",
+            "domutils": "1.5.1",
+            "entities": "1.0.0",
+            "readable-stream": "1.1.14"
+          }
+        },
+        "isarray": {
+          "version": "0.0.1",
+          "resolved": "https://services.ub.uni-leipzig.de/npm/isarray/-/isarray-0.0.1.tgz",
+          "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+          "dev": true
+        },
+        "lodash": {
+          "version": "3.7.0",
+          "resolved": "https://services.ub.uni-leipzig.de/npm/lodash/-/lodash-3.7.0.tgz",
+          "integrity": "sha1-Nni9irmVBXwHreg27S7wh9qBHUU=",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "1.1.14",
+          "resolved": "https://services.ub.uni-leipzig.de/npm/readable-stream/-/readable-stream-1.1.14.tgz",
+          "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+          "dev": true,
+          "requires": {
+            "core-util-is": "1.0.2",
+            "inherits": "2.0.3",
+            "isarray": "0.0.1",
+            "string_decoder": "0.10.31"
+          }
+        },
+        "string_decoder": {
+          "version": "0.10.31",
+          "resolved": "https://services.ub.uni-leipzig.de/npm/string_decoder/-/string_decoder-0.10.31.tgz",
+          "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+          "dev": true
+        }
+      }
+    },
     "json-loader": {
       "version": "0.5.7",
       "resolved": "https://services.ub.uni-leipzig.de/npm/json-loader/-/json-loader-0.5.7.tgz",
@@ -3836,67 +3970,1661 @@
       "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
       "dev": true
     },
-    "oauth-sign": {
-      "version": "0.8.2",
-      "resolved": "https://services.ub.uni-leipzig.de/npm/oauth-sign/-/oauth-sign-0.8.2.tgz",
-      "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM="
-    },
-    "object-assign": {
-      "version": "4.1.1",
-      "resolved": "https://services.ub.uni-leipzig.de/npm/object-assign/-/object-assign-4.1.1.tgz",
-      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
-    },
-    "object-copy": {
-      "version": "0.1.0",
-      "resolved": "https://services.ub.uni-leipzig.de/npm/object-copy/-/object-copy-0.1.0.tgz",
-      "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+    "nyc": {
+      "version": "11.3.0",
+      "resolved": "https://services.ub.uni-leipzig.de/npm/nyc/-/nyc-11.3.0.tgz",
+      "integrity": "sha512-oUu0WHt1k/JMIODvAYXX6C50Mupw2GO34P/Jdg2ty9xrLufBthHiKR2gf08aF+9S0abW1fl24R7iKRBXzibZmg==",
       "dev": true,
       "requires": {
-        "copy-descriptor": "0.1.1",
-        "define-property": "0.2.5",
-        "kind-of": "3.2.2"
+        "archy": "1.0.0",
+        "arrify": "1.0.1",
+        "caching-transform": "1.0.1",
+        "convert-source-map": "1.5.0",
+        "debug-log": "1.0.1",
+        "default-require-extensions": "1.0.0",
+        "find-cache-dir": "0.1.1",
+        "find-up": "2.1.0",
+        "foreground-child": "1.5.6",
+        "glob": "7.1.2",
+        "istanbul-lib-coverage": "1.1.1",
+        "istanbul-lib-hook": "1.1.0",
+        "istanbul-lib-instrument": "1.9.1",
+        "istanbul-lib-report": "1.1.2",
+        "istanbul-lib-source-maps": "1.2.2",
+        "istanbul-reports": "1.1.3",
+        "md5-hex": "1.3.0",
+        "merge-source-map": "1.0.4",
+        "micromatch": "2.3.11",
+        "mkdirp": "0.5.1",
+        "resolve-from": "2.0.0",
+        "rimraf": "2.6.2",
+        "signal-exit": "3.0.2",
+        "spawn-wrap": "1.3.8",
+        "test-exclude": "4.1.1",
+        "yargs": "10.0.3",
+        "yargs-parser": "8.0.0"
       },
       "dependencies": {
-        "define-property": {
-          "version": "0.2.5",
-          "resolved": "https://services.ub.uni-leipzig.de/npm/define-property/-/define-property-0.2.5.tgz",
-          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+        "align-text": {
+          "version": "0.1.4",
+          "bundled": true,
           "dev": true,
           "requires": {
-            "is-descriptor": "0.1.6"
+            "kind-of": "3.2.2",
+            "longest": "1.0.1",
+            "repeat-string": "1.6.1"
           }
         },
-        "is-descriptor": {
-          "version": "0.1.6",
-          "resolved": "https://services.ub.uni-leipzig.de/npm/is-descriptor/-/is-descriptor-0.1.6.tgz",
-          "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+        "amdefine": {
+          "version": "1.0.1",
+          "bundled": true,
+          "dev": true
+        },
+        "ansi-regex": {
+          "version": "2.1.1",
+          "bundled": true,
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "2.2.1",
+          "bundled": true,
+          "dev": true
+        },
+        "append-transform": {
+          "version": "0.4.0",
+          "bundled": true,
           "dev": true,
           "requires": {
-            "is-accessor-descriptor": "0.1.6",
-            "is-data-descriptor": "0.1.4",
-            "kind-of": "5.1.0"
+            "default-require-extensions": "1.0.0"
+          }
+        },
+        "archy": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true
+        },
+        "arr-diff": {
+          "version": "2.0.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "arr-flatten": "1.1.0"
+          }
+        },
+        "arr-flatten": {
+          "version": "1.1.0",
+          "bundled": true,
+          "dev": true
+        },
+        "array-unique": {
+          "version": "0.2.1",
+          "bundled": true,
+          "dev": true
+        },
+        "arrify": {
+          "version": "1.0.1",
+          "bundled": true,
+          "dev": true
+        },
+        "async": {
+          "version": "1.5.2",
+          "bundled": true,
+          "dev": true
+        },
+        "babel-code-frame": {
+          "version": "6.26.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "chalk": "1.1.3",
+            "esutils": "2.0.2",
+            "js-tokens": "3.0.2"
+          }
+        },
+        "babel-generator": {
+          "version": "6.26.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "babel-messages": "6.23.0",
+            "babel-runtime": "6.26.0",
+            "babel-types": "6.26.0",
+            "detect-indent": "4.0.0",
+            "jsesc": "1.3.0",
+            "lodash": "4.17.4",
+            "source-map": "0.5.7",
+            "trim-right": "1.0.1"
+          }
+        },
+        "babel-messages": {
+          "version": "6.23.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "babel-runtime": "6.26.0"
+          }
+        },
+        "babel-runtime": {
+          "version": "6.26.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "core-js": "2.5.1",
+            "regenerator-runtime": "0.11.0"
+          }
+        },
+        "babel-template": {
+          "version": "6.26.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "babel-runtime": "6.26.0",
+            "babel-traverse": "6.26.0",
+            "babel-types": "6.26.0",
+            "babylon": "6.18.0",
+            "lodash": "4.17.4"
+          }
+        },
+        "babel-traverse": {
+          "version": "6.26.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "babel-code-frame": "6.26.0",
+            "babel-messages": "6.23.0",
+            "babel-runtime": "6.26.0",
+            "babel-types": "6.26.0",
+            "babylon": "6.18.0",
+            "debug": "2.6.9",
+            "globals": "9.18.0",
+            "invariant": "2.2.2",
+            "lodash": "4.17.4"
+          }
+        },
+        "babel-types": {
+          "version": "6.26.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "babel-runtime": "6.26.0",
+            "esutils": "2.0.2",
+            "lodash": "4.17.4",
+            "to-fast-properties": "1.0.3"
+          }
+        },
+        "babylon": {
+          "version": "6.18.0",
+          "bundled": true,
+          "dev": true
+        },
+        "balanced-match": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true
+        },
+        "brace-expansion": {
+          "version": "1.1.8",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "balanced-match": "1.0.0",
+            "concat-map": "0.0.1"
+          }
+        },
+        "braces": {
+          "version": "1.8.5",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "expand-range": "1.8.2",
+            "preserve": "0.2.0",
+            "repeat-element": "1.1.2"
+          }
+        },
+        "builtin-modules": {
+          "version": "1.1.1",
+          "bundled": true,
+          "dev": true
+        },
+        "caching-transform": {
+          "version": "1.0.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "md5-hex": "1.3.0",
+            "mkdirp": "0.5.1",
+            "write-file-atomic": "1.3.4"
+          }
+        },
+        "camelcase": {
+          "version": "1.2.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "center-align": {
+          "version": "0.1.3",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "align-text": "0.1.4",
+            "lazy-cache": "1.0.4"
+          }
+        },
+        "chalk": {
+          "version": "1.1.3",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "ansi-styles": "2.2.1",
+            "escape-string-regexp": "1.0.5",
+            "has-ansi": "2.0.0",
+            "strip-ansi": "3.0.1",
+            "supports-color": "2.0.0"
+          }
+        },
+        "cliui": {
+          "version": "2.1.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "center-align": "0.1.3",
+            "right-align": "0.1.3",
+            "wordwrap": "0.0.2"
           },
           "dependencies": {
-            "kind-of": {
-              "version": "5.1.0",
-              "resolved": "https://services.ub.uni-leipzig.de/npm/kind-of/-/kind-of-5.1.0.tgz",
-              "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
-              "dev": true
+            "wordwrap": {
+              "version": "0.0.2",
+              "bundled": true,
+              "dev": true,
+              "optional": true
             }
           }
         },
-        "kind-of": {
-          "version": "3.2.2",
-          "resolved": "https://services.ub.uni-leipzig.de/npm/kind-of/-/kind-of-3.2.2.tgz",
-          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+        "code-point-at": {
+          "version": "1.1.0",
+          "bundled": true,
+          "dev": true
+        },
+        "commondir": {
+          "version": "1.0.1",
+          "bundled": true,
+          "dev": true
+        },
+        "concat-map": {
+          "version": "0.0.1",
+          "bundled": true,
+          "dev": true
+        },
+        "convert-source-map": {
+          "version": "1.5.0",
+          "bundled": true,
+          "dev": true
+        },
+        "core-js": {
+          "version": "2.5.1",
+          "bundled": true,
+          "dev": true
+        },
+        "cross-spawn": {
+          "version": "4.0.2",
+          "bundled": true,
           "dev": true,
           "requires": {
-            "is-buffer": "1.1.6"
+            "lru-cache": "4.1.1",
+            "which": "1.3.0"
           }
-        }
-      }
-    },
-    "object-visit": {
+        },
+        "debug": {
+          "version": "2.6.9",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "debug-log": {
+          "version": "1.0.1",
+          "bundled": true,
+          "dev": true
+        },
+        "decamelize": {
+          "version": "1.2.0",
+          "bundled": true,
+          "dev": true
+        },
+        "default-require-extensions": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "strip-bom": "2.0.0"
+          }
+        },
+        "detect-indent": {
+          "version": "4.0.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "repeating": "2.0.1"
+          }
+        },
+        "error-ex": {
+          "version": "1.3.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "is-arrayish": "0.2.1"
+          }
+        },
+        "escape-string-regexp": {
+          "version": "1.0.5",
+          "bundled": true,
+          "dev": true
+        },
+        "esutils": {
+          "version": "2.0.2",
+          "bundled": true,
+          "dev": true
+        },
+        "execa": {
+          "version": "0.7.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "cross-spawn": "5.1.0",
+            "get-stream": "3.0.0",
+            "is-stream": "1.1.0",
+            "npm-run-path": "2.0.2",
+            "p-finally": "1.0.0",
+            "signal-exit": "3.0.2",
+            "strip-eof": "1.0.0"
+          },
+          "dependencies": {
+            "cross-spawn": {
+              "version": "5.1.0",
+              "bundled": true,
+              "dev": true,
+              "requires": {
+                "lru-cache": "4.1.1",
+                "shebang-command": "1.2.0",
+                "which": "1.3.0"
+              }
+            }
+          }
+        },
+        "expand-brackets": {
+          "version": "0.1.5",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "is-posix-bracket": "0.1.1"
+          }
+        },
+        "expand-range": {
+          "version": "1.8.2",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "fill-range": "2.2.3"
+          }
+        },
+        "extglob": {
+          "version": "0.3.2",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "is-extglob": "1.0.0"
+          }
+        },
+        "filename-regex": {
+          "version": "2.0.1",
+          "bundled": true,
+          "dev": true
+        },
+        "fill-range": {
+          "version": "2.2.3",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "is-number": "2.1.0",
+            "isobject": "2.1.0",
+            "randomatic": "1.1.7",
+            "repeat-element": "1.1.2",
+            "repeat-string": "1.6.1"
+          }
+        },
+        "find-cache-dir": {
+          "version": "0.1.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "commondir": "1.0.1",
+            "mkdirp": "0.5.1",
+            "pkg-dir": "1.0.0"
+          }
+        },
+        "find-up": {
+          "version": "2.1.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "locate-path": "2.0.0"
+          }
+        },
+        "for-in": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true
+        },
+        "for-own": {
+          "version": "0.1.5",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "for-in": "1.0.2"
+          }
+        },
+        "foreground-child": {
+          "version": "1.5.6",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "cross-spawn": "4.0.2",
+            "signal-exit": "3.0.2"
+          }
+        },
+        "fs.realpath": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true
+        },
+        "get-caller-file": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true
+        },
+        "get-stream": {
+          "version": "3.0.0",
+          "bundled": true,
+          "dev": true
+        },
+        "glob": {
+          "version": "7.1.2",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "fs.realpath": "1.0.0",
+            "inflight": "1.0.6",
+            "inherits": "2.0.3",
+            "minimatch": "3.0.4",
+            "once": "1.4.0",
+            "path-is-absolute": "1.0.1"
+          }
+        },
+        "glob-base": {
+          "version": "0.3.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "glob-parent": "2.0.0",
+            "is-glob": "2.0.1"
+          }
+        },
+        "glob-parent": {
+          "version": "2.0.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "is-glob": "2.0.1"
+          }
+        },
+        "globals": {
+          "version": "9.18.0",
+          "bundled": true,
+          "dev": true
+        },
+        "graceful-fs": {
+          "version": "4.1.11",
+          "bundled": true,
+          "dev": true
+        },
+        "handlebars": {
+          "version": "4.0.11",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "async": "1.5.2",
+            "optimist": "0.6.1",
+            "source-map": "0.4.4",
+            "uglify-js": "2.8.29"
+          },
+          "dependencies": {
+            "source-map": {
+              "version": "0.4.4",
+              "bundled": true,
+              "dev": true,
+              "requires": {
+                "amdefine": "1.0.1"
+              }
+            }
+          }
+        },
+        "has-ansi": {
+          "version": "2.0.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "ansi-regex": "2.1.1"
+          }
+        },
+        "has-flag": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true
+        },
+        "hosted-git-info": {
+          "version": "2.5.0",
+          "bundled": true,
+          "dev": true
+        },
+        "imurmurhash": {
+          "version": "0.1.4",
+          "bundled": true,
+          "dev": true
+        },
+        "inflight": {
+          "version": "1.0.6",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "once": "1.4.0",
+            "wrappy": "1.0.2"
+          }
+        },
+        "inherits": {
+          "version": "2.0.3",
+          "bundled": true,
+          "dev": true
+        },
+        "invariant": {
+          "version": "2.2.2",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "loose-envify": "1.3.1"
+          }
+        },
+        "invert-kv": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true
+        },
+        "is-arrayish": {
+          "version": "0.2.1",
+          "bundled": true,
+          "dev": true
+        },
+        "is-buffer": {
+          "version": "1.1.5",
+          "bundled": true,
+          "dev": true
+        },
+        "is-builtin-module": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "builtin-modules": "1.1.1"
+          }
+        },
+        "is-dotfile": {
+          "version": "1.0.3",
+          "bundled": true,
+          "dev": true
+        },
+        "is-equal-shallow": {
+          "version": "0.1.3",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "is-primitive": "2.0.0"
+          }
+        },
+        "is-extendable": {
+          "version": "0.1.1",
+          "bundled": true,
+          "dev": true
+        },
+        "is-extglob": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true
+        },
+        "is-finite": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "number-is-nan": "1.0.1"
+          }
+        },
+        "is-fullwidth-code-point": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "number-is-nan": "1.0.1"
+          }
+        },
+        "is-glob": {
+          "version": "2.0.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "is-extglob": "1.0.0"
+          }
+        },
+        "is-number": {
+          "version": "2.1.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "kind-of": "3.2.2"
+          }
+        },
+        "is-posix-bracket": {
+          "version": "0.1.1",
+          "bundled": true,
+          "dev": true
+        },
+        "is-primitive": {
+          "version": "2.0.0",
+          "bundled": true,
+          "dev": true
+        },
+        "is-stream": {
+          "version": "1.1.0",
+          "bundled": true,
+          "dev": true
+        },
+        "is-utf8": {
+          "version": "0.2.1",
+          "bundled": true,
+          "dev": true
+        },
+        "isarray": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true
+        },
+        "isexe": {
+          "version": "2.0.0",
+          "bundled": true,
+          "dev": true
+        },
+        "isobject": {
+          "version": "2.1.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "isarray": "1.0.0"
+          }
+        },
+        "istanbul-lib-coverage": {
+          "version": "1.1.1",
+          "bundled": true,
+          "dev": true
+        },
+        "istanbul-lib-hook": {
+          "version": "1.1.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "append-transform": "0.4.0"
+          }
+        },
+        "istanbul-lib-instrument": {
+          "version": "1.9.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "babel-generator": "6.26.0",
+            "babel-template": "6.26.0",
+            "babel-traverse": "6.26.0",
+            "babel-types": "6.26.0",
+            "babylon": "6.18.0",
+            "istanbul-lib-coverage": "1.1.1",
+            "semver": "5.4.1"
+          }
+        },
+        "istanbul-lib-report": {
+          "version": "1.1.2",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "istanbul-lib-coverage": "1.1.1",
+            "mkdirp": "0.5.1",
+            "path-parse": "1.0.5",
+            "supports-color": "3.2.3"
+          },
+          "dependencies": {
+            "supports-color": {
+              "version": "3.2.3",
+              "bundled": true,
+              "dev": true,
+              "requires": {
+                "has-flag": "1.0.0"
+              }
+            }
+          }
+        },
+        "istanbul-lib-source-maps": {
+          "version": "1.2.2",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "debug": "3.1.0",
+            "istanbul-lib-coverage": "1.1.1",
+            "mkdirp": "0.5.1",
+            "rimraf": "2.6.2",
+            "source-map": "0.5.7"
+          },
+          "dependencies": {
+            "debug": {
+              "version": "3.1.0",
+              "bundled": true,
+              "dev": true,
+              "requires": {
+                "ms": "2.0.0"
+              }
+            }
+          }
+        },
+        "istanbul-reports": {
+          "version": "1.1.3",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "handlebars": "4.0.11"
+          }
+        },
+        "js-tokens": {
+          "version": "3.0.2",
+          "bundled": true,
+          "dev": true
+        },
+        "jsesc": {
+          "version": "1.3.0",
+          "bundled": true,
+          "dev": true
+        },
+        "kind-of": {
+          "version": "3.2.2",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "is-buffer": "1.1.5"
+          }
+        },
+        "lazy-cache": {
+          "version": "1.0.4",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "lcid": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "invert-kv": "1.0.0"
+          }
+        },
+        "load-json-file": {
+          "version": "1.1.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "graceful-fs": "4.1.11",
+            "parse-json": "2.2.0",
+            "pify": "2.3.0",
+            "pinkie-promise": "2.0.1",
+            "strip-bom": "2.0.0"
+          }
+        },
+        "locate-path": {
+          "version": "2.0.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "p-locate": "2.0.0",
+            "path-exists": "3.0.0"
+          },
+          "dependencies": {
+            "path-exists": {
+              "version": "3.0.0",
+              "bundled": true,
+              "dev": true
+            }
+          }
+        },
+        "lodash": {
+          "version": "4.17.4",
+          "bundled": true,
+          "dev": true
+        },
+        "longest": {
+          "version": "1.0.1",
+          "bundled": true,
+          "dev": true
+        },
+        "loose-envify": {
+          "version": "1.3.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "js-tokens": "3.0.2"
+          }
+        },
+        "lru-cache": {
+          "version": "4.1.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "pseudomap": "1.0.2",
+            "yallist": "2.1.2"
+          }
+        },
+        "md5-hex": {
+          "version": "1.3.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "md5-o-matic": "0.1.1"
+          }
+        },
+        "md5-o-matic": {
+          "version": "0.1.1",
+          "bundled": true,
+          "dev": true
+        },
+        "mem": {
+          "version": "1.1.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "mimic-fn": "1.1.0"
+          }
+        },
+        "merge-source-map": {
+          "version": "1.0.4",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "source-map": "0.5.7"
+          }
+        },
+        "micromatch": {
+          "version": "2.3.11",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "arr-diff": "2.0.0",
+            "array-unique": "0.2.1",
+            "braces": "1.8.5",
+            "expand-brackets": "0.1.5",
+            "extglob": "0.3.2",
+            "filename-regex": "2.0.1",
+            "is-extglob": "1.0.0",
+            "is-glob": "2.0.1",
+            "kind-of": "3.2.2",
+            "normalize-path": "2.1.1",
+            "object.omit": "2.0.1",
+            "parse-glob": "3.0.4",
+            "regex-cache": "0.4.4"
+          }
+        },
+        "mimic-fn": {
+          "version": "1.1.0",
+          "bundled": true,
+          "dev": true
+        },
+        "minimatch": {
+          "version": "3.0.4",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "brace-expansion": "1.1.8"
+          }
+        },
+        "minimist": {
+          "version": "0.0.8",
+          "bundled": true,
+          "dev": true
+        },
+        "mkdirp": {
+          "version": "0.5.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "minimist": "0.0.8"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "bundled": true,
+          "dev": true
+        },
+        "normalize-package-data": {
+          "version": "2.4.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "hosted-git-info": "2.5.0",
+            "is-builtin-module": "1.0.0",
+            "semver": "5.4.1",
+            "validate-npm-package-license": "3.0.1"
+          }
+        },
+        "normalize-path": {
+          "version": "2.1.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "remove-trailing-separator": "1.1.0"
+          }
+        },
+        "npm-run-path": {
+          "version": "2.0.2",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "path-key": "2.0.1"
+          }
+        },
+        "number-is-nan": {
+          "version": "1.0.1",
+          "bundled": true,
+          "dev": true
+        },
+        "object-assign": {
+          "version": "4.1.1",
+          "bundled": true,
+          "dev": true
+        },
+        "object.omit": {
+          "version": "2.0.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "for-own": "0.1.5",
+            "is-extendable": "0.1.1"
+          }
+        },
+        "once": {
+          "version": "1.4.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "wrappy": "1.0.2"
+          }
+        },
+        "optimist": {
+          "version": "0.6.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "minimist": "0.0.8",
+            "wordwrap": "0.0.3"
+          }
+        },
+        "os-homedir": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true
+        },
+        "os-locale": {
+          "version": "2.1.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "execa": "0.7.0",
+            "lcid": "1.0.0",
+            "mem": "1.1.0"
+          }
+        },
+        "p-finally": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true
+        },
+        "p-limit": {
+          "version": "1.1.0",
+          "bundled": true,
+          "dev": true
+        },
+        "p-locate": {
+          "version": "2.0.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "p-limit": "1.1.0"
+          }
+        },
+        "parse-glob": {
+          "version": "3.0.4",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "glob-base": "0.3.0",
+            "is-dotfile": "1.0.3",
+            "is-extglob": "1.0.0",
+            "is-glob": "2.0.1"
+          }
+        },
+        "parse-json": {
+          "version": "2.2.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "error-ex": "1.3.1"
+          }
+        },
+        "path-exists": {
+          "version": "2.1.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "pinkie-promise": "2.0.1"
+          }
+        },
+        "path-is-absolute": {
+          "version": "1.0.1",
+          "bundled": true,
+          "dev": true
+        },
+        "path-key": {
+          "version": "2.0.1",
+          "bundled": true,
+          "dev": true
+        },
+        "path-parse": {
+          "version": "1.0.5",
+          "bundled": true,
+          "dev": true
+        },
+        "path-type": {
+          "version": "1.1.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "graceful-fs": "4.1.11",
+            "pify": "2.3.0",
+            "pinkie-promise": "2.0.1"
+          }
+        },
+        "pify": {
+          "version": "2.3.0",
+          "bundled": true,
+          "dev": true
+        },
+        "pinkie": {
+          "version": "2.0.4",
+          "bundled": true,
+          "dev": true
+        },
+        "pinkie-promise": {
+          "version": "2.0.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "pinkie": "2.0.4"
+          }
+        },
+        "pkg-dir": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "find-up": "1.1.2"
+          },
+          "dependencies": {
+            "find-up": {
+              "version": "1.1.2",
+              "bundled": true,
+              "dev": true,
+              "requires": {
+                "path-exists": "2.1.0",
+                "pinkie-promise": "2.0.1"
+              }
+            }
+          }
+        },
+        "preserve": {
+          "version": "0.2.0",
+          "bundled": true,
+          "dev": true
+        },
+        "pseudomap": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true
+        },
+        "randomatic": {
+          "version": "1.1.7",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "is-number": "3.0.0",
+            "kind-of": "4.0.0"
+          },
+          "dependencies": {
+            "is-number": {
+              "version": "3.0.0",
+              "bundled": true,
+              "dev": true,
+              "requires": {
+                "kind-of": "3.2.2"
+              },
+              "dependencies": {
+                "kind-of": {
+                  "version": "3.2.2",
+                  "bundled": true,
+                  "dev": true,
+                  "requires": {
+                    "is-buffer": "1.1.5"
+                  }
+                }
+              }
+            },
+            "kind-of": {
+              "version": "4.0.0",
+              "bundled": true,
+              "dev": true,
+              "requires": {
+                "is-buffer": "1.1.5"
+              }
+            }
+          }
+        },
+        "read-pkg": {
+          "version": "1.1.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "load-json-file": "1.1.0",
+            "normalize-package-data": "2.4.0",
+            "path-type": "1.1.0"
+          }
+        },
+        "read-pkg-up": {
+          "version": "1.0.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "find-up": "1.1.2",
+            "read-pkg": "1.1.0"
+          },
+          "dependencies": {
+            "find-up": {
+              "version": "1.1.2",
+              "bundled": true,
+              "dev": true,
+              "requires": {
+                "path-exists": "2.1.0",
+                "pinkie-promise": "2.0.1"
+              }
+            }
+          }
+        },
+        "regenerator-runtime": {
+          "version": "0.11.0",
+          "bundled": true,
+          "dev": true
+        },
+        "regex-cache": {
+          "version": "0.4.4",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "is-equal-shallow": "0.1.3"
+          }
+        },
+        "remove-trailing-separator": {
+          "version": "1.1.0",
+          "bundled": true,
+          "dev": true
+        },
+        "repeat-element": {
+          "version": "1.1.2",
+          "bundled": true,
+          "dev": true
+        },
+        "repeat-string": {
+          "version": "1.6.1",
+          "bundled": true,
+          "dev": true
+        },
+        "repeating": {
+          "version": "2.0.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "is-finite": "1.0.2"
+          }
+        },
+        "require-directory": {
+          "version": "2.1.1",
+          "bundled": true,
+          "dev": true
+        },
+        "require-main-filename": {
+          "version": "1.0.1",
+          "bundled": true,
+          "dev": true
+        },
+        "resolve-from": {
+          "version": "2.0.0",
+          "bundled": true,
+          "dev": true
+        },
+        "right-align": {
+          "version": "0.1.3",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "align-text": "0.1.4"
+          }
+        },
+        "rimraf": {
+          "version": "2.6.2",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "glob": "7.1.2"
+          }
+        },
+        "semver": {
+          "version": "5.4.1",
+          "bundled": true,
+          "dev": true
+        },
+        "set-blocking": {
+          "version": "2.0.0",
+          "bundled": true,
+          "dev": true
+        },
+        "shebang-command": {
+          "version": "1.2.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "shebang-regex": "1.0.0"
+          }
+        },
+        "shebang-regex": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true
+        },
+        "signal-exit": {
+          "version": "3.0.2",
+          "bundled": true,
+          "dev": true
+        },
+        "slide": {
+          "version": "1.1.6",
+          "bundled": true,
+          "dev": true
+        },
+        "source-map": {
+          "version": "0.5.7",
+          "bundled": true,
+          "dev": true
+        },
+        "spawn-wrap": {
+          "version": "1.3.8",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "foreground-child": "1.5.6",
+            "mkdirp": "0.5.1",
+            "os-homedir": "1.0.2",
+            "rimraf": "2.6.2",
+            "signal-exit": "3.0.2",
+            "which": "1.3.0"
+          }
+        },
+        "spdx-correct": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "spdx-license-ids": "1.2.2"
+          }
+        },
+        "spdx-expression-parse": {
+          "version": "1.0.4",
+          "bundled": true,
+          "dev": true
+        },
+        "spdx-license-ids": {
+          "version": "1.2.2",
+          "bundled": true,
+          "dev": true
+        },
+        "string-width": {
+          "version": "2.1.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "is-fullwidth-code-point": "2.0.0",
+            "strip-ansi": "4.0.0"
+          },
+          "dependencies": {
+            "ansi-regex": {
+              "version": "3.0.0",
+              "bundled": true,
+              "dev": true
+            },
+            "is-fullwidth-code-point": {
+              "version": "2.0.0",
+              "bundled": true,
+              "dev": true
+            },
+            "strip-ansi": {
+              "version": "4.0.0",
+              "bundled": true,
+              "dev": true,
+              "requires": {
+                "ansi-regex": "3.0.0"
+              }
+            }
+          }
+        },
+        "strip-ansi": {
+          "version": "3.0.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "ansi-regex": "2.1.1"
+          }
+        },
+        "strip-bom": {
+          "version": "2.0.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "is-utf8": "0.2.1"
+          }
+        },
+        "strip-eof": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true
+        },
+        "supports-color": {
+          "version": "2.0.0",
+          "bundled": true,
+          "dev": true
+        },
+        "test-exclude": {
+          "version": "4.1.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "arrify": "1.0.1",
+            "micromatch": "2.3.11",
+            "object-assign": "4.1.1",
+            "read-pkg-up": "1.0.1",
+            "require-main-filename": "1.0.1"
+          }
+        },
+        "to-fast-properties": {
+          "version": "1.0.3",
+          "bundled": true,
+          "dev": true
+        },
+        "trim-right": {
+          "version": "1.0.1",
+          "bundled": true,
+          "dev": true
+        },
+        "uglify-js": {
+          "version": "2.8.29",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "source-map": "0.5.7",
+            "uglify-to-browserify": "1.0.2",
+            "yargs": "3.10.0"
+          },
+          "dependencies": {
+            "yargs": {
+              "version": "3.10.0",
+              "bundled": true,
+              "dev": true,
+              "optional": true,
+              "requires": {
+                "camelcase": "1.2.1",
+                "cliui": "2.1.0",
+                "decamelize": "1.2.0",
+                "window-size": "0.1.0"
+              }
+            }
+          }
+        },
+        "uglify-to-browserify": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "validate-npm-package-license": {
+          "version": "3.0.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "spdx-correct": "1.0.2",
+            "spdx-expression-parse": "1.0.4"
+          }
+        },
+        "which": {
+          "version": "1.3.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "isexe": "2.0.0"
+          }
+        },
+        "which-module": {
+          "version": "2.0.0",
+          "bundled": true,
+          "dev": true
+        },
+        "window-size": {
+          "version": "0.1.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "wordwrap": {
+          "version": "0.0.3",
+          "bundled": true,
+          "dev": true
+        },
+        "wrap-ansi": {
+          "version": "2.1.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "string-width": "1.0.2",
+            "strip-ansi": "3.0.1"
+          },
+          "dependencies": {
+            "string-width": {
+              "version": "1.0.2",
+              "bundled": true,
+              "dev": true,
+              "requires": {
+                "code-point-at": "1.1.0",
+                "is-fullwidth-code-point": "1.0.0",
+                "strip-ansi": "3.0.1"
+              }
+            }
+          }
+        },
+        "wrappy": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true
+        },
+        "write-file-atomic": {
+          "version": "1.3.4",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "graceful-fs": "4.1.11",
+            "imurmurhash": "0.1.4",
+            "slide": "1.1.6"
+          }
+        },
+        "y18n": {
+          "version": "3.2.1",
+          "bundled": true,
+          "dev": true
+        },
+        "yallist": {
+          "version": "2.1.2",
+          "bundled": true,
+          "dev": true
+        },
+        "yargs": {
+          "version": "10.0.3",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "cliui": "3.2.0",
+            "decamelize": "1.2.0",
+            "find-up": "2.1.0",
+            "get-caller-file": "1.0.2",
+            "os-locale": "2.1.0",
+            "require-directory": "2.1.1",
+            "require-main-filename": "1.0.1",
+            "set-blocking": "2.0.0",
+            "string-width": "2.1.1",
+            "which-module": "2.0.0",
+            "y18n": "3.2.1",
+            "yargs-parser": "8.0.0"
+          },
+          "dependencies": {
+            "cliui": {
+              "version": "3.2.0",
+              "bundled": true,
+              "dev": true,
+              "requires": {
+                "string-width": "1.0.2",
+                "strip-ansi": "3.0.1",
+                "wrap-ansi": "2.1.0"
+              },
+              "dependencies": {
+                "string-width": {
+                  "version": "1.0.2",
+                  "bundled": true,
+                  "dev": true,
+                  "requires": {
+                    "code-point-at": "1.1.0",
+                    "is-fullwidth-code-point": "1.0.0",
+                    "strip-ansi": "3.0.1"
+                  }
+                }
+              }
+            }
+          }
+        },
+        "yargs-parser": {
+          "version": "8.0.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "camelcase": "4.1.0"
+          },
+          "dependencies": {
+            "camelcase": {
+              "version": "4.1.0",
+              "bundled": true,
+              "dev": true
+            }
+          }
+        }
+      }
+    },
+    "oauth-sign": {
+      "version": "0.8.2",
+      "resolved": "https://services.ub.uni-leipzig.de/npm/oauth-sign/-/oauth-sign-0.8.2.tgz",
+      "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM="
+    },
+    "object-assign": {
+      "version": "4.1.1",
+      "resolved": "https://services.ub.uni-leipzig.de/npm/object-assign/-/object-assign-4.1.1.tgz",
+      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
+    },
+    "object-copy": {
+      "version": "0.1.0",
+      "resolved": "https://services.ub.uni-leipzig.de/npm/object-copy/-/object-copy-0.1.0.tgz",
+      "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+      "dev": true,
+      "requires": {
+        "copy-descriptor": "0.1.1",
+        "define-property": "0.2.5",
+        "kind-of": "3.2.2"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://services.ub.uni-leipzig.de/npm/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "0.1.6"
+          }
+        },
+        "is-descriptor": {
+          "version": "0.1.6",
+          "resolved": "https://services.ub.uni-leipzig.de/npm/is-descriptor/-/is-descriptor-0.1.6.tgz",
+          "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "0.1.6",
+            "is-data-descriptor": "0.1.4",
+            "kind-of": "5.1.0"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "5.1.0",
+              "resolved": "https://services.ub.uni-leipzig.de/npm/kind-of/-/kind-of-5.1.0.tgz",
+              "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+              "dev": true
+            }
+          }
+        },
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://services.ub.uni-leipzig.de/npm/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "1.1.6"
+          }
+        }
+      }
+    },
+    "object-visit": {
       "version": "1.0.1",
       "resolved": "https://services.ub.uni-leipzig.de/npm/object-visit/-/object-visit-1.0.1.tgz",
       "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
@@ -5148,6 +6876,31 @@
         "align-text": "0.1.4"
       }
     },
+    "rimraf": {
+      "version": "2.6.2",
+      "resolved": "https://services.ub.uni-leipzig.de/npm/rimraf/-/rimraf-2.6.2.tgz",
+      "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
+      "dev": true,
+      "requires": {
+        "glob": "7.1.2"
+      },
+      "dependencies": {
+        "glob": {
+          "version": "7.1.2",
+          "resolved": "https://services.ub.uni-leipzig.de/npm/glob/-/glob-7.1.2.tgz",
+          "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+          "dev": true,
+          "requires": {
+            "fs.realpath": "1.0.0",
+            "inflight": "1.0.6",
+            "inherits": "2.0.3",
+            "minimatch": "3.0.4",
+            "once": "1.4.0",
+            "path-is-absolute": "1.0.1"
+          }
+        }
+      }
+    },
     "ripemd160": {
       "version": "2.0.1",
       "resolved": "https://services.ub.uni-leipzig.de/npm/ripemd160/-/ripemd160-2.0.1.tgz",
@@ -5307,6 +7060,12 @@
       "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
       "dev": true
     },
+    "shelljs": {
+      "version": "0.3.0",
+      "resolved": "https://services.ub.uni-leipzig.de/npm/shelljs/-/shelljs-0.3.0.tgz",
+      "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=",
+      "dev": true
+    },
     "should": {
       "version": "11.2.1",
       "resolved": "https://services.ub.uni-leipzig.de/npm/should/-/should-11.2.1.tgz",
@@ -5736,6 +7495,12 @@
       "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
       "dev": true
     },
+    "strip-json-comments": {
+      "version": "1.0.4",
+      "resolved": "https://services.ub.uni-leipzig.de/npm/strip-json-comments/-/strip-json-comments-1.0.4.tgz",
+      "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=",
+      "dev": true
+    },
     "style-loader": {
       "version": "0.18.2",
       "resolved": "https://services.ub.uni-leipzig.de/npm/style-loader/-/style-loader-0.18.2.tgz",
@@ -5797,6 +7562,12 @@
       "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
       "dev": true
     },
+    "time-stamp": {
+      "version": "2.0.0",
+      "resolved": "https://services.ub.uni-leipzig.de/npm/time-stamp/-/time-stamp-2.0.0.tgz",
+      "integrity": "sha1-lcakRTDhW6jW9KPsuMOj+sRto1c=",
+      "dev": true
+    },
     "timers-browserify": {
       "version": "2.0.4",
       "resolved": "https://services.ub.uni-leipzig.de/npm/timers-browserify/-/timers-browserify-2.0.4.tgz",
@@ -6465,6 +8236,19 @@
         }
       }
     },
+    "webpack-dev-middleware": {
+      "version": "1.12.0",
+      "resolved": "https://services.ub.uni-leipzig.de/npm/webpack-dev-middleware/-/webpack-dev-middleware-1.12.0.tgz",
+      "integrity": "sha1-007++y7dp+HTtdvgcolRMhllFwk=",
+      "dev": true,
+      "requires": {
+        "memory-fs": "0.4.1",
+        "mime": "1.4.1",
+        "path-is-absolute": "1.0.1",
+        "range-parser": "1.2.0",
+        "time-stamp": "2.0.0"
+      }
+    },
     "webpack-merge": {
       "version": "4.1.1",
       "resolved": "https://services.ub.uni-leipzig.de/npm/webpack-merge/-/webpack-merge-4.1.1.tgz",
diff --git a/package.json b/package.json
index 2d73a0ecea27f9d866153ffe81f74207946dc7af..a95882ff3df5e944aba45727160fbc45b41a321b 100644
--- a/package.json
+++ b/package.json
@@ -10,14 +10,16 @@
     "test": "test"
   },
   "scripts": {
-    "webpack-watch": "webpack --config webpack.dev.js --watch",
     "start": "node bin/dacap",
     "tsc": "tsc",
-    "inspect-watch": "tsc-watch --onSuccess 'node --inspect=0.0.0.0:9229 bin/dacap'",
-    "inspect-brk-watch": "tsc-watch --onSuccess 'node --inspect-brk=0.0.0.0:9229 bin/dacap'",
+    "inspect-watch": "tsc-watch --sourceMap --onSuccess 'node --inspect=0.0.0.0:9229 bin/dacap'",
+    "inspect-brk-watch": "tsc-watch --sourceMap --onSuccess 'node --inspect-brk=0.0.0.0:9229 bin/dacap'",
     "test": "mocha",
-    "ci": "istanbul cover _mocha -- --timeout 10000",
-    "build": "rm -rf dist public && tsc --declaration && webpack --config webpack.prod.js"
+    "test-inspect": "mocha --inspect-brk=0.0.0.0:9229",
+    "test-watch": "tsc-watch --sourceMap --onSuccess 'nyc mocha'",
+    "ci": "nyc mocha --timeout=10000",
+    "build": "rm -rf lib test public && tsc --declaration && webpack --config webpack.prod.js",
+    "nyc": "nyc"
   },
   "author": "Ulf Seltmann <ulf.seltmann@uni-leipzig.de>",
   "license": "GPL-2.0",
@@ -50,9 +52,11 @@
     "@types/debug": "0.0.30",
     "@types/express": "^4.0.37",
     "@types/mocha": "^2.2.42",
+    "@types/nock": "^8.2.1",
     "@types/node": "^8.0.25",
     "@types/node-cache": "^4.1.0",
     "@types/request": "^2.0.3",
+    "@types/rimraf": "^2.0.2",
     "@types/should": "^11.2.0",
     "angular2-template-loader": "^0.6.2",
     "awesome-typescript-loader": "^3.2.3",
@@ -64,8 +68,12 @@
     "html-webpack-plugin": "^2.30.1",
     "istanbul": "^0.4.5",
     "jquery": "^3.2.1",
+    "jshint": "^2.9.5",
     "mocha": "^3.5.0",
     "mocha-jenkins-reporter": "^0.3.9",
+    "nock": "^9.1.0",
+    "nyc": "^11.3.0",
+    "rimraf": "^2.6.2",
     "should": "^11.2.1",
     "source-map-loader": "^0.2.1",
     "style-loader": "^0.18.2",
@@ -73,6 +81,7 @@
     "tslint": "^5.7.0",
     "typescript": "^2.5.1",
     "webpack": "^3.5.5",
+    "webpack-dev-middleware": "^1.12.0",
     "webpack-merge": "^4.1.0"
   }
 }
diff --git a/src/cache.ts b/src/cache.ts
deleted file mode 100644
index a04727ec0ea1d2328d11728fa19252f2ac88d778..0000000000000000000000000000000000000000
--- a/src/cache.ts
+++ /dev/null
@@ -1,271 +0,0 @@
-import * as debugFactory from 'debug';
-import * as express from 'express';
-import * as NodeCache from 'node-cache';
-import * as crypto from 'crypto';
-import * as fs from 'fs';
-import * as path from 'path';
-import * as Q from 'q';
-
-import { Endpoint, EndpointValue } from './endpoint';
-
-const debug = debugFactory('dacap:cache');
-
-export interface MiddlewareFunction {
-	(req: express.Request, res: express.Response, next: express.NextFunction): Promise<void>
-}
-
-export interface RegisterObject {
-	name: string
-	data: CacheObject
-}
-export interface CacheObject {
-	endPoint: string,
-	cacheOptions: NodeCache.Options,
-	cache: [
-		{
-			hash: string,
-			value: any
-		}
-	]
-}
-
-export interface CacheDetails {
-	hash: string,
-	uriPath: string,
-	contentType: string,
-	ttl: number,
-	size: number
-}
-
-export interface CacheInfo {
-	name: string,
-	apiEndPoint: string,
-	cacheOptions: NodeCache.Options,
-	cacheStats: NodeCache.Stats,
-	cache: CacheDetails[],
-}
-
-export function Middleware(register: Register): MiddlewareFunction {
-
-	return async function (req: express.Request, res: express.Response, next: express.NextFunction): Promise<void> {
-		const pattern = new RegExp('^/([^/]+)/?(.*)$');
-		const match = req.url.match(pattern);
-		try {
-			const cache = register.get(match[1]);
-			const uniQueryString = Object.keys(req.query).sort().map(function (key) { return `${key}=${req.query[key]}` }).join('&');
-			const hash = crypto.createHash('sha1').update(req.path + uniQueryString).digest('hex');
-			debug(`finding cache-entry for ${hash}`);
-			const value = await cache.get(hash, match[2]);
-			res.setHeader('content-type', value.contentType)
-			res.send(value.data);
-		} catch (err) {
-			res.status(404).send(err.message);
-		}
-	}
-}
-
-/**
- * the cache register
- *
- * @export
- * @class Register
- */
-export class Register {
-	cacheRegister: { [key: string]: Cache } = {};
-
-	constructor(private storage: string, public name: string) {
-		fs.existsSync(storage) || fs.mkdirSync(storage);
-	}
-
-	has = (name: string): boolean => {
-		return !!this.cacheRegister[name];
-	}
-	/**
-	 * gets register by its name
-	 *
-	 * @memberof Register
-	 */
-	get = (name: string): Cache => {
-		if (!this.has(name)) throw new Error(`register not found: ${name}`);
-		return this.cacheRegister[name];
-	}
-
-	/**
-	 * adds API-Endpoint to cache-register
-	 *
-	 * @memberof Register
-	 */
-	add = (name: string, serverUrl: string, cacheOptions: NodeCache.Options) => {
-		const endpoint: Endpoint = new Endpoint(serverUrl);
-		const nodeCache: NodeCache = new NodeCache(cacheOptions)
-		this.cacheRegister[name] = new Cache(endpoint, nodeCache);
-	}
-
-	delete(name: string) {
-		if (!this.has(name)) throw new Error(`register not found: ${name}`);
-		delete this.cacheRegister[name];
-	}
-
-	getInfo = (name?: string): CacheInfo|CacheInfo[] => {
-		return (name) ? this._getInfo(name) : Object.keys(this.cacheRegister).map((key): CacheInfo => {
-			return this._getInfo(key);
-		});
-	}
-
-	private _getInfo(name: string): CacheInfo {
-		return {
-			name: name,
-			apiEndPoint: this.cacheRegister[name].getEndpoint().toString(),
-			cacheOptions: this.cacheRegister[name].getCache().options,
-			cacheStats: this.cacheRegister[name].getCache().getStats(),
-			cache: <CacheDetails[]>this.cacheRegister[name].getDetails()
-		}
-	}
-
-	toObject = (): RegisterObject[] => {
-		return Object.keys(this.cacheRegister).map((name) => {
-			return {
-				name: name,
-				data: this.cacheRegister[name].toObject()
-			}
-		});
-	}
-
-	save = (interval:number): void => {
-		setTimeout(() => {
-			fs.writeFileSync(path.resolve(this.storage, this.name), JSON.stringify(this.toObject()), { encoding: 'utf8', flag: 'w' });
-			debug(`register "${this.name}" saved to "${this.storage}"`);
-			this.save(interval);
-		}, interval);
-	}
-
-	restore = async (): Promise<void> => {
-		const data = JSON.parse(fs.readFileSync(path.resolve(this.storage, this.name), { encoding: 'utf8' }));
-
-		data.map((cache) => {
-			this.cacheRegister[cache.name] = new Cache();
-			this.cacheRegister[cache.name].fromObject(cache.data);
-		});
-		debug(`register "${this.name}" restored from "${this.storage}"`);
-	}
-}
-
-export class Cache {
-	constructor(private endpoint?: Endpoint, private realCache?: NodeCache) {
-		if (endpoint) this.setEndpoint(endpoint);
-		if (realCache) this.setCache(realCache);
-	}
-
-	setEndpoint(endpoint: Endpoint): this {
-		this.endpoint = endpoint;
-		return this;
-	}
-
-	getEndpoint(): Endpoint {
-		return this.endpoint;
-	}
-
-	setCache(realCache: NodeCache): this {
-		this.realCache = realCache;
-		this.realCache.on('expired', (key, value) => {
-			debug(`hash "${key}" has expired`);
-			this.refresh(key, value);
-		})
-		return this;
-	}
-
-	getCache(): NodeCache {
-		return this.realCache;
-	}
-
-	flush() {
-		return this.realCache.flushAll();
-	}
-
-	del(hash) {
-		return this.realCache.del(hash);
-	}
-
-	async get(hash: string, path: string): Promise<EndpointValue> {
-		let value: EndpointValue | undefined = this.realCache.get(hash);
-		if (value == undefined) {
-			debug(`no cache hit. fetching ${path}`);
-			value = {
-				uriPath: path,
-				contentType: '',
-				data: ''
-			};
-			try {
-				await this.endpoint.request(value);
-				this.realCache.set(hash, value);
-			} catch (err) {
-				console.error(err);
-			}
-		} else {
-			debug(`cache hit. ttl is ${this.realCache.getTtl(hash)}`);
-
-		}
-
-		return value;
-	}
-
-	async refresh(key, value) {
-		const newValue = {
-			uriPath: value.uriPath,
-			contentType: '',
-			data: ''
-		}
-		await this.endpoint.request(newValue);
-		value.data = newValue.data;
-		value.contentType = newValue.contentType;
-		this.realCache.set(key, value);
-		debug(`successfully refreshed "${key}"`);
-	}
-
-	keys = (): string[] => {
-		return this.realCache.keys();
-	}
-
-	getDetails<T>(hash?:string): CacheDetails|CacheDetails[] {
-		return (hash) ? this._getDetails(hash) : this.realCache.keys().map(this._getDetails.bind(this));
-	}
-
-	private _getDetails(hash: string): CacheDetails {
-		return {
-			hash: hash,
-			ttl: this.realCache.getTtl(hash),
-			uriPath: this.realCache.get<EndpointValue>(hash).uriPath,
-			contentType: this.realCache.get<EndpointValue>(hash).contentType,
-			size: this.realCache.get<EndpointValue>(hash).data.length
-		};
-	}
-
-	toObject(): CacheObject {
-		const data = {
-			endPoint: this.endpoint.toString(),
-			cacheOptions: this.realCache.options,
-			cache: []
-		}
-
-		this.realCache.keys().map((hash) => {
-			data.cache.push({
-				hash: hash,
-				value: this.realCache.get<EndpointValue>(hash)
-			});
-		});
-
-		return <CacheObject>data;
-	}
-
-	fromObject(data) {
-		const endpoint = new Endpoint(data.endPoint);
-		const realCache = new NodeCache(data.cacheOptions);
-		this.setEndpoint(endpoint);
-
-		data.cache.map((item) => {
-			realCache.set(item.hash, item.value);
-		});
-
-		this.setCache(realCache);
-	}
-}
\ No newline at end of file
diff --git a/src/lib/cache.ts b/src/lib/cache.ts
new file mode 100644
index 0000000000000000000000000000000000000000..540d5682bb0274260b1596c8e0eb35d2ec0d8be5
--- /dev/null
+++ b/src/lib/cache.ts
@@ -0,0 +1,156 @@
+import * as debugFactory from 'debug';
+import * as NodeCache from 'node-cache';
+
+import { Endpoint, EndpointValue } from './endpoint';
+
+const debug = debugFactory('dacap:cache');
+
+export interface CacheObject {
+	endPoint: string,
+	cacheOptions: NodeCache.Options,
+	cache: [
+		{
+			hash: string,
+			value: any
+		}
+	]
+}
+
+export interface CacheDetails {
+	hash: string,
+	uriPath: string,
+	contentType: string,
+	ttl: number,
+	size: number
+}
+
+export interface CacheInfo {
+	name: string,
+	apiEndPoint: string,
+	cacheOptions: NodeCache.Options,
+	cacheStats: NodeCache.Stats,
+	cache: CacheDetails[],
+}
+
+
+export class Cache {
+	constructor(private endpoint?: Endpoint, private realCache?: NodeCache) {
+		if (endpoint) this.setEndpoint(endpoint);
+		if (realCache) this.setCache(realCache);
+	}
+
+	setEndpoint(endpoint: Endpoint): this {
+		this.endpoint = endpoint;
+		return this;
+	}
+
+	getEndpoint(): Endpoint {
+		return this.endpoint;
+	}
+
+	setCache(realCache: NodeCache): this {
+		this.realCache = realCache;
+		this.realCache.on('expired', (key, value) => {
+			debug(`hash "${key}" has expired`);
+			this.refresh(key, value);
+		})
+		return this;
+	}
+
+	getCache(): NodeCache {
+		return this.realCache;
+	}
+
+	flush() {
+		return this.realCache.flushAll();
+	}
+
+	del(hash) {
+		return this.realCache.del(hash);
+	}
+
+	async get(hash: string, path: string): Promise<EndpointValue> {
+		let value: EndpointValue | undefined = this.realCache.get(hash);
+		if (value == undefined) {
+			debug(`no cache hit. fetching ${path}`);
+			value = {
+				uriPath: path,
+				contentType: '',
+				data: ''
+			};
+			try {
+				await this.endpoint.request(value);
+				this.realCache.set(hash, value);
+			} catch (err) {
+				console.error(err);
+			}
+		} else {
+			debug(`cache hit. ttl is ${this.realCache.getTtl(hash)}`);
+
+		}
+
+		return value;
+	}
+
+	async refresh(key, value) {
+		const newValue = {
+			uriPath: value.uriPath,
+			contentType: '',
+			data: ''
+		}
+		await this.endpoint.request(newValue);
+		value.data = newValue.data;
+		value.contentType = newValue.contentType;
+		this.realCache.set(key, value);
+		debug(`successfully refreshed "${key}"`);
+	}
+
+	keys(): string[] {
+		return this.realCache.keys();
+	}
+
+	getDetails(): CacheDetails[];
+	getDetails(hash: string): CacheDetails;
+	getDetails(hash?): any {
+		return (hash) ? this._getDetails(hash) : this.realCache.keys().map(this._getDetails.bind(this));
+	}
+
+	private _getDetails(hash: string): CacheDetails {
+		return {
+			hash: hash,
+			ttl: this.realCache.getTtl(hash),
+			uriPath: this.realCache.get<EndpointValue>(hash).uriPath,
+			contentType: this.realCache.get<EndpointValue>(hash).contentType,
+			size: this.realCache.get<EndpointValue>(hash).data.length
+		};
+	}
+
+	toObject(): CacheObject {
+		const data = {
+			endPoint: this.endpoint.toString(),
+			cacheOptions: this.realCache.options,
+			cache: []
+		}
+
+		this.realCache.keys().map((hash) => {
+			data.cache.push({
+				hash: hash,
+				value: this.realCache.get<EndpointValue>(hash)
+			});
+		});
+
+		return <CacheObject>data;
+	}
+
+	fromObject(data) {
+		const endpoint = new Endpoint(data.endPoint);
+		const realCache = new NodeCache(data.cacheOptions);
+		this.setEndpoint(endpoint);
+
+		data.cache.map((item) => {
+			realCache.set(item.hash, item.value);
+		});
+
+		this.setCache(realCache);
+	}
+}
\ No newline at end of file
diff --git a/src/endpoint.ts b/src/lib/endpoint.ts
similarity index 93%
rename from src/endpoint.ts
rename to src/lib/endpoint.ts
index cd94c001f7287ce8e107681118eac67eaf72987d..cf1346278f27e5448fa56998933cf900952aae52 100644
--- a/src/endpoint.ts
+++ b/src/lib/endpoint.ts
@@ -17,7 +17,7 @@ export class Endpoint {
 	}
 
 	toString(): string {
-		return Url.format(this.serverUrl);
+		return this.serverUrl ? Url.format(this.serverUrl) : '';
 	}
 
 	request(value:EndpointValue): Promise<void>{
diff --git a/src/lib/middleware.ts b/src/lib/middleware.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1115eef4c4bc9644e10c4ea5c34ccca99430ec53
--- /dev/null
+++ b/src/lib/middleware.ts
@@ -0,0 +1,29 @@
+import * as express from 'express';
+import * as crypto from 'crypto';
+import { Register } from './register';
+import * as debugFactory from 'debug';
+
+const debug = debugFactory('dacap:middleware');
+
+export interface MiddlewareFunction {
+	(req: express.Request, res: express.Response, next: express.NextFunction): Promise<void>
+}
+
+export function Middleware(register: Register): MiddlewareFunction {
+
+	return async function (req: express.Request, res: express.Response, next: express.NextFunction): Promise<void> {
+		const pattern = new RegExp('^/([^/]+)/?(.*)$');
+		const match = req.url.match(pattern);
+		try {
+			const cache = register.get(match[1]);
+			const uniQueryString = Object.keys(req.query).sort().map(function (key) { return `${key}=${req.query[key]}` }).join('&');
+			const hash = crypto.createHash('sha1').update(req.path + uniQueryString).digest('hex');
+			debug(`finding cache-entry for ${hash}`);
+			const value = await cache.get(hash, match[2]);
+			res.setHeader('content-type', value.contentType)
+			res.send(value.data);
+		} catch (err) {
+			res.status(404).send(err.message);
+		}
+	}
+}
diff --git a/src/lib/register.ts b/src/lib/register.ts
new file mode 100644
index 0000000000000000000000000000000000000000..415fda80a0d27a54915268918c5ec99bc3b6e8e8
--- /dev/null
+++ b/src/lib/register.ts
@@ -0,0 +1,117 @@
+import * as debugFactory from 'debug';
+import * as NodeCache from 'node-cache';
+import * as fs from 'fs';
+import * as path from 'path';
+import * as Q from 'q';
+
+import { CacheObject, Cache, CacheInfo } from './cache';
+import { Endpoint } from './endpoint';
+
+const debug = debugFactory('dacap:register');
+
+export interface RegisterObject {
+	name: string
+	data: CacheObject
+}
+
+/**
+ * the cache register
+ *
+ * @export
+ * @class Register
+ */
+export class Register {
+	cacheRegister: { [key: string]: Cache } = {};
+	saveTimer: NodeJS.Timer;
+
+	constructor(private storage: string, public name: string) {
+		fs.existsSync(storage) || fs.mkdirSync(storage);
+	}
+
+	has(name: string): boolean {
+		return !!this.cacheRegister[name];
+	}
+	/**
+	 * gets register by its name
+	 *
+	 * @memberof Register
+	 */
+	get(name: string): Cache {
+		if (!this.has(name)) throw new Error(`register not found: ${name}`);
+		return this.cacheRegister[name];
+	}
+
+	/**
+	 * adds API-Endpoint to cache-register
+	 *
+	 * @memberof Register
+	 */
+	add(name: string, serverUrl: string, cacheOptions: NodeCache.Options) {
+		const endpoint: Endpoint = new Endpoint(serverUrl);
+		const nodeCache: NodeCache = new NodeCache(cacheOptions)
+		this.cacheRegister[name] = new Cache(endpoint, nodeCache);
+	}
+
+	delete(name: string) {
+		if (!this.has(name)) throw new Error(`register not found: ${name}`);
+		delete this.cacheRegister[name];
+	}
+
+	getInfo(): CacheInfo[];
+	getInfo(name: string): CacheInfo;
+	getInfo(name?): any {
+		return (name) ? this._getInfo(name) : Object.keys(this.cacheRegister).map((key): CacheInfo => {
+			return this._getInfo(key);
+		});
+	}
+
+	private _getInfo(name: string): CacheInfo {
+		return {
+			name: name,
+			apiEndPoint: this.cacheRegister[name].getEndpoint().toString(),
+			cacheOptions: this.cacheRegister[name].getCache().options,
+			cacheStats: this.cacheRegister[name].getCache().getStats(),
+			cache: this.cacheRegister[name].getDetails()
+		}
+	}
+
+	toObject(): RegisterObject[] {
+		return Object.keys(this.cacheRegister).map((name) => {
+			return {
+				name: name,
+				data: this.cacheRegister[name].toObject()
+			}
+		});
+	}
+
+	save(interval?: number): void {
+		let success = this._save();
+
+		if (this.saveTimer) {
+			clearTimeout(this.saveTimer);
+			this.saveTimer = undefined;
+		}
+
+		if (interval && success) {
+			this.saveTimer = setTimeout(() => {
+				this.save(interval);
+			}, interval);
+		}
+	}
+
+	_save(): Boolean {
+		fs.writeFileSync(path.resolve(this.storage, this.name), JSON.stringify(this.toObject()), { encoding: 'utf8', flag: 'w' });
+		debug(`register "${this.name}" saved to "${this.storage}"`);
+		return true;
+	}
+
+	async restore(): Promise<void> {
+		const data = JSON.parse(fs.readFileSync(path.resolve(this.storage, this.name), { encoding: 'utf8' }));
+
+		data.map((cache) => {
+			this.cacheRegister[cache.name] = new Cache();
+			this.cacheRegister[cache.name].fromObject(cache.data);
+		});
+		debug(`register "${this.name}" restored from "${this.storage}"`);
+	}
+}
\ No newline at end of file
diff --git a/src/server.ts b/src/lib/server.ts
similarity index 84%
rename from src/server.ts
rename to src/lib/server.ts
index e7116ffe5674cfc38d630922023f5fd46cb11bcc..2d3521be6a9fb21c814bb76fc5f10c53d58dfbe2 100644
--- a/src/server.ts
+++ b/src/lib/server.ts
@@ -2,16 +2,18 @@ import * as express from 'express';
 import * as compression from 'compression';
 import * as debugFactory from 'debug';
 import * as path from 'path';
-import * as cache from './cache';
 import * as bodyparser from 'body-parser';
 import * as cors from 'cors';
 import * as url from 'url';
 import * as PrettyPrint from 'js-object-pretty-print';
 
+import { Register } from './register';
+import { Middleware } from './middleware';
+
 const debug = debugFactory('dacap:server');
 
 export class Server {
-	private register: cache.Register;
+	private register: Register;
 	private expressApp: express.Application;
 	private corsOptions: cors.CorsOptions;
 	private prePath: string = '';
@@ -42,7 +44,7 @@ export class Server {
 	}
 
 	private initRegister() {
-		this.register = new cache.Register(this.config.storagePath, this.config.registerName);
+		this.register = new Register(this.config.storagePath, this.config.registerName);
 		this.register.restore();
 		this.register.save(this.config.autosaveInterval * 1000);
 	}
@@ -130,9 +132,18 @@ export class Server {
 			}
 		});
 
-		this.expressApp.use(this.prePath + '/admin/', express.static(path.resolve(__dirname, '..', 'public')));
+		if (process.env.NODE_ENV === 'development') {
+			let webpack = require('webpack');
+			let WebpackDevMiddleware = require('webpack-dev-middleware');
+			let webpackConfig = require('../webpack.dev');
+			this.expressApp.use(WebpackDevMiddleware(webpack(webpackConfig), {
+				publicPath: `${this.prePath}/admin/`
+			}));
+		} else {
+			this.expressApp.use(`${this.prePath}/admin/`, express.static(path.resolve(__dirname, '..', 'public')));
+		}
 
-		this.expressApp.use(this.prePath + this.config.proxyPath, cache.Middleware(this.register));
+		this.expressApp.use(this.prePath + this.config.proxyPath, Middleware(this.register));
 	}
 
 	listen(port: number, cb) {
diff --git a/src/test/cache.ts b/src/test/cache.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d7f5185df4f12748e70058770a3f23272c80b6dc
--- /dev/null
+++ b/src/test/cache.ts
@@ -0,0 +1,123 @@
+/// <reference types="mocha" />
+
+import { Cache } from '../lib/cache';
+import { Endpoint } from '../lib/endpoint';
+import * as NodeCache from 'node-cache';
+import * as should from 'should';
+import * as fs from 'fs';
+import * as rimraf from 'rimraf';
+import * as path from 'path';
+import * as nock from 'nock';
+
+const tmpPath = '.dacap-tmp';
+
+describe('Cache', () => {
+	describe('instantiate empty', () => {
+		it('should be an instance of Cache', () => {
+			let cache = new Cache();
+			should(cache).be.instanceof(Cache);
+		});
+	});
+
+	describe('instantiate with endpoint and node-cache', () => {
+		it('should be an instance of Cache', () => {
+			let endpoint = new Endpoint();
+			let realCache = new NodeCache();
+			let cache = new Cache(endpoint, realCache);
+			should(cache).be.instanceof(Cache);
+		});
+	});
+
+	describe('setEndpoint', () => {
+		it('should set endpoint', () => {
+			let endpoint = new Endpoint()
+			let cache = new Cache();
+			should(cache.setEndpoint(endpoint)).be.instanceof(Cache);
+		});
+	});
+
+	describe('getEndpoint', () => {
+		let cache;
+		beforeEach(() => {
+			cache = new Cache(new Endpoint());
+		});
+
+		it('should get endpoint', () => {
+			should(cache.getEndpoint()).be.instanceof(Endpoint);
+		});
+	});
+
+	describe('setCache', () => {
+		let cache;
+		beforeEach(() => {
+			cache = new Cache();
+		});
+
+		it('should set cache', () => {
+			should(cache.setCache(new NodeCache())).be.instanceof(Cache);
+		})
+	});
+
+	describe('getCache', () => {
+		let cache;
+		beforeEach(() => {
+			cache = new Cache(null, new NodeCache());
+		});
+
+		it('should get cache', () => {
+			should(cache.getCache()).be.instanceof(NodeCache);
+		});
+	});
+
+	describe('flush', () => {
+		let cache, realCache = new NodeCache();
+		beforeEach(() => {
+			cache = new Cache(null, realCache);
+			realCache.set('validHash', 'validData');
+			realCache.set('anotherValidHash', 'anotherValidData');
+		});
+
+		it('should remove all values', () => {
+			cache.flush();
+			should(realCache.get('validHash')).be.undefined;
+			should(realCache.get('anotherValidHash')).be.undefined;
+		});
+	});
+
+	describe('delete', () => {
+		let cache, realCache = new NodeCache();
+		beforeEach(() => {
+			cache = new Cache(null, realCache);
+			realCache.set('validHash', 'validData');
+			realCache.set('anotherValidHash', 'anotherValidData');
+		});
+
+		it('should remove onnly one value', () => {
+			cache.del('validHash');
+			should(realCache.get('validHash')).be.undefined;
+			should(realCache.get('anotherValidHash')).eql('anotherValidData');
+		});
+	});
+
+	describe('get', () => {
+		let cache;
+		beforeEach(() => {
+			nock('https://api.example.com').get('/').reply(200, {
+				"validKey": "validData"
+			});
+
+			cache = new Cache(new Endpoint('https://api.example.com'), new NodeCache);
+		});
+
+		it('should return the json',(done) => {
+			cache.get('newHash', '/').then((value) => {
+				should(value).eql({
+					uriPath: '/',
+					contentType: '',
+					data:'validData'
+				});
+				done();
+			}).catch(done);
+		});
+	});
+});
\ No newline at end of file
diff --git a/src/test/register.ts b/src/test/register.ts
new file mode 100644
index 0000000000000000000000000000000000000000..774d9ee4b72080002f3afa4755e237e8b6102b8c
--- /dev/null
+++ b/src/test/register.ts
@@ -0,0 +1,316 @@
+/// <reference types="mocha" />
+
+import { Register } from '../lib/register';
+import * as should from 'should';
+import * as fs from 'fs';
+import * as rimraf from 'rimraf';
+import * as path from 'path';
+
+const tmpPath = '.dacap-tmp';
+
+describe('Register', () => {
+	describe('instantiate', () => {
+		describe('with valid folder', () => {
+			afterEach(() => {
+				rimraf.sync(tmpPath);
+			});
+
+			it('should perform successfully', () => {
+				let register = new Register(`${tmpPath}/`, 'foo');
+				should(register).instanceof(Register);
+			});
+
+			it('even without trailing slash', () => {
+				let register = new Register(tmpPath, 'foo');
+				should(register).instanceof(Register);
+			});
+		});
+
+		describe('with invalid folder name', () => {
+			it('should throw an exception', () => {
+				should(() => {
+					let register = new Register('', 'foo');
+				}).throw(/NOENT/);
+			});
+		});
+
+		describe('with insufficient permissions', () => {
+			it('should throw an exception', () => {
+				should(() => {
+					let register = new Register('/root/.tmp', 'foo');
+				}).throw(/EACCES/);
+			});
+		});
+	});
+
+	describe('has', () => {
+		let register: Register;
+		beforeEach(() => {
+			register = new Register(tmpPath, 'foo');
+			register.add('validCache', 'http://example.com/', {});
+		});
+
+		describe('existing cache', () => {
+			it('should return true', () => {
+				should(register.has('validCache')).eql(true);
+			});
+		});
+
+		describe('existing cache', () => {
+			it('should return false', () => {
+				should(register.has('invalidCache')).eql(false);
+			});
+		});
+	});
+
+	describe('get', () => {
+		let register: Register;
+		beforeEach(() => {
+			register = new Register(tmpPath, 'foo');
+			register.add('validCache', 'http://example.com/', {});
+		});
+
+		afterEach(() => {
+			rimraf.sync(tmpPath)
+		});
+
+		describe('existing cache', () => {
+			it('should be an instance of Cache', () => {
+				let validCache = register.get('validCache');
+				should(validCache).not.undefined;
+			});
+		});
+
+		describe('non-existing cache', () => {
+			it('should throw an error', () => {
+				should(() => {
+					let validCache = register.get('invalidCache');
+				}).throw('register not found: invalidCache');
+			});
+		});
+	});
+
+	describe('add', () => {
+		let register: Register;
+		beforeEach(() => {
+			register = new Register(tmpPath, 'foo');
+		});
+
+		afterEach(() => {
+			rimraf.sync(tmpPath)
+		});
+
+		describe('new cache', () => {
+			beforeEach(() => {
+				register.add('newCache', 'http://example.com/', {});
+			});
+			it('should have added a new cache', () => {
+				should(register.get('newCache')).not.be.undefined;
+			});
+		});
+	});
+
+	describe('delete', () => {
+		let register: Register;
+		beforeEach(() => {
+			register = new Register(tmpPath, 'foo');
+			register.add('validCache', 'http://example.com/', {});
+		});
+
+		afterEach(() => {
+			rimraf.sync(tmpPath)
+		});
+
+		describe('existing cache', () => {
+			beforeEach(() => {
+				register.delete('validCache');
+			});
+			it('should have removed existing cache', () => {
+				should(register.cacheRegister['newCache']).eql(undefined);
+			});
+		});
+
+		describe('non-existing cache', () => {
+			it('should throw an error', () => {
+				should(() => {
+					register.delete('nonExistingCache');
+				}).throw('register not found: nonExistingCache');
+			});
+		});
+	});
+
+	describe('getInfo', () => {
+		let register: Register;
+		beforeEach(() => {
+			register = new Register(tmpPath, 'foo');
+			register.add('newCache', 'http://example.com/', {});
+		});
+
+		describe('without passing cache name', () => {
+			it('should return list of CacheInfo objects', () => {
+				let cacheInfoList = register.getInfo();
+				should(cacheInfoList).be.an.Array();
+				should(cacheInfoList[0]).have.keys('name', 'apiEndPoint', 'cacheOptions', 'cacheStats', 'cache');
+			});
+		});
+
+		describe('with passing cache name', () => {
+			it('should return a CacheInfo object', () => {
+				let cacheInfo = register.getInfo('newCache');
+				should(cacheInfo).have.keys('name', 'apiEndPoint', 'cacheOptions', 'cacheStats', 'cache');
+			});
+		});
+	});
+
+	describe('toObject', () => {
+		let register: Register;
+		beforeEach(() => {
+			register = new Register(tmpPath, 'foo');
+			register.add('newCache', 'http://example.com/', {});
+		});
+
+		describe('existing register', () => {
+			let serializedCache;
+			beforeEach(() => {
+				serializedCache = register.toObject();
+			});
+
+			it('should serialize the register', () => {
+				should(serializedCache).be.an.Array();
+				should(serializedCache[0]).containDeep({
+					name: "newCache",
+					data: {
+						endPoint: 'http://example.com/',
+						cache: []
+					}
+				});
+
+			});
+		});
+	});
+	describe('save', () => {
+		let register: Register;
+
+		afterEach(() => {
+			rimraf.sync(tmpPath);
+		});
+
+		describe('with sufficient permissions', () => {
+			beforeEach(() => {
+				register = new Register(tmpPath, 'foo');
+				register.add('newCache', 'http://example.com/', {});
+			});
+
+			describe('once', () => {
+				it('should create a save file', () => {
+					register.save();
+					should(() => {
+						fs.statSync(path.resolve(tmpPath, 'foo'))
+					}).not.throw(Error);
+				});
+			});
+
+			describe('with interval', () => {
+				let filesize1, filesize2;
+
+				it('should increase file size', (done) => {
+					register.save(100);
+					filesize1 = fs.statSync(path.resolve(tmpPath, 'foo')).size
+					register.add('moreCache', 'https://api.example.com/', {});
+					setTimeout(() => {
+						should(() => {
+							filesize2 = fs.statSync(path.resolve(tmpPath, 'foo')).size
+						}).not.throw(Error)
+						should(filesize2).above(filesize1);
+						register.add('evenMoreCache', 'https://anotherapi.example.com/', {});
+						filesize1 = filesize2;
+					}, 150);
+					setTimeout(() => {
+						should(() => {
+							filesize2 = fs.statSync(path.resolve(tmpPath, 'foo')).size
+						}).not.throw(Error)
+						should(filesize2).above(filesize1);
+						done();
+					}, 250);
+				});
+			});
+
+			describe('remove interval', () => {
+				let filesize1, filesize2;
+
+				it('should stop saving file', () => {
+					register.save(100);
+					filesize1 = fs.statSync(path.resolve(tmpPath, 'foo')).size
+					register.save();
+					register.add('moreCache', 'https://api.example.com/', {});
+
+					setTimeout(() => {
+						should(() => {
+							filesize2 = fs.statSync(path.resolve(tmpPath, 'foo')).size
+						}).not.throw(Error)
+						should(filesize2).equal(filesize1);
+					}, 150);
+				});
+			});
+		});
+
+		describe('with insufficient permissions', () => {
+			beforeEach(() => {
+				register = new Register('/root', 'foo');
+				register.add('newCache', 'http://example.com/', {});
+			});
+
+			describe('once', () => {
+				it('should throw an error', () => {
+					should(() => {
+						register.save();
+					}).throw(/EACCES/);
+				});
+			});
+		});
+	});
+
+	describe('restore', () => {
+		describe('existing file', () => {
+			beforeEach(() => {
+				let register = new Register(tmpPath, 'foo');
+				register.add('newCache', 'http://example.com/', {});
+				let Cache = register.get('newCache').getCache();
+				Cache.set('validHash', {
+					uriPath: '/foo/bar',
+					contentType: 'x-mostly/garbage',
+					data: 'validData'
+				});
+				register.save();
+			});
+
+			afterEach(() => {
+				rimraf.sync(tmpPath);
+			});
+
+			it('should restore the register', (done) => {
+				let register = new Register(tmpPath, 'foo');
+				register.restore().then(() => {
+					should(register.has('newCache')).be.true;
+					should(register.getInfo('newCache').apiEndPoint).eql('http://example.com/');
+					should(register.get('newCache').getCache().get('validHash')).containEql({
+						uriPath: '/foo/bar',
+						contentType: 'x-mostly/garbage',
+						data: 'validData'
+					});
+					done();
+				}).catch(done);
+			});
+		});
+		describe('non-existing file', () => {
+			it('should reject promise', (done) => {
+				let register = new Register(tmpPath, 'foo');
+				register.restore().then(() => {
+					done('promise was resolved')
+				}).catch(() => {
+					done();
+				})
+			});
+		});
+	});
+});
\ No newline at end of file
diff --git a/test/cache.js b/test/cache.js
deleted file mode 100644
index df2f88d10712a084aacd92e6fd2ce0635c59fcb8..0000000000000000000000000000000000000000
--- a/test/cache.js
+++ /dev/null
@@ -1,11 +0,0 @@
-const path = require('path');
-
-const Middleware = require('../dist/cache').Middleware;
-const Register = require('../dist/cache').Register;
-const Cache = require('../dist/cache').Cache;
-
-describe('Middleware', () => {
-	it('should be a function', (done) => {
-		done();
-	});
-})
\ No newline at end of file
diff --git a/tsconfig.json b/tsconfig.json
index 1d467e6ee29a1edda39a4d753e2d390c7c010bd4..af0b79e7177bb985f204d1774156441a7566065f 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -3,10 +3,10 @@
 		"module": "commonjs",
 		"target": "es6",
 		"noImplicitAny": false,
-		"outDir": "dist"
+		"outDir": "./"
 	},
-	"include": ["src/*"],
+	"include": ["src/**/*"],
 	"exclude": [
-		"admin"
+		"src/admin"
 	]
 }
\ No newline at end of file