incorporate jshint, and clean up jshint errors
diff --git a/client/.jshintrc b/client/.jshintrc
new file mode 100644
index 0000000..6adc52f
--- /dev/null
+++ b/client/.jshintrc
@@ -0,0 +1,74 @@
+{

+

+	"bitwise" : true,

+	"curly" : true,

+	"eqeqeq" : true,

+	"forin" : true,

+	"immed" : true,

+	"latedef" : true,

+	"newcap" : true,

+	"noarg" : true,

+	"noempty" : false,

+	"nonew" : true,

+	"plusplus" : false,

+	"quotmark" : "single",

+	"regexp" : true,

+	"undef" : true,

+	"strict" : false,

+	"trailing" : true,

+

+	"asi" : false,

+	"boss" : false,

+	"debug" : false,

+	"eqnull" : false,

+	"esnext" : false,

+	"esversion": 6,

+	"evil" : false,

+	"expr" : false,

+	"funcscope" : false,

+	"globalstrict" : false,

+	"globals": { "angular": false },

+	"iterator" : false,

+	"lastsemic" : false,

+	"laxbreak" : true,

+	"laxcomma" : true,

+	"loopfunc" : true,

+	"maxerr" : 9999,

+	"moz" : false,

+	"multistr" : false,

+	"onecase" : false,

+	"proto" : false,

+	"regexdash" : false,

+	"scripturl" : false,

+	"smarttabs" : false,

+	"shadow" : false,

+	"sub" : false,

+	"supernew" : false,

+	"validthis" : false,

+

+	"browser" : true,

+	"couch" : false,

+	"devel" : false,

+	"dojo" : false,

+	"jquery" : true,

+	"mootools" : false,

+	"node" : true,

+	"nonstandard" : false,

+	"phantom" : false,

+	"prototypejs" : false,

+	"rhino" : false,

+	"worker" : false,

+	"wsh" : false,

+	"yui" : false,

+

+	"nomen" : false,

+	"onevar" : false,

+	"passfail" : false,

+	"white" : false,

+

+	"predef" : [

+

+		"Java", "JavaFX", "$ARG"

+	]

+

+}

diff --git a/client/lib/debug-bootstrap.js b/client/lib/debug-bootstrap.js
index 37303be..b841532 100644
--- a/client/lib/debug-bootstrap.js
+++ b/client/lib/debug-bootstrap.js
@@ -16,7 +16,9 @@
 
 	// if you want to insert a breakpoint just before exit
 	if (breakAtExit) {
+	    /* jshint ignore:start */
 	    debugger;
+	    /* jshint ignore:end */
 	}
 
 	console.log('Returning ' + JSON.stringify(result, undefined, 4));
diff --git a/client/lib/debug-nodejs.js b/client/lib/debug-nodejs.js
index e7c11f9..894895e 100644
--- a/client/lib/debug-nodejs.js
+++ b/client/lib/debug-nodejs.js
@@ -26,11 +26,11 @@
     } catch (e) {
 	console.error(e);
     }
-}
+};
 exports._debug = function debugNodeJS(message, ws, echoChamberNames, done, commandLineOptions) {
     var code = message.action.exec.code;
 
-    var r = new RegExp(/main[\s]*\([^\)]*\)/)
+    var r = new RegExp(/main[\s]*\([^\)]*\)/);
     var startOfMethodBody = code.search(r);
     if (startOfMethodBody >= 0) {
 	var paren = code.indexOf('{', startOfMethodBody);
@@ -44,7 +44,7 @@
     bootstrap += 'ow = openwhisk({api: \'' + api.host + api.path + '\', api_key: \'' + message.key + '\', namespace: \'' + message.action.namespace + '\' });\n';
     bootstrap += 'ow.triggers.invoke({ triggerName: \'' + echoChamberNames.trigger + '\', params: result });\n';*/
 
-    code += '\n\n//\n'
+    code += '\n\n//\n';
     code += '// Welcome to the OpenWhisk debugger.\n';
     code += '//\n';
     code += '// To proceed with debugging, press the continue => button.\n';
@@ -59,7 +59,7 @@
 
             // we need to update the NODE_PATH env var, to add our local modules
 	    var env = Object.assign({}, process.env);
-	    env['NODE_PATH'] = path.join(process.cwd(), 'node_modules')
+	    env.NODE_PATH = path.join(process.cwd(), 'node_modules')
 		+ ':' + path.join(process.cwd(), 'lib');
 
 	    function trySpawnWithBrowser(webPort, debugPort) {
@@ -103,7 +103,7 @@
 			//
 			// ignore some internal errors in node-inspector
 			//
-			console.error('stderr: ' + message)
+			console.error('stderr: ' + message);
 		    }
 		});
 
