diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 0000000..c795b05
--- /dev/null
+++ b/.eslintignore
@@ -0,0 +1 @@
+build
\ No newline at end of file
diff --git a/src/agentmgr.js b/src/agentmgr.js
new file mode 100644
index 0000000..cb0e5a9
--- /dev/null
+++ b/src/agentmgr.js
@@ -0,0 +1,505 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+'use strict';
+
+const NgrokAgent = require('./ngrok');
+const fs = require('fs-extra');
+const sleep = require('util').promisify(setTimeout);
+
+function getAnnotation(action, key) {
+    const a = action.annotations.find(a => a.key === key);
+    if (a) {
+        return a.value;
+    }
+}
+
+function getActionCopyName(name) {
+    return `${name}_wskdebug_original`;
+}
+
+function isAgent(action) {
+    return getAnnotation(action, "wskdebug") ||
+           (getAnnotation(action, "description") || "").startsWith("wskdebug agent.");
+}
+
+function getActivationError(e) {
+    if (e.error && e.error.response && e.error.response.result && e.error.response.result.error) {
+        return e.error.response.result.error;
+    }
+    return {};
+}
+
+async function getWskActionWithoutCode(wsk, actionName) {
+    try {
+        return await wsk.actions.get({name: actionName, code:false});
+    } catch (e) {
+        if (e.statusCode === 404) {
+            return null;
+        } else {
+            throw e;
+        }
+    }
+}
+
+async function actionExists(wsk, name) {
+    try {
+        await wsk.actions.get({name: name, code: false});
+        return true;
+    } catch (e) {
+        return false;
+    }
+}
+
+async function deleteActionIfExists(wsk, name) {
+    if (await actionExists(wsk, name)) {
+        await wsk.actions.delete(name);
+    }
+}
+
+
+// TODO: test wskdebug manually
+// TODO: openwhiskSupports() into separate shared class
+class AgentMgr {
+
+    constructor(argv, wsk, actionName) {
+        this.argv = argv;
+        this.wsk = wsk;
+        this.actionName = actionName;
+        this.polling = true;
+    }
+
+    async readAction() {
+        if (this.argv.verbose) {
+            console.log(`Getting action metadata from OpenWhisk: ${this.actionName}`);
+        }
+        let action = await getWskActionWithoutCode(this.wsk, this.actionName);
+        if (action === null) {
+            throw new Error(`Action not found: ${this.actionName}`);
+        }
+
+        let agentAlreadyInstalled = false;
+
+        // check if this actoin needs to
+        if (isAgent(action)) {
+            // ups, action is our agent, not the original
+            // happens if a previous wskdebug was killed and could not restore before it exited
+            const backupName = getActionCopyName(this.actionName);
+
+            // check the backup action
+            try {
+                const backup = await this.wsk.actions.get(backupName);
+
+                if (isAgent(backup)) {
+                    // backup is also an agent (should not happen)
+                    // backup is useless, delete it
+                    // await this.wsk.actions.delete(backupName);
+                    throw new Error(`Dang! Agent is already installed and action backup is broken (${backupName}).\n\nPlease redeploy your action first before running wskdebug again.`);
+
+                } else {
+                    console.warn("Agent was already installed, but backup is still present. All good.");
+
+                    // need to look at the original action
+                    action = backup;
+                    agentAlreadyInstalled = true;
+                    this.agentInstalled = true;
+                }
+
+            } catch (e) {
+                if (e.statusCode === 404) {
+                    // backup missing
+                    throw new Error(`Dang! Agent is already installed and action backup is gone (${backupName}).\n\nPlease redeploy your action first before running wskdebug again.`);
+
+                } else {
+                    // other error
+                    throw e;
+                }
+            }
+        }
+        return {action, agentAlreadyInstalled };
+    }
+
+    async installAgent(action) {
+        this.agentInstalled = true;
+
+        let agentName;
+
+        // choose the right agent implementation
+        let agentCode;
+        if (this.argv.ngrok) {
+            // user manually requested ngrok
+
+            this.ngrokAgent = new NgrokAgent(this.argv);
+
+            // agent using ngrok for forwarding
+            agentName = "ngrok";
+            agentCode = await this.ngrokAgent.getAgent(action);
+
+        } else {
+            this.concurrency = await this.openwhiskSupports("concurrency");
+            if (this.concurrency) {
+                // normal fast agent using concurrent node.js actions
+                agentName = "concurrency";
+                agentCode = await this.getConcurrencyAgent();
+
+            } else {
+                console.log("This OpenWhisk does not support action concurrency. Debugging will be a bit slower. Consider using '--ngrok' which might be a faster option.");
+
+                agentName = "polling activation db";
+                agentCode = await this.getPollingActivationRecordAgent();
+            }
+        }
+
+        const backupName = getActionCopyName(this.actionName);
+
+        if (this.argv.verbose) {
+            console.log(`Installing agent in OpenWhisk (${agentName})...`);
+        }
+
+        // create copy
+        await this.wsk.actions.update({
+            name: backupName,
+            action: action
+        });
+
+        if (this.argv.verbose) {
+            console.log(`Original action backed up at ${backupName}.`);
+        }
+
+        if (this.argv.condition) {
+            action.parameters.push({
+                key: "$condition",
+                value: this.argv.condition
+            });
+        }
+
+        await this.pushAgent(action, agentCode, backupName);
+
+        if (this.argv.verbose) {
+            console.log(`Agent installed.`);
+        }
+    }
+
+    stop() {
+        this.polling = false;
+    }
+
+    async shutdown() {
+        try {
+            await this.restoreAction();
+        } finally {
+            if (this.ngrokAgent) {
+                await this.ngrokAgent.stop();
+            }
+        }
+    }
+
+    // --------------------------------------< polling >-------------------
+
+    async waitForActivations() {
+        this.activationsSeen = this.activationsSeen || {};
+
+        // secondary loop to get next activation
+        // the $waitForActivation agent activation will block, but only until
+        // it times out, hence we need to retry when it fails
+        while (this.polling) {
+            if (this.argv.verbose) {
+                process.stdout.write(".");
+            }
+            try {
+                let activation;
+                if (this.concurrency) {
+                    // invoke - blocking for up to 1 minute
+                    activation = await this.wsk.actions.invoke({
+                        name: this.actionName,
+                        params: {
+                            $waitForActivation: true
+                        },
+                        blocking: true
+                    });
+
+                } else {
+                    // poll for the newest activation
+                    const since = Date.now();
+
+                    // older openwhisk only allows the name of an action when filtering activations
+                    // newer openwhisk versions want package/name
+                    let name = this.actionName;
+                    if (await this.openwhiskSupports("activationListFilterOnlyBasename")) {
+                        if (this.actionName.includes("/")) {
+                            name = this.actionName.substring(this.actionName.lastIndexOf("/") + 1);
+                        }
+                    }
+
+                    while (true) {
+                        if (this.argv.verbose) {
+                            process.stdout.write(".");
+                        }
+
+                        const activations = await this.wsk.activations.list({
+                            name: `${name}_wskdebug_invoked`,
+                            since: since,
+                            limit: 1, // get the most recent one only
+                            docs: true // include results
+                        });
+
+                        if (activations && activations.length >= 1) {
+                            const a = activations[0];
+                            if (a.response && a.response.result && !this.activationsSeen[a.activationId]) {
+                                activation = a;
+                                break;
+                            }
+                        }
+
+                        // need to limit load on openwhisk (activation list)
+                        await sleep(1000);
+                    }
+                }
+
+                // check for successful response with a new activation
+                if (activation && activation.response) {
+                    const params = activation.response.result;
+
+                    // mark this as seen so we don't reinvoke it
+                    this.activationsSeen[activation.activationId] = true;
+
+                    if (this.argv.verbose) {
+                        console.log();
+                        console.info(`Activation: ${params.$activationId}`);
+                        console.log(params);
+                    } else {
+                        console.info(`Activation: ${params.$activationId}`);
+                    }
+                    return params;
+
+                } else if (activation && activation.activationId) {
+                    // ignore this and retry.
+                    // usually means the action did not respond within one second,
+                    // which in turn is unlikely for the agent who should exit itself
+                    // after 50 seconds, so can only happen if there was some delay
+                    // outside the action itself
+
+                } else {
+                    // unexpected, just log and retry
+                    console.log("Unexpected empty response while waiting for new activations:", activation);
+                }
+
+            } catch (e) {
+                // look for special error codes from agent
+                const errorCode = getActivationError(e).code;
+                // 42 => retry
+                if (errorCode === 42) {
+                    // do nothing
+                } else if (errorCode === 43) {
+                    // 43 => graceful shutdown (for unit tests)
+                    console.log("Graceful shutdown requested by agent (only for unit tests)");
+                    return null;
+                } else {
+                    // otherwise log error and abort
+                    console.error();
+                    console.error("Unexpected error while polling agent for activation:");
+                    console.dir(e, { depth: null });
+                    throw new Error("Unexpected error while polling agent for activation.");
+                }
+            }
+
+            // some small wait to avoid too many requests in case things run amok
+            await sleep(100);
+        }
+    }
+
+    async completeActivation(activationId, result, duration) {
+        console.info(`Completed activation ${activationId} in ${duration/1000.0} sec`);
+        if (this.argv.verbose) {
+            console.log(result);
+        }
+
+        try {
+            result.$activationId = activationId;
+            await this.wsk.actions.invoke({
+                name: this.concurrency ? this.actionName : `${this.actionName}_wskdebug_completed`,
+                params: result,
+                blocking: true
+            });
+        } catch (e) {
+            // look for special error codes from agent
+            const errorCode = getActivationError(e).code;
+            // 42 => retry
+            if (errorCode === 42) {
+                // do nothing
+            } else if (errorCode === 43) {
+                // 43 => graceful shutdown (for unit tests)
+                console.log("Graceful shutdown requested by agent (only for unit tests)");
+                return false;
+            } else {
+                console.error("Unexpected error while completing activation:", e);
+            }
+        }
+        return true;
+    }
+
+    // --------------------------------------< restoring >------------------
+
+    async restoreAction() {
+        if (this.agentInstalled) {
+            if (this.argv.verbose) {
+                console.log();
+                console.log(`Restoring action`);
+            }
+
+            const copy = getActionCopyName(this.actionName);
+
+            try {
+                const original = await this.wsk.actions.get(copy);
+
+                // copy the backup (copy) to the regular action
+                await this.wsk.actions.update({
+                    name: this.actionName,
+                    action: original
+                });
+
+                // remove the backup
+                await this.wsk.actions.delete(copy);
+
+                // remove any helpers if they exist
+                await deleteActionIfExists(this.wsk, `${this.actionName}_wskdebug_invoked`);
+                await deleteActionIfExists(this.wsk, `${this.actionName}_wskdebug_completed`);
+
+            } catch (e) {
+                console.error("Error while restoring original action:", e);
+            }
+        }
+    }
+
+    // --------------------------------------< agent types >------------------
+
+    async getConcurrencyAgent() {
+        return fs.readFileSync(`${__dirname}/../agent/agent-concurrency.js`, {encoding: 'utf8'});
+    }
+
+    async getPollingActivationRecordAgent() {
+        // this needs 2 helper actions in addition to the agent in place of the action
+        await this.createHelperAction(`${this.actionName}_wskdebug_invoked`,   `${__dirname}/../agent/echo.js`);
+        await this.createHelperAction(`${this.actionName}_wskdebug_completed`, `${__dirname}/../agent/echo.js`);
+
+        let agentCode = fs.readFileSync(`${__dirname}/../agent/agent-activationdb.js`, {encoding: 'utf8'});
+        // rewrite the code to pass config (we want to avoid fiddling with default params of the action)
+        if (await this.openwhiskSupports("activationListFilterOnlyBasename")) {
+            agentCode = agentCode.replace("const activationListFilterOnlyBasename = false;", "const activationListFilterOnlyBasename = true;");
+        }
+        return agentCode;
+    }
+
+    async pushAgent(action, agentCode, backupName) {
+        // overwrite action with agent
+
+        // this is to support older openwhisks for which nodejs:default is less than version 8
+        const nodejs8 = await this.openwhiskSupports("nodejs8");
+
+        await this.wsk.actions.update({
+            name: this.actionName,
+            action: {
+                exec: {
+                    kind: nodejs8 ? "nodejs:default" : "blackbox",
+                    image: nodejs8 ? undefined : "openwhisk/action-nodejs-v8",
+                    code: agentCode
+                },
+                limits: {
+                    timeout: (this.argv.agentTimeout || 300) * 1000,
+                    concurrency: this.concurrency ? 200: 1
+                },
+                annotations: [
+                    ...action.annotations,
+                    { key: "provide-api-key", value: true },
+                    { key: "wskdebug", value: true },
+                    { key: "description", value: `wskdebug agent. temporarily installed over original action. original action backup at ${backupName}.` }
+                ],
+                parameters: action.parameters
+            }
+        });
+    }
+
+    async createHelperAction(actionName, file) {
+        const nodejs8 = await this.openwhiskSupports("nodejs8");
+
+        await this.wsk.actions.update({
+            name: actionName,
+            action: {
+                exec: {
+                    kind: nodejs8 ? "nodejs:default" : "blackbox",
+                    image: nodejs8 ? undefined : "openwhisk/action-nodejs-v8",
+                    code: fs.readFileSync(file, {encoding: 'utf8'})
+                },
+                limits: {
+                    timeout: (this.argv.agentTimeout || 300) * 1000
+                },
+                annotations: [
+                    { key: "description", value: `wskdebug agent helper. temporarily installed.` }
+                ]
+            }
+        });
+    }
+
+    // ----------------------------------------< openwhisk feature detection >-----------------
+
+    async getOpenWhiskVersion() {
+        if (this.openwhiskVersion === undefined) {
+            try {
+                const json = await this.wsk.actions.client.request("GET", "/api/v1");
+                if (json && typeof json.build === "string") {
+                    this.openwhiskVersion = json.build;
+                } else {
+                    this.openwhiskVersion = null;
+                }
+            } catch (e) {
+                console.warn("Could not retrieve OpenWhisk version:", e.message);
+                this.openwhiskVersion = null;
+            }
+        }
+        return this.openwhiskVersion;
+    }
+
+    async openwhiskSupports(feature) {
+        const FEATURES = {
+            // guesstimated
+            activationListFilterOnlyBasename: v => v.startsWith("2018") || v.startsWith("2017"),
+            // hack
+            nodejs8: v => !v.startsWith("2018") && !v.startsWith("2017"),
+            concurrency: async (_, wsk) => {
+                // check swagger api docs instead of version to see if concurrency is supported
+                try {
+                    const swagger = await wsk.actions.client.request("GET", "/api/v1/api-docs");
+
+                    if (swagger && swagger.definitions && swagger.definitions.ActionLimits && swagger.definitions.ActionLimits.properties) {
+                        return swagger.definitions.ActionLimits.properties.concurrency;
+                    }
+                } catch (e) {
+                    console.warn('Could not read /api/v1/api-docs, setting max action concurrency to 1')
+                    return false;
+                }
+            }
+        };
+        const checker = FEATURES[feature];
+        if (checker) {
+            return checker(await this.getOpenWhiskVersion(), this.wsk);
+        } else {
+            throw new Error("Unknown feature " + feature);
+        }
+    }
+}
+
+module.exports = AgentMgr;
\ No newline at end of file
diff --git a/src/debugger.js b/src/debugger.js
index 86bc8ec..e43c8e8 100644
--- a/src/debugger.js
+++ b/src/debugger.js
@@ -17,33 +17,21 @@
 
 'use strict';
 
