initial support for debugging sequences
diff --git a/client/lib/rewriter.js b/client/lib/rewriter.js
index 541fa31..1323799 100644
--- a/client/lib/rewriter.js
+++ b/client/lib/rewriter.js
@@ -10,7 +10,7 @@
     };
 
 /** the dictionary of live attachments to actions */
-var attached = {};
+var attached = {}, chainAttached = {};
 var created = {};
 
 function echoContinuation(entity, entityNamespace) {
@@ -46,7 +46,7 @@
     return function(err) {
 	console.error('Error ' + inOperation);
 	console.error(err);
-	callback();
+	callback && callback();
     };
 }
 
@@ -207,6 +207,46 @@
 	}, errorWhile('cleaning actions and triggers', next));
 };
 
+function createUpstreamAdapterNames(continuationName) {
+    return {
+	ruleName: Namer.name('continuation-rule'),
+	triggerName: Namer.name('continuation-trigger'),
+	continuationName: continuationName || Namer.name('continuation-action'),
+	createContinuationPlease: !continuationName,
+	debugStubName: Namer.name('stub')
+    };
+}
+
+function createUpstreamAdapter(ow, actionBeingDebugged, actionBeingDebuggedNamespace, names) {
+    try {
+	var work = [
+	    ow.triggers.create(names),
+	    ow.packages.create({ packageName: names.debugStubName,
+				 package: {
+				     binding: {
+					 namespace: invokerPackageNamespace,
+					 name: invokerPackageName
+				     },
+				     parameters: [{ key: 'action', value: actionBeingDebugged },
+						  { key: 'namespace', value: actionBeingDebuggedNamespace },
+						  { key: 'onDone_trigger', value: names.triggerName }
+						 ]
+				 }
+			       })
+	];
+	if (names.createContinuationPlease) {
+	    work.push(ow.actions.create({ actionName: names.continuationName, action: echoContinuation(actionBeingDebugged,
+												       actionBeingDebuggedNamespace) }));
+	}
+	return Promise.all(work)
+	    .then(() => ow.rules.create({ ruleName: names.ruleName, trigger: names.triggerName, action: names.continuationName }),
+		  errorWhile('creating upstream adapter part 1'))
+	    .then(() => names, errorWhile('creating upstream adapter part 2'));
+    } catch (e) {
+	console.error(e);
+    }
+}
+
 /**
  * Create a rule splice
  */
@@ -216,7 +256,7 @@
 	    debugStubName: Namer.name('stub'),
 	    triggerName: Namer.name('continuation-trigger'),
 	    continuationName: Namer.name('continuation-action'),
-	    ruleName: Namer.name('continuation-rule'),
+	    ruleName: Namer.name('continuation-rule')
 	};
 
 	Promise.all([ow.triggers.create(names),
@@ -228,19 +268,22 @@
 						  name: invokerPackageName
 					      },
 					      parameters: [{ key: 'action', value: entity },
-							   { key: 'namespace', value: entityNamespace }
+							   { key: 'namespace', value: entityNamespace },
+							   { key: 'onDone_trigger', value: names.triggerName }
 							  ]
 					  }
 					})
 		    ])
-	    .then(function() {
+	    .then(function onSuccessOfPart1() {
 		ow.rules
 		    .create({ ruleName: names.ruleName, trigger: names.triggerName, action: names.continuationName })
 		    .then(function() { next(names); },
 			  errorWhile('attaching to action', next));
-	    });
+	    }, errorWhile('attaching to action', next));
+
     } catch (e) {
 	console.error(e);
+	next();
     }
 }
 
@@ -255,10 +298,10 @@
 }
 
 function beforeSpliceSplitter(element, replacement, A) { A = A.slice(0, A.indexOf(element)); A.push(replacement); return A; }