@@ -161,4 +161,4 @@
 	    console.error(e);
 	}
     });
-}
+};
diff --git a/client/lib/repl.js b/client/lib/repl.js
index 03de488..c48ee81 100644
--- a/client/lib/repl.js
+++ b/client/lib/repl.js
@@ -19,6 +19,7 @@
     rewriter = require('./rewriter'),
     columnify = require('columnify');
 
+var commandHandlers; // defined below. helping out jshint here
 var help = {
     handler: function help() {
 	console.log('The available commands are:');
@@ -26,72 +27,74 @@
 
 	var grouped = {};
 	for (var x in commandHandlers) {
-	    var already = grouped[commandHandlers[x].description];
-	    if (already) {
-		grouped[commandHandlers[x].description] = already + ", " + x;
-	    } else {
-		grouped[commandHandlers[x].description] = x;
+	    if (commandHandlers.hasOwnProperty(x)) {
+		var already = grouped[commandHandlers[x].description];
+		if (already) {
+		    grouped[commandHandlers[x].description] = already + ', ' + x;
+		} else {
+		    grouped[commandHandlers[x].description] = x;
+		}
 	    }
 	}
 	
 	var pruned = [];
 	for (var d in grouped) {
-	    pruned.push({ command: grouped[d], description: d });
+	    if (grouped.hasOwnProperty(d)) {
+		pruned.push({ command: grouped[d], description: d });
+	    }
 	}
 
 	console.log(columnify(pruned, { minWidth: 18 }));
     },
-    description: "Print this help text"
+    description: 'Print this help text'
 };
 var attach = {
     handler: rewriter.attach,
     enumerate: rewriter.list,
-    description: "Attach to an action",
+    description: 'Attach to an action',
     synchronous: true,
     options: [{ name: 'action-only', short: 'a', type: 'string', description: 'Instrument just the action, not any rules or sequences in which it takes part' }]
 };
 var detach = {
     handler: rewriter.detach,
-    description: "Detatch from an action",
+    description: 'Detatch from an action',
     synchronous: true
 };
 var exit = {
     handler: function(wskprops) {
-	//console.log("Cleaning up".red);
+	//console.log('Cleaning up'.red);
 	rewriter.detachAll(wskprops, process.exit);
     },
-    description: "Quit the debugger",
+    description: 'Quit the debugger',
     synchronous: true
 };
 var invoke = {
     handler: rewriter.invoke,
-    description: "Invoke an action",
+    description: 'Invoke an action',
     synchronous: true
 };
 var list = {
     handler: rewriter.listToConsole,
-    description: "List available actions",
+    description: 'List available actions',
     synchronous: true,
     options: [{ name: 'full', short: 'f', type: 'string', description: 'Show all actions, including debugging artifacts' }]
 };
 var clean = {
     handler: rewriter.clean,
-    description: "Clean up debugging artifacts",
+    description: 'Clean up debugging artifacts',
     synchronous: true
 };
 var create = {
     handler: rewriter.create,
-    description: "Create an action",
+    description: 'Create an action',
     synchronous: true
 };
 var deleteAction = {
     handler: rewriter.deleteAction,
-    description: "Delete an action",
+    description: 'Delete an action',
     synchronous: true
 };
-
-
-var commandHandlers = {
+commandHandlers = {
     list: list,
     l: list,
     
@@ -126,10 +129,10 @@
 	prefixMessage: '', // override the default question mark prefix
 	validate: function(line) {
 	    var commandLine = line.split(/\s+/);
-	    return line.length == 0 || commandHandlers[commandLine[0]] ? true : "Invalid command";
+	    return line.length === 0 || commandHandlers[commandLine[0]] ? true : 'Invalid command';
 	}
     }]).then(function(response) {
-	if (response.command.length == 0) {
+	if (response.command.length === 0) {
 	    // user hit return;
 	    return repl(wskprops);
 	}
@@ -142,10 +145,10 @@
 	if (handler.options) {
 	    argv.clear();
 	    argv.description = 'Usage: ' + command + ' [options]';
-	    argv.options.help.example = "";
+	    argv.options.help.example = '';
 	    argv.options.help.onset = (args) => {
 		argv.help(args.mod);
-	    }
+	    };
 	    options = argv.option(handler.options).run(commandLine).options;
 	}
 
diff --git a/client/lib/rewriter.js b/client/lib/rewriter.js
index 14dfa3d..037f5cb 100644
--- a/client/lib/rewriter.js
+++ b/client/lib/rewriter.js
@@ -44,8 +44,8 @@
  *
  */
 function setupOpenWhisk(wskprops) {
-    var key = wskprops['AUTH'];
-    var namespace = wskprops['NAMESPACE'];
+    var key = wskprops.AUTH;
+    var namespace = wskprops.NAMESPACE;
     var ow = openwhisk({
 	api: api.host + api.path,
 	api_key: key,
@@ -62,7 +62,9 @@
     return function(err) {
 	console.error('Error ' + inOperation);
 	console.error(err);
-	callback && callback();
+	if (callback) {
+	    callback();
+	}
     };
 }
 
@@ -86,23 +88,25 @@
 	return Namer.prefix + (extra ? extra + '-' : '') + uuid.v4();
     },
     isDebugArtifact: function(name) {
-	return name.indexOf(Namer.prefix) == 0;
+	return name.indexOf(Namer.prefix) === 0;
     }
 };
 
-exports.list = function list(wskprops, callback, type) {
-    var ow = setupOpenWhisk(wskprops);
-    _list(ow, callback, type);
-};
 function _list(ow, callback, type) {
     ow[type || 'actions']
 	.list({ limit: 200 })
 	.then(function onList(L) { callback(L, ow); },
 	      errorWhile('fetching actions', callback));
 }
+exports.list = function list(wskprops, callback, type) {
+    var ow = setupOpenWhisk(wskprops);
+    _list(ow, callback, type);
+};
 
 exports.listToConsole = function listToConsole(wskprops, options, next) {
-    if (options.help) return next();
+    if (options.help) {
+	return next();
+    }
 
     console.log('Available actions:'.blue);
     function print(actions) {
@@ -132,9 +136,16 @@
     questions.push({ name: 'code', type: 'editor',
 		     message: 'Please provide the function body for your new action',
 		     default: function(response) {
-			 if (response.kind == 'nodejs') return 'function main(params) {\n    return { message: \'hello\' };\n}\n'
-			 else if (response.kind == 'swift') return 'func main(args: [String:Any]) -> [String:Any] {\n      return [ "message" : "Hello world" ]\n}\n'
-			 else return 'import sys\n\ndef main(dict):\n    return { \'message\': \'Hello world\' }\n'
+			 if (response.kind === 'nodejs') {
+			     // nodejs
+			     return 'function main(params) {\n    return { message: \'hello\' };\n}\n';
+			 } else if (response.kind === 'swift') {
+			     // swift
+			     return 'func main(args: [String:Any]) -> [String:Any] {\n      return [ "message" : "Hello world" ]\n}\n';
+			 } else {
+			     // python
+			     return 'import sys\n\ndef main(dict):\n    return { \'message\': \'Hello world\' }\n';
+			 }
 		     }
 		   });
 
@@ -198,11 +209,11 @@
 		});
 		var counter = toClean.length;
 		
-		if (counter == 0) {
+		if (counter === 0) {
 		    return resolve(toClean.length);
 		}
 		function countDown() {
-		    if (--counter == 0) {
+		    if (--counter === 0) {
 			resolve(toClean.length);
 		    }
 		}
@@ -223,7 +234,7 @@
 	.then(function() {
 	    cleanType('rule')
 		.then(ok(next),
-		      errorWhile('cleaning rules', next))
+		      errorWhile('cleaning rules', next));
 	}, errorWhile('cleaning actions and triggers', next));
 };
 
@@ -307,14 +318,16 @@
     }
 }
 