-const openwhisk = require("openwhisk");
 const wskprops = require('./wskprops');
-const fs = require('fs-extra');
 const OpenWhiskInvoker = require('./invoker');
+const AgentMgr = require('./agentmgr');
+const Watcher = require('./watcher');
+const openwhisk = require('openwhisk');
 const { spawnSync } = require('child_process');
-const livereload = require('livereload');
-const http = require('http');
-const ngrok = require('ngrok');
-const url = require('url');
-const util = require('util');
-const crypto = require("crypto");
+const sleep = require('util').promisify(setTimeout);
 
-async function sleep(millis) {
-    return new Promise(resolve => setTimeout(resolve, millis));
-}
-
-function getAnnotation(action, key) {
-    const a = action.annotations.find(a => a.key === key);
-    if (a) {
-        return a.value;
-    }
-}
-
+/**
+ * Central component of wskdebug.
+ */
 class Debugger {
     constructor(argv) {
         this.argv = argv;
-        this.action = argv.action;
+        this.actionName = argv.action;
 
         this.wskProps = wskprops.get();
         if (argv.ignoreCerts) {
@@ -54,16 +42,19 @@
     async start() {
         await this.setupWsk();
 
+        this.agentMgr = new AgentMgr(this.argv, this.wsk, this.actionName);
+        this.watcher = new Watcher(this.argv, this.wsk);
+
         // quick fail for missing requirements such as docker not running
         await OpenWhiskInvoker.checkIfAvailable();
 
-        console.info(`Starting debugger for /${this.wskProps.namespace}/${this.action}`);
+        console.info(`Starting debugger for /${this.wskProps.namespace}/${this.actionName}`);
 
         // get the action
-        const { action, agentAlreadyInstalled } = await this.getAction(this.action);
+        const { action, agentAlreadyInstalled } = await this.agentMgr.readAction();
 
         // local debug container
-        this.invoker = new OpenWhiskInvoker(this.action, action, this.argv, this.wskProps, this.wsk);
+        this.invoker = new OpenWhiskInvoker(this.actionName, action, this.argv, this.wskProps, this.wsk);
 
         try {
             // run build initially (would be required by starting container)
@@ -77,9 +68,9 @@
 
             // get code and /init local container
             if (this.argv.verbose) {
-                console.log(`Fetching action code from OpenWhisk: ${this.action}`);
+                console.log(`Fetching action code from OpenWhisk: ${this.actionName}`);
             }
-            const actionWithCode = await this.wsk.actions.get(this.action);
+            const actionWithCode = await this.wsk.actions.get(this.actionName);
             action.exec = actionWithCode.exec;
             await this.invoker.init(actionWithCode);
 
@@ -88,21 +79,21 @@
             // user can switch between agents (ngrok or not), hence we need to restore
             // (better would be to track the agent + its version and avoid a restore, but that's TBD)
             if (agentAlreadyInstalled) {
-                await this.restoreAction(this.action);
+                await this.agentMgr.restoreAction();
             }
 
-            await this.installAgent(this.action, action);
+            await this.agentMgr.installAgent(action);
 
             if (this.argv.onStart) {
                 console.log("On start:", this.argv.onStart);
                 spawnSync(this.argv.onStart, {shell: true, stdio: "inherit"});
             }
 
-            // start live reload (if requested)
-            await this.startSourceWatching();
+            // start source watching (live reload) if requested
+            await this.watcher.start();
 
             console.log();
-            console.info(`Action     : ${this.action}`);
+            console.info(`Action     : ${this.actionName}`);
             this.invoker.logInfo();
             if (this.argv.condition) {
                 console.info(`Condition  : ${this.argv.condition}`);
@@ -139,9 +130,9 @@
                     // agent: concurrent
                     // agent: non-concurrent
                     // wait for activation, run it, complete, repeat
-                    const activation = await this.waitForActivations(this.action);
+                    const activation = await this.agentMgr.waitForActivations();
                     if (!activation) {
-                        this.running = false;
+                        // this.running = false;
                         return;
                     }
 
@@ -157,7 +148,10 @@
                     const duration = Date.now() - startTime;
 
                     // pass on the local result to the agent in openwhisk
-                    await this.completeActivation(this.action, id, result, duration);
+                    if (!await this.agentMgr.completeActivation(id, result, duration)) {
+                        // this.running = false;
+                        return;
+                    }
                 }
             }
         } finally {
@@ -167,6 +161,8 @@
 
     async stop() {
         this.running = false;
+        this.agentMgr.stop();
+
         if (this.runPromise) {
             // wait for the main loop to gracefully end, which will call shutdown()
             await this.runPromise;
@@ -178,6 +174,7 @@
 
     async kill() {
         this.running = false;
+        this.agentMgr.stop();
 
         await this.shutdown();
     }
@@ -192,29 +189,9 @@
 
         // need to shutdown everything even if some fail, hence tryCatch() for each
 
-        if (this.action) {
-            await this.tryCatch(this.restoreAction(this.action));
-        }
+        await this.tryCatch(this.agentMgr.shutdown());
         await this.tryCatch(this.invoker.stop());
-
-        if (this.liveReloadServer) {
-            await this.tryCatch(() => {
-                if (this.liveReloadServer.server) {
-                    this.liveReloadServer.close();
-                } else {
-                    this.liveReloadServer.watcher.close();
-                }
-                this.liveReloadServer = null;
-            });
-        }
-
-        if (this.ngrokServer) {
-            await this.tryCatch(() => {
-                this.ngrokServer.close();
-                this.ngrokServer = null;
-            });
-        }
-        await this.tryCatch(ngrok.kill());
+        await this.tryCatch(this.watcher.stop());
 
         // only log this if we started properly
         if (this.ready) {
@@ -246,611 +223,6 @@
         }
     }
 
-    async getWskActionWithoutCode(actionName) {
-        if (this.argv.verbose) {
-            console.log(`Getting action metadata from OpenWhisk: ${actionName}`);
-        }
-        try {
-            return await this.wsk.actions.get({name: actionName, code:false});
-        } catch (e) {
-            if (e.statusCode === 404) {
-                return null;
-            } else {
-                throw e;
-            }
-        }
-    }
-
-    async actionExists(name) {
-        try {
-            await this.wsk.actions.get({name: name, code: false});
-            return true;
-        } catch (e) {
-            return false;
-        }
-    }
-
-    async deleteActionIfExists(name) {
-        if (await this.actionExists(name)) {
-            await this.wsk.actions.delete(name);
-        }
-    }
-
-    // ------------------------------------------------< agent >------------------
-
-    getActionCopyName(name) {
-        return `${name}_wskdebug_original`;
-    }
-
-    isAgent(action) {
-        return getAnnotation(action, "wskdebug") ||
-               (getAnnotation(action, "description") || "").startsWith("wskdebug agent.");
-    }
-
-    async getAction(actionName) {
-        let action = await this.getWskActionWithoutCode(actionName);
-        if (action === null) {
-            throw new Error(`Action not found: ${actionName}`);
-        }
-
-        let agentAlreadyInstalled = false;
-
-        // check if this actoin needs to
-        if (this.isAgent(action)) {
-            // ups, action is our agent, not the original
-            // happens if a previous wskdebug was killed and could not restore before it exited
-            const backupName = this.getActionCopyName(actionName);
-
-            // check the backup action
-            try {
-                const backup = await this.wsk.actions.get(backupName);
-
-                if (this.isAgent(backup)) {
-                    // backup is also an agent (should not happen)
-                    // backup is useless, delete it
-                    // await this.wsk.actions.delete(backupName);
-                    throw new Error(`Dang! Agent is already installed and action backup is broken (${backupName}).\n\nPlease redeploy your action first before running wskdebug again.`);
-
-                } else {
-                    console.warn("Agent was already installed, but backup is still present. All good.");
-
-                    // need to look at the original action
-                    action = backup;
-                    agentAlreadyInstalled = true;
-                    this.agentInstalled = true;
-                }
-
-            } catch (e) {
-                if (e.statusCode === 404) {
-                    // backup missing
-                    throw new Error(`Dang! Agent is already installed and action backup is gone (${backupName}).\n\nPlease redeploy your action first before running wskdebug again.`);
-
-                } else {
-                    // other error
-                    throw e;
-                }
-            }
-        }
-        return {action, agentAlreadyInstalled };
-    }
-
-    async createHelperAction(actionName, file) {
-        const nodejs8 = await this.openwhiskSupports("nodejs8");
-
-        await this.wsk.actions.update({
-            name: actionName,
-            action: {
-                exec: {
-                    kind: nodejs8 ? "nodejs:default" : "blackbox",
-                    image: nodejs8 ? undefined : "openwhisk/action-nodejs-v8",
-                    code: fs.readFileSync(file, {encoding: 'utf8'})
-                },
-                limits: {
-                    timeout: (this.argv.agentTimeout || 300) * 1000
-                },
-                annotations: [
-                    { key: "description", value: `wskdebug agent helper. temporarily installed.` }
-                ]
-            }
-        });
-    }
-
-    async installAgent(actionName, action) {
-        this.agentInstalled = true;
-
-        const agentDir = `${__dirname}/../agent`;
-        let agentName;
-
-        // choose the right agent implementation
-        let code;
-        if (this.argv.ngrok) {
-            // user manually requested ngrok
-            if (this.argv.verbose) {
-                console.log("Setting up ngrok", this.argv.ngrokRegion ? `(region: ${this.argv.ngrokRegion})` : "");
-            }
-
-            // 1. start local server on random port
-            this.ngrokServer = http.createServer(this.ngrokHandler.bind(this));
-            // turn server.listen() into promise so we can await
-            const listen = util.promisify( this.ngrokServer.listen.bind(this.ngrokServer) );
-            await listen(0, '127.0.0.1');
-
-            // 2. start ngrok tunnel connected to that port
-            this.ngrokServerPort = this.ngrokServer.address().port;
-
-            // create a unique authorization token that we check on our local instance later
-            // this adds extra protection on top of the uniquely generated ngrok subdomain (e.g. a01ae275.ngrok.io)
-            this.ngrokAuth = crypto.randomBytes(32).toString("hex");
-            const ngrokUrl = await ngrok.connect({
-                addr: this.ngrokServerPort,
-                region: this.argv.ngrokRegion
-            });
-
-            // 3. pass on public ngrok url to agent
-            action.parameters.push({
-                key: "$ngrokUrl",
-                value: url.parse(ngrokUrl).host
-            });
-            action.parameters.push({
-                key: "$ngrokAuth",
-                value: this.ngrokAuth
-            });
-
-            console.log(`Ngrok forwarding: ${ngrokUrl} => http://localhost:${this.ngrokServerPort} (auth: ${this.ngrokAuth})`);
-
-            // agent using ngrok for forwarding
-            agentName = "ngrok";
-            code = fs.readFileSync(`${agentDir}/agent-ngrok.js`, {encoding: 'utf8'});
-
-        } else {
-            this.concurrency = await this.openwhiskSupports("concurrency");
-            if (this.concurrency) {
-                // normal fast agent using concurrent node.js actions
-                agentName = "concurrency";
-                code = fs.readFileSync(`${agentDir}/agent-concurrency.js`, {encoding: 'utf8'});
-
-            } else {
-                console.log("This OpenWhisk does not support action concurrency. Debugging will be a bit slower. Consider using '--ngrok' which might be a faster option.");
-
-                agentName = "polling activation db";
-
-                // this needs 2 helper actions in addition to the agent in place of the action
-                await this.createHelperAction(`${actionName}_wskdebug_invoked`,   `${agentDir}/echo.js`);
-                await this.createHelperAction(`${actionName}_wskdebug_completed`, `${agentDir}/echo.js`);
-
-                code = fs.readFileSync(`${agentDir}/agent-activationdb.js`, {encoding: 'utf8'});
-                // rewrite the code to pass config (we want to avoid fiddling with default params of the action)
-                if (await this.openwhiskSupports("activationListFilterOnlyBasename")) {
-                    code = code.replace("const activationListFilterOnlyBasename = false;", "const activationListFilterOnlyBasename = true;");
-                }
-            }
-        }
-
-        const backupName = this.getActionCopyName(actionName);
-
-        if (this.argv.verbose) {
-            console.log(`Installing agent in OpenWhisk (${agentName})...`);
-        }
-
-        // create copy
-        await this.wsk.actions.update({
-            name: backupName,
-            action: action
-        });
-
-        if (this.argv.verbose) {
-            console.log(`Original action backed up at ${backupName}.`);
-        }
-
-        // this is to support older openwhisks for which nodejs:default is less than version 8
-        const nodejs8 = await this.openwhiskSupports("nodejs8");
-
-        if (this.argv.condition) {
-            action.parameters.push({
-                key: "$condition",
-                value: this.argv.condition
-            });
-        }
-
-        // overwrite action with agent
-        await this.wsk.actions.update({
-            name: actionName,
-            action: {
-                exec: {
-                    kind: nodejs8 ? "nodejs:default" : "blackbox",
-                    image: nodejs8 ? undefined : "openwhisk/action-nodejs-v8",
-                    code: code
-                },
-                limits: {
-                    timeout: (this.argv.agentTimeout || 300) * 1000,
-                    concurrency: this.concurrency ? 200: 1
-                },
-                annotations: [
-                    ...action.annotations,
-                    { key: "provide-api-key", value: true },
-                    { key: "wskdebug", value: true },
-                    { key: "description", value: `wskdebug agent. temporarily installed over original action. original action backup at ${backupName}.` }
-                ],
-                parameters: action.parameters
-            }
-        });
-
-        if (this.argv.verbose) {
-            console.log(`Agent installed.`);
-        }
-    }
-
-    async restoreAction(actionName) {
-        if (this.agentInstalled) {
-            if (this.argv.verbose) {
-                console.log();
-                console.log(`Restoring action`);
-            }
-
-            const copy = this.getActionCopyName(actionName);
-
-            try {
-                const original = await this.wsk.actions.get(copy);
-
-                // copy the backup (copy) to the regular action
-                await this.wsk.actions.update({
-                    name: actionName,
-                    action: original
-                });
-
-                // remove the backup
-                await this.wsk.actions.delete(copy);
-
-                // remove any helpers if they exist
-                await this.deleteActionIfExists(`${actionName}_wskdebug_invoked`);
-                await this.deleteActionIfExists(`${actionName}_wskdebug_completed`);
-
-            } catch (e) {
-                console.error("Error while restoring original action:", e);
-            }
-        }
-    }
-
-    // ------------------------------------------------< ngrok >------------------
-
-    // local http server retrieving forwards from the ngrok agent, running them
-    // as a blocking local invocation and then returning the activation result back
-    ngrokHandler(req, res) {
-        // check authorization against our unique token
-        const authHeader = req.headers.authorization;
-        if (authHeader !== this.ngrokAuth) {
-            res.statusCode = 401;
-            res.end();
-            return;
-        }
-
-        if (req.method === 'POST') {
-            // agent POSTs arguments as json body
-            let body = '';
-            // collect full request body first
-            req.on('data', chunk => {
-                body += chunk.toString();
-            });
-            req.on('end', async () => {
-                try {
-                    const params = JSON.parse(body);
-                    const id = params.$activationId;
-                    delete params.$activationId;
-
-                    if (this.argv.verbose) {
-                        console.log();
-                        console.info(`Activation: ${id}`);
-                        console.log(params);
-                    } else {
-                        console.info(`Activation: ${id}`);
-                    }
-
-                    const startTime = Date.now();
-
-                    const result = await this.invoker.run(params, id);
-
-                    const duration = Date.now() - startTime;
-                    console.info(`Completed activation ${id} in ${duration/1000.0} sec`);
-                    if (this.argv.verbose) {
-                        console.log(result);
-                    }
-
-                    res.statusCode = 200;
-                    res.setHeader("Content-Type", "application/json");
-                    res.end(JSON.stringify(result));
-
-                } catch (e) {
-                    console.error(e);
-                    res.statusCode = 400;
-                    res.end();
-                }
-            });
-        } else {
-            res.statusCode = 404;
-            res.end();
-        }
-    }
-
-    // ------------------------------------------------< polling >------------------
-
-    async waitForActivations(actionName) {
-        this.activationsSeen = this.activationsSeen || {};
-
-        // secondary loop to get next activation
-        // the $waitForActivation agent activation will block, but only until
-        // it times out, hence we need to retry when it fails
-        while (this.running) {
-            if (this.argv.verbose) {
-                process.stdout.write(".");
-            }
-            try {
-                let activation;
-                if (this.concurrency) {
-                    // invoke - blocking for up to 1 minute
-                    activation = await this.wsk.actions.invoke({
-                        name: actionName,
-                        params: {
-                            $waitForActivation: true
-                        },
-                        blocking: true
-                    });
-
-                } else {
-                    // poll for the newest activation
-                    const since = Date.now();
-
-                    // older openwhisk only allows the name of an action when filtering activations
-                    // newer openwhisk versions want package/name
-                    let name = actionName;
-                    if (await this.openwhiskSupports("activationListFilterOnlyBasename")) {
-                        if (actionName.includes("/")) {
-                            name = actionName.substring(actionName.lastIndexOf("/") + 1);
-                        }
-                    }
-
-                    while (true) {
-                        if (this.argv.verbose) {
-                            process.stdout.write(".");
-                        }
-
-                        const activations = await this.wsk.activations.list({
-                            name: `${name}_wskdebug_invoked`,
-                            since: since,
-                            limit: 1, // get the most recent one only
-                            docs: true // include results
-                        });
-
-                        if (activations && activations.length >= 1) {
-                            const a = activations[0];
-                            if (a.response && a.response.result && !this.activationsSeen[a.activationId]) {
-                                activation = a;
-                                break;
-                            }
-                        }
-
-                        // need to limit load on openwhisk (activation list)
-                        await sleep(1000);
-                    }
-                }
-
-                // check for successful response with a new activation
-                if (activation && activation.response) {
-                    const params = activation.response.result;
-
-                    // mark this as seen so we don't reinvoke it
-                    this.activationsSeen[activation.activationId] = true;
-
-                    if (this.argv.verbose) {
-                        console.log();
-                        console.info(`Activation: ${params.$activationId}`);
-                        console.log(params);
-                    } else {
-                        console.info(`Activation: ${params.$activationId}`);
-                    }
-                    return params;
-
-                } else if (activation && activation.activationId) {
-                    // ignore this and retry.
-                    // usually means the action did not respond within one second,
-                    // which in turn is unlikely for the agent who should exit itself
-                    // after 50 seconds, so can only happen if there was some delay
-                    // outside the action itself
-
-                } else {
-                    // unexpected, just log and retry
-                    console.log("Unexpected empty response while waiting for new activations:", activation);
-                }
-
-            } catch (e) {
-                // look for special error codes from agent
-                const errorCode = this.getActivationError(e).code;
-                // 42 => retry
-                if (errorCode === 42) {
-                    // do nothing
-                } else if (errorCode === 43) {
-                    // 43 => graceful shutdown (for unit tests)
-                    console.log("Graceful shutdown requested by agent (only for unit tests)");
-                    return null;
-                } else {
-                    // otherwise log error and abort
-                    console.error();
-                    console.error("Unexpected error while polling agent for activation:");
-                    console.dir(e, { depth: null });
-                    throw new Error("Unexpected error while polling agent for activation.");
-                }
-            }
-
-            // some small wait to avoid too many requests in case things run amok
-            await sleep(100);
-        }
-    }
-
-    getActivationError(e) {
-        if (e.error && e.error.response && e.error.response.result && e.error.response.result.error) {
-            return e.error.response.result.error;
-        }
-        return {};
-    }
-
-    async completeActivation(actionName, activationId, result, duration) {
-        console.info(`Completed activation ${activationId} in ${duration/1000.0} sec`);
-        if (this.argv.verbose) {
-            console.log(result);
-        }
-
-        try {
-            result.$activationId = activationId;
-            await this.wsk.actions.invoke({
-                name: this.concurrency ? actionName : `${actionName}_wskdebug_completed`,
-                params: result,
-                blocking: true
-            });
-        } catch (e) {
-            // look for special error codes from agent
-            const errorCode = this.getActivationError(e).code;
-            // 42 => retry
-            if (errorCode === 42) {
-                // do nothing
-            } else if (errorCode === 43) {
-                // 43 => graceful shutdown (for unit tests)
-                console.log("Graceful shutdown requested by agent (only for unit tests)");
-                this.running = false;
-            } else {
-                console.error("Unexpected error while completing activation:", e);
-            }
-        }
-    }
-
-    // ----------------------------------------< openwhisk feature detection >-----------------
-
-    async getOpenWhiskVersion() {
-        if (this.openwhiskVersion === undefined) {
-            try {
-                const json = await this.wsk.actions.client.request("GET", "/api/v1");
-                if (json && typeof json.build === "string") {
-                    this.openwhiskVersion = json.build;
-                } else {
-                    this.openwhiskVersion = null;
-                }
-            } catch (e) {
-                console.warn("Could not retrieve OpenWhisk version:", e.message);
-                this.openwhiskVersion = null;
-            }
-        }
-        return this.openwhiskVersion;
-    }
-
-    async openwhiskSupports(feature) {
-        const FEATURES = {
-            // guesstimated
-            activationListFilterOnlyBasename: v => v.startsWith("2018") || v.startsWith("2017"),
-            // hack
-            nodejs8: v => !v.startsWith("2018") && !v.startsWith("2017"),
-            concurrency: async (_, wsk) => {
-                // check swagger api docs instead of version to see if concurrency is supported
-                try {
-                    const swagger = await wsk.actions.client.request("GET", "/api/v1/api-docs");
-
-                    if (swagger && swagger.definitions && swagger.definitions.ActionLimits && swagger.definitions.ActionLimits.properties) {
-                        return swagger.definitions.ActionLimits.properties.concurrency;
-                    }
-                } catch (e) {
-                    console.warn('Could not read /api/v1/api-docs, setting max action concurrency to 1')
-                    return false;
-                }
-            }
-        };
-        const checker = FEATURES[feature];
-        if (checker) {
-            return checker(await this.getOpenWhiskVersion(), this.wsk);
-        } else {
-            throw new Error("Unknown feature " + feature);
-        }
-    }
-
-    // ------------------------------------------------< source watching >-----------------
-
-    async startSourceWatching() {
-        const watch = this.argv.watch || process.cwd();
-        if (watch &&
-            // each of these triggers listening
-            (   this.argv.livereload
-             || this.argv.onBuild
-             || this.argv.onChange
-             || this.argv.invokeParams
-             || this.argv.invokeAction )
-        ) {
-            this.liveReloadServer = livereload.createServer({
-                port: this.argv.livereloadPort,
-                noListen: !this.argv.livereload,
-                exclusions: [this.argv.buildPath, "node_modules/**"],
-                exts: this.argv.watchExts || ["json", "js", "ts", "coffee", "py", "rb", "erb", "go", "java", "scala", "php", "swift", "rs", "cs", "bal", "php", "php5"],
-                extraExts: []
-            });
-            this.liveReloadServer.watch(watch);
-
-            // overwrite function to get notified on changes
-            const refresh = this.liveReloadServer.refresh;
-            const argv = this.argv;
-            const wsk = this.wsk;
-            this.liveReloadServer.refresh = function(filepath) {
-                try {
-                    let result = [];
-
-                    if (argv.verbose) {
-                        console.log("File modified:", filepath);
-                    }
-
-                    // call original function if we are listening
-                    if (argv.livereload) {
-                        result = refresh.call(this, filepath);
-                    }
-
-                    // run build command before invoke triggers below
-                    if (argv.onBuild) {
-                        console.info("=> Build:", argv.onBuild);
-                        spawnSync(argv.onBuild, {shell: true, stdio: "inherit"});
-                    }
-
-                    // run shell command
-                    if (argv.onChange) {
-                        console.info("=> Run:", argv.onChange);
-                        spawnSync(argv.onChange, {shell: true, stdio: "inherit"});
-                    }
-
-                    // action invoke
-                    if (argv.invokeParams || argv.invokeAction) {
-                        let json = {};
-                        if (argv.invokeParams) {
-                            if (argv.invokeParams.trim().startsWith("{")) {
-                                json = JSON.parse(argv.invokeParams);
-                            } else {
-                                json = JSON.parse(fs.readFileSync(argv.invokeParams, {encoding: 'utf8'}));
-                            }
-                        }
-                        const action = argv.invokeAction || argv.action;
-                        wsk.actions.invoke({
-                            name: action,
-                            params: json
-                        }).then(response => {
-                            console.info(`=> Invoked action ${action} with params ${argv.invokeParams}: ${response.activationId}`);
-                        }).catch(err => {
-                            console.error("Error invoking action:", err);
-                        });
-                    }
-
-                    return result;
-                } catch (e) {
-                    console.error(e);
-                }
-            };
-
-            if (this.argv.livereload) {
-                console.info(`LiveReload enabled for ${watch} on port ${this.liveReloadServer.config.port}`);
-            }
-        }
-    }
-
     // ------------------------------------------------< utils >-----------------
 
     async tryCatch(task, message="Error during shutdown:") {
diff --git a/src/ngrok.js b/src/ngrok.js
new file mode 100644
index 0000000..afa01d7
--- /dev/null
+++ b/src/ngrok.js
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+'use strict';
+
+const fs = require('fs-extra');
+const http = require('http');
+const ngrok = require('ngrok');
+const url = require('url');
+const util = require('util');
+const crypto = require("crypto");
+
+class NgrokAgent {
+    constructor(argv) {
+        this.argv = argv;
+    }
+
+    async getAgent(action) {
+        if (this.argv.verbose) {
+            console.log("Setting up ngrok", this.argv.ngrokRegion ? `(region: ${this.argv.ngrokRegion})` : "");
+        }
+
+        // 1. start local server on random port
+        this.ngrokServer = http.createServer(this.ngrokHandler.bind(this));
+        // turn server.listen() into promise so we can await
+        const listen = util.promisify( this.ngrokServer.listen.bind(this.ngrokServer) );
+        await listen(0, '127.0.0.1');
+
+        // 2. start ngrok tunnel connected to that port
+        this.ngrokServerPort = this.ngrokServer.address().port;
+
+        // create a unique authorization token that we check on our local instance later
+        // this adds extra protection on top of the uniquely generated ngrok subdomain (e.g. a01ae275.ngrok.io)
+        this.ngrokAuth = crypto.randomBytes(32).toString("hex");
+        const ngrokUrl = await ngrok.connect({
+            addr: this.ngrokServerPort,
+            region: this.argv.ngrokRegion
+        });
+
+        // 3. pass on public ngrok url to agent
+        action.parameters.push({
+            key: "$ngrokUrl",
+            value: url.parse(ngrokUrl).host
+        });
+        action.parameters.push({
+            key: "$ngrokAuth",
+            value: this.ngrokAuth
+        });
+
+        console.log(`Ngrok forwarding: ${ngrokUrl} => http://localhost:${this.ngrokServerPort} (auth: ${this.ngrokAuth})`);
+
+        return fs.readFileSync(`${__dirname}/../agent/agent-ngrok.js`, {encoding: 'utf8'});
+    }
+
+    async stop() {
+        try {
+            if (this.ngrokServer) {
+                this.ngrokServer.close();
+                this.ngrokServer = null;
+            }
+        } finally {
+            await ngrok.kill();
+        }
+    }
+
+    // local http server retrieving forwards from the ngrok agent, running them
+    // as a blocking local invocation and then returning the activation result back
+    ngrokHandler(req, res) {
+        // check authorization against our unique token
+        const authHeader = req.headers.authorization;
+        if (authHeader !== this.ngrokAuth) {
+            res.statusCode = 401;
+            res.end();
+            return;
+        }
+
+        if (req.method === 'POST') {
+            // agent POSTs arguments as json body
+            let body = '';
+            // collect full request body first
+            req.on('data', chunk => {
+                body += chunk.toString();
+            });
+            req.on('end', async () => {
+                try {
+                    const params = JSON.parse(body);
+                    const id = params.$activationId;
+                    delete params.$activationId;
+
+                    if (this.argv.verbose) {
+                        console.log();
+                        console.info(`Activation: ${id}`);
+                        console.log(params);
+                    } else {
+                        console.info(`Activation: ${id}`);
+                    }
+
+                    const startTime = Date.now();
+
+                    const result = await this.invoker.run(params, id);
+
+                    const duration = Date.now() - startTime;
+                    console.info(`Completed activation ${id} in ${duration/1000.0} sec`);
+                    if (this.argv.verbose) {
+                        console.log(result);
+                    }
+
+                    res.statusCode = 200;
+                    res.setHeader("Content-Type", "application/json");
+                    res.end(JSON.stringify(result));
+
+                } catch (e) {
+                    console.error(e);
+                    res.statusCode = 400;
+                    res.end();
+                }
+            });
+        } else {
+            res.statusCode = 404;
+            res.end();
+        }
+    }
+}
+
+module.exports = NgrokAgent;
\ No newline at end of file
diff --git a/src/watcher.js b/src/watcher.js
new file mode 100644
index 0000000..d69b554
--- /dev/null
+++ b/src/watcher.js
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+'use strict';
+
+const fs = require('fs-extra');
+const livereload = require('livereload');
+const { spawnSync } = require('child_process');
+
+class Watcher {
+    constructor(argv, wsk) {
+        this.argv = argv;
+        this.wsk = wsk;
+    }
+
+    async start() {
+        const watch = this.argv.watch || process.cwd();
+        if (watch &&
+            // each of these triggers listening
+            (   this.argv.livereload
+             || this.argv.onBuild
+             || this.argv.onChange
+             || this.argv.invokeParams
+             || this.argv.invokeAction )
+        ) {
+            this.liveReloadServer = livereload.createServer({
+                port: this.argv.livereloadPort,
+                noListen: !this.argv.livereload,
+                exclusions: [this.argv.buildPath, "node_modules/**"],
+                exts: this.argv.watchExts || ["json", "js", "ts", "coffee", "py", "rb", "erb", "go", "java", "scala", "php", "swift", "rs", "cs", "bal", "php", "php5"],
+                extraExts: []
+            });
+            this.liveReloadServer.watch(watch);
+
+            // overwrite function to get notified on changes
+            const refresh = this.liveReloadServer.refresh;
+            const argv = this.argv;
+            const wsk = this.wsk;
+            this.liveReloadServer.refresh = function(filepath) {
+                try {
+                    let result = [];
+
+                    if (argv.verbose) {
+                        console.log("File modified:", filepath);
+                    }
+
+                    // call original function if we are listening
+                    if (argv.livereload) {
+                        result = refresh.call(this, filepath);
+                    }
+
+                    // run build command before invoke triggers below
+                    if (argv.onBuild) {
+                        console.info("=> Build:", argv.onBuild);
+                        spawnSync(argv.onBuild, {shell: true, stdio: "inherit"});
+                    }
+
+                    // run shell command
+                    if (argv.onChange) {
+                        console.info("=> Run:", argv.onChange);
+                        spawnSync(argv.onChange, {shell: true, stdio: "inherit"});
+                    }
+
+                    // action invoke
+                    if (argv.invokeParams || argv.invokeAction) {
+                        let json = {};
+                        if (argv.invokeParams) {
+                            if (argv.invokeParams.trim().startsWith("{")) {
+                                json = JSON.parse(argv.invokeParams);
+                            } else {
+                                json = JSON.parse(fs.readFileSync(argv.invokeParams, {encoding: 'utf8'}));
+                            }
+                        }
+                        const action = argv.invokeAction || argv.action;
+                        wsk.actions.invoke({
+                            name: action,
+                            params: json
+                        }).then(response => {
+                            console.info(`=> Invoked action ${action} with params ${argv.invokeParams}: ${response.activationId}`);
+                        }).catch(err => {
+                            console.error("Error invoking action:", err);
+                        });
+                    }
+
+                    return result;
+                } catch (e) {
+                    console.error(e);
+                }
+            };
+
+            if (this.argv.livereload) {
+                console.info(`LiveReload enabled for ${watch} on port ${this.liveReloadServer.config.port}`);
+            }
+        }
+    }
+
+    async stop() {
+        if (this.liveReloadServer) {
+            if (this.liveReloadServer.server) {
+                this.liveReloadServer.close();
+            } else {
+                this.liveReloadServer.watcher.close();
+            }
+            this.liveReloadServer = null;
+        }
+    }
+}
+
+module.exports = Watcher;
\ No newline at end of file