-function afterSpliceSplitter(element, replacement, A) { A = A.slice(A.indexOf(element)); A[0] = replacement; return A; }
-function makeSequenceSplicePart(ow, sequence, splitter) {
+function afterSpliceSplitter(element, tackOnTheEnd, A) { A = A.slice(A.indexOf(element) + 1); return A; }
+function makeSequenceSplicePart(ow, name, sequence, splitter) {
     var opts = {
-	actionName: Namer.name('sequence-splice'),
+	actionName: name,
 	action: {
 	    exec: {
 		kind: sequence.exec.kind,
@@ -270,11 +313,48 @@
     return ow.actions.create(opts);
 }
 function spliceSequence(ow, sequence, entity, entityNamespace, names) {
+    try {
+	var finalBit = undefined/*{
+	    actionName: Namer.name('action'),
+	    action: echoContinuation(entity, entityNamespace, spliceNames.onDone_trigger)
+	};*/
+	
     var fqn = '/' + entityNamespace + '/' + entity;
+
+    var afterSpliceContinuation = Namer.name('sequence-splice-after');
+    var upstreamAdapterNames = createUpstreamAdapterNames(afterSpliceContinuation);
+
+	var beforeSpliceUpstream = '/' + entityNamespace + '/' + upstreamAdapterNames.debugStubName + '/' + invokerActionName;
+    //var afterSpliceContinuation = '/' + entityNamespace + '/' + upstreamAdapterNames.continuationName;
+
     return Promise.all([
-	makeSequenceSplicePart(ow, sequence, beforeSpliceSplitter.bind(undefined, fqn, names.debugStubName + '/' + invokerActionName)),
-	makeSequenceSplicePart(ow, sequence, afterSpliceSplitter.bind(undefined, fqn, '/' + entityNamespace + '/' + names.continuationName))
-    ]);
+	makeSequenceSplicePart(ow,
+			       Namer.name('sequence-splice-before'),
+			       sequence,
+			       beforeSpliceSplitter.bind(undefined, fqn, beforeSpliceUpstream)),   // before: _/--upstream
+	makeSequenceSplicePart(ow,
+			       afterSpliceContinuation,
+			       sequence,
+			       afterSpliceSplitter.bind(undefined, fqn, finalBit)) // after: -\__continuation
+
+    ]).then((beforeAndAfter) => { // a destructuring bind would clean this up
+	// after the breakpoint, continue with the afterSplice
+	return createUpstreamAdapter(ow, entity, entityNamespace, upstreamAdapterNames)
+	    .then(() => {
+		//
+		// this sequence splice uses its own downstream trigger, not the generic one from the action splice
+		//
+		return chainAttached[sequence.name] = {
+		    before: beforeAndAfter[0].name,
+		    after: beforeAndAfter[1].name,
+		    triggerName: upstreamAdapterNames.triggerName
+		};
+
+	    }, errorWhile('creating upstream adapter'));
+    }, errorWhile('splicing sequence'));
+    } catch (e) {
+	console.error(e);
+    }
 }
 
 /**
@@ -298,7 +378,7 @@
 	    }
 	    _list(ow, function onList(entities) {
 		var counter = entities.length;
-		function countDown() {
+		function countDown(names) {
 		    if (--counter <= 0) {
 			ok_(next);
 		    }
@@ -351,11 +431,30 @@
 };
 
 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);
 
     function errlog(idx, noNext) {
 	return function(err) {
-	    if (err.indexOf('HTTP 404') < 0) {
+	    if (err.indexOf && err.indexOf('HTTP 404') < 0) {
 		console.error('Error ' + idx, err);
 	    }
 	    if (!noNext) next();
@@ -366,18 +465,22 @@
     if (names) {
 	try {
 	    var ow = setupOpenWhisk(wskprops);
-	    //console.log('D1');
 	    ow.rules.disable(names).then(function() {
 		try {
-		    //console.log('D2');
+		    // first delete the action and rule and debug package
 		    Promise.all([ow.triggers.delete(names),
 				 ow.actions.delete({ actionName: names.continuationName }),
 				 ow.packages.delete({ packageName: names.debugStubName })
 				])
 			.then(function(values) {
-			    //console.log('D3');
+			    // then we can delete the rule
 			    ow.rules.delete(names).then(function() {
-				try { delete attached[entity]; ok_(next()); } catch (err) { errlog(5, true)(err); }
+				try {
+				    delete attached[entity];
+				    ok_(next);
+				} catch (err) {
+				    errlog(5, true)(err);
+				}
 			    }, errlog(4));
 			}, errlog(3));
 		} catch (err) { errlog(2, true)(err); }
@@ -388,6 +491,10 @@
     }
 };
 
+/**
+ * Invoke an action
+ *
+ */
 exports.invoke = function invoke() {
     try {
 	exports._invoke.apply(undefined, arguments);
@@ -413,8 +520,15 @@
     
     var attachedTo = attached[action];
     if (!attachedTo) {
-	invokeThisAction = action;
-	waitForThisAction = action;
+	var seq = chainAttached[action];
+	if (seq) {
+	    invokeThisAction = seq.before;
+	    waitForThisAction = seq.after;
+
+	} else {
+	    invokeThisAction = action;
+	    waitForThisAction = action;
+	}
 
     } else {
 	invokeThisAction = attachedTo.debugStubName + '/' + invokerActionName;
@@ -422,12 +536,12 @@
 	// these are now part of the debug stub binding
 	// params.action = action;
 	// params.namespace = namespace;
+	// params.onDone_trigger = attachedTo.triggerName;
 
-	params.onDone_trigger = attachedTo.triggerName;
 	waitForThisAction = attachedTo.continuationName;
     }
 
-    //console.log('PARAMS', invokeThisAction, params);
+    console.log('Invoking', invokeThisAction, waitForThisAction, params);
 
     var key = wskprops['AUTH'];
     var ow = setupOpenWhisk(wskprops);
@@ -440,13 +554,13 @@
     ow.actions.invoke({
 	actionName: invokeThisAction,
 	params: params
-    }).then(function(activation) {
+    }).then(function onSuccess(activation) {
 	if (activation && activation.activationId) {
 	    // successfully invoked
 	    if (!attachedTo) {
 		console.log('Successfully invoked with activationId', activation.activationId);
 	    } else {
-
+		// we'll wait for the result...
 	    }
 
 	    //
@@ -468,5 +582,8 @@
 		});
 	    }, 1000);
 	}
+    }, function onError(err) {
+	console.error('Unable to invoke your specified action');
+	next();
     });
 }