-function sequenceUses(maybeUsingEntity, entity, entityNamespace) {
+/**
+ * Does the given sequence entity use the given action entity located in the given entityNamespace?
+ *
+ */
+function sequenceUses(sequenceEntityThatMaybeUses, entity, entityNamespace) {
     var fqn = '/' + entityNamespace + '/' + entity;
 
-    return maybeUsingEntity.name !== entity
-	&& maybeUsingEntity.exec && maybeUsingEntity.exec.kind == 'sequence'
-	&& maybeUsingEntity.exec.components && maybeUsingEntity.exec.components.find(function(c) {
-	    return c === fqn;
-	});
+    return sequenceEntityThatMaybeUses.name !== entity
+	&& sequenceEntityThatMaybeUses.exec && sequenceEntityThatMaybeUses.exec.kind === 'sequence'
+	&& sequenceEntityThatMaybeUses.exec.components && sequenceEntityThatMaybeUses.exec.components.find((c) => c === fqn);
 }
 
 function beforeSpliceSplitter(element, replacement, A) { A = A.slice(0, A.indexOf(element)); A.push(replacement); return A; }
@@ -334,7 +347,7 @@
 }
 function spliceSequence(ow, sequence, entity, entityNamespace, names) {
     try {
-	var finalBit = undefined/*{
+	var finalBit;/*{
 	    actionName: Namer.name('action'),
 	    action: echoContinuation(entity, entityNamespace, spliceNames.onDone_trigger)
 	};*/
@@ -364,11 +377,13 @@
 		//
 		// this sequence splice uses its own downstream trigger, not the generic one from the action splice
 		//
-		return chainAttached[sequence.name] = {
+		var names = {
 		    before: beforeAndAfter[0].name,
 		    after: beforeAndAfter[1].name,
 		    triggerName: upstreamAdapterNames.triggerName
 		};
+		chainAttached[sequence.name] = names;
+		return names;
 
 	    }, errorWhile('creating upstream adapter'));
     }, errorWhile('splicing sequence'));
@@ -382,12 +397,14 @@
  *
  */
 exports.attach = function attach(wskprops, options, next, entity) {
-    if (options.help) return next();
+    if (options.help) {
+	return next();
+    }
 
     console.log('Attaching'.blue + ' to ' + entity);
 
     try {
-	var entityNamespace = wskprops['NAMESPACE'];
+	var entityNamespace = wskprops.NAMESPACE;
 	var ow = setupOpenWhisk(wskprops);
 
 	console.log('   Creating action trampoline'.green);
@@ -407,7 +424,10 @@
 		}
 		entities.forEach(function(otherEntity) {
 		    if (otherEntity.name === entity) {
+			// this is the entity itself. skip, because
+			// we're looking for uses in *other* entities
 			countDown();
+
 		    } else {
 			ow.actions.get({ actionName: otherEntity.name, namespace: otherEntity.namespace })
 			    .then(function(sequenceWithDetails) {
@@ -435,42 +455,29 @@
     var count = 0;
     function done() {
 	if (--count <= 0) {
-	    next && next();
+	    if (next) {
+		next();
+	    }
 	}
     }
     
     for (var entity in attached) {
-	count++;
+	if (attached.hasOwnProperty(entity)) {
+	    count++;
+	}
     }
 
-    if (count == 0) {
+    if (count === 0) {
 	done();
     } else {
-	for (var entity in attached) {
-	    exports.detach(wskprops, done, entity);
+	for (entity in attached) {
+	    if (attached.hasOwnProperty(entity)) {
+		exports.detach(wskprops, done, entity);
+	    }
 	}
     }
 };
 
-exports.detach = function detach(wskprops, next, entity) {
-    if (!entity) {
-	var L = [];
-	for (var x in attached) { L.push(x); }
-	if (L.length === 0) {
-	    console.error("No attached actions detected");
-	    next();
-	} else {
-	    require('inquirer')
-		.prompt([{ name: 'name', type: 'list',
-			   message: 'From which action do you wish to detach',
-			   choices: L
-			 }])
-		.then(function(response) { doDetach(wskprops, next, response.name); });
-	}
-    } else {
-	doDetach(wskprops, next, entity);
-    }
-}
 function doDetach(wskprops, next, entity) {
     console.log('Detaching'.blue + ' from ' + entity);
 
@@ -479,7 +486,9 @@
 	    if (err.indexOf && err.indexOf('HTTP 404') < 0) {
 		console.error('Error ' + idx, err);
 	    }
-	    if (!noNext) next();
+	    if (!noNext) {
+		next();
+	    }
 	};
     }
     
@@ -511,6 +520,29 @@
 	    console.error(e);
 	}
     }
+}
+exports.detach = function detach(wskprops, next, entity) {
+    if (!entity) {
+	var L = [];
+	for (var x in attached) {
+	    if (attached.hasOwnProperty(x)) {
+		L.push(x);
+	    }
+	}
+	if (L.length === 0) {
+	    console.error('No attached actions detected');
+	    next();
+	} else {
+	    require('inquirer')
+		.prompt([{ name: 'name', type: 'list',
+			   message: 'From which action do you wish to detach',
+			   choices: L
+			 }])
+		.then(function(response) { doDetach(wskprops, next, response.name); });
+	}
+    } else {
+	doDetach(wskprops, next, entity);
+    }
 };
 
 /**
@@ -527,13 +559,13 @@
 exports._invoke = function invoke() {
     var args = Array.prototype.slice.call(arguments);
     var wskprops = args.shift();
-    var namespace = wskprops['NAMESPACE'];
+    var namespace = wskprops.NAMESPACE;
     var next = args.shift();
     var action = args.shift();
 
     var params = {};
     for (var i = 0; i < args.length; i++) {
-	if (args[i] == '-p') {
+	if (args[i] === '-p') {
 	    params[args[++i]] = args[++i];
 	}
     }
@@ -569,7 +601,7 @@
 	return next();
     }
 
-    var key = wskprops['AUTH'];
+    var key = wskprops.AUTH;
     var ow = setupOpenWhisk(wskprops);
     var owForActivations = openwhisk({
 	api: api.host + api.path,
@@ -596,7 +628,7 @@
 		owForActivations.activations.list({ limit: 10 }).then(function(list) {
 		    for (var i = 0; i < list.length; i++) {
 			var activation = list[i];
-			if (activation.name == waitForThisAction) {
+			if (activation.name === waitForThisAction) {
 			    clearInterval(timer);
 			    owForActivations.activations.get({ activation: activation.activationId }).then(function(activation) {
 				console.log(JSON.stringify(activation, undefined, 4));
@@ -612,4 +644,4 @@
 	console.error('Unable to invoke your specified action');
 	next();
     });
-}
+};
diff --git a/client/package.json b/client/package.json
index a640fb5..55096ae 100644
--- a/client/package.json
+++ b/client/package.json
@@ -5,7 +5,7 @@
   "repository": "https://github.ibm.com/nickm/owdbg",
   "main": "client.js",
   "scripts": {
-    "test": "ava --verbose"
+    "test": "./node_modules/.bin/jshint wskdb.js lib/*.js && ava --verbose"
   },
   "author": "",
   "license": "ISC",
@@ -25,6 +25,7 @@
     "ws": "^1.1.1"
   },
   "devDependencies": {
-    "ava": "^0.16.0"
+    "ava": "^0.16.0",
+    "jshint": "^2.9.3"
   }
 }
diff --git a/client/wskdb.js b/client/wskdb.js
index 77a6e59..7e1853c 100644
--- a/client/wskdb.js
+++ b/client/wskdb.js
@@ -47,13 +47,15 @@
 
     if (commandLineOptions) {
 	for (var x in commandLineOptions) {
-	    console.log(('    + ' + commandLineOptionsConfig.find((o) => o.name == x).description).dim);
+	    if (commandLineOptions.hasOwnProperty(x)) {
+		console.log(('    + ' + commandLineOptionsConfig.find((o) => o.name === x).description).dim);
+	    }
 	}
     }
     console.log();
 
     var wskprops = propertiesParser.read(expandHomeDir('~/.wskprops'));
-    var key = wskprops['AUTH'];
+    var key = wskprops.AUTH;
     ws.send(JSON.stringify({
 	type: 'init',
 	key: key
@@ -68,7 +70,7 @@
     process.on('exit', function onExit() {
     try {
 	console.log('Goodbye!'.red);
-	clearTimer(keepAlive);
+	clearInterval(keepAlive);
 
 	ws.send(JSON.stringify({
 	    type: 'disconnect'
@@ -101,7 +103,7 @@
 	    console.log('Debug session requested');
 	    //console.log(JSON.stringify(message, undefined, 4));
 
-	    function done(err, result) {
+	    var done = function done(err, result) {
 		// console.log('Finishing up this debug session');
 
 		ws.send(JSON.stringify({
@@ -112,17 +114,14 @@
 		}));
 
 		//ws.close();
-	    }
-	    function circuitBreaker() {
+	    };
+	    var circuitBreaker = function circuitBreaker() {
 		ws.send(JSON.stringify({
 			type: 'circuit-breaker',
 			key: message.key,
 			activationId: message.activationId,
 		}));
-	    }
-	    function next(echoChamberNames) {
-	    }
-	    var nextOnErr = done.bind(undefined, true);
+	    };
 
 	    if (message.onDone_trigger) {
 		if (message.action && message.action.exec && message.action.exec.kind.indexOf('nodejs') >= 0) {