Merge "veyron/lib/bluetooth: Make the bluetooth net.Conn and net.Listener implementations amenable to concurrent method invocations."
diff --git a/examples/bank/bank.vdl.go b/examples/bank/bank.vdl.go
index 207d354..6156492 100644
--- a/examples/bank/bank.vdl.go
+++ b/examples/bank/bank.vdl.go
@@ -18,7 +18,7 @@
 	_gen_ipc "veyron2/ipc"
 	_gen_naming "veyron2/naming"
 	_gen_rt "veyron2/rt"
-	_gen_vdl "veyron2/vdl"
+	_gen_vdlutil "veyron2/vdl/vdlutil"
 	_gen_wiretype "veyron2/wiretype"
 )
 
@@ -60,10 +60,10 @@
 		case _gen_ipc.Client:
 			client = o
 		default:
-			return nil, _gen_vdl.ErrUnrecognizedOption
+			return nil, _gen_vdlutil.ErrUnrecognizedOption
 		}
 	default:
-		return nil, _gen_vdl.ErrTooManyOptionsToBind
+		return nil, _gen_vdlutil.ErrTooManyOptionsToBind
 	}
 	stub := &clientStubBank{client: client, name: name}
 
@@ -160,7 +160,7 @@
 		},
 	}
 
-	result.TypeDefs = []_gen_vdl.Any{
+	result.TypeDefs = []_gen_vdlutil.Any{
 		_gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}}
 
 	return result, nil
@@ -238,10 +238,10 @@
 		case _gen_ipc.Client:
 			client = o
 		default:
-			return nil, _gen_vdl.ErrUnrecognizedOption
+			return nil, _gen_vdlutil.ErrUnrecognizedOption
 		}
 	default:
-		return nil, _gen_vdl.ErrTooManyOptionsToBind
+		return nil, _gen_vdlutil.ErrTooManyOptionsToBind
 	}
 	stub := &clientStubBankAccount{client: client, name: name}
 
@@ -401,7 +401,7 @@
 		},
 	}
 
-	result.TypeDefs = []_gen_vdl.Any{
+	result.TypeDefs = []_gen_vdlutil.Any{
 		_gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}}
 
 	return result, nil
diff --git a/examples/boxes/boxes.vdl.go b/examples/boxes/boxes.vdl.go
index 5f73ee5..40da80a 100644
--- a/examples/boxes/boxes.vdl.go
+++ b/examples/boxes/boxes.vdl.go
@@ -12,7 +12,7 @@
 	_gen_ipc "veyron2/ipc"
 	_gen_naming "veyron2/naming"
 	_gen_rt "veyron2/rt"
-	_gen_vdl "veyron2/vdl"
+	_gen_vdlutil "veyron2/vdl/vdlutil"
 	_gen_wiretype "veyron2/wiretype"
 )
 
@@ -68,10 +68,10 @@
 		case _gen_ipc.Client:
 			client = o
 		default:
-			return nil, _gen_vdl.ErrUnrecognizedOption
+			return nil, _gen_vdlutil.ErrUnrecognizedOption
 		}
 	default:
-		return nil, _gen_vdl.ErrTooManyOptionsToBind
+		return nil, _gen_vdlutil.ErrTooManyOptionsToBind
 	}
 	stub := &clientStubBoxSignalling{client: client, name: name}
 
@@ -188,7 +188,7 @@
 		},
 	}
 
-	result.TypeDefs = []_gen_vdl.Any{
+	result.TypeDefs = []_gen_vdlutil.Any{
 		_gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}}
 
 	return result, nil
@@ -346,10 +346,10 @@
 		case _gen_ipc.Client:
 			client = o
 		default:
-			return nil, _gen_vdl.ErrUnrecognizedOption
+			return nil, _gen_vdlutil.ErrUnrecognizedOption
 		}
 	default:
-		return nil, _gen_vdl.ErrTooManyOptionsToBind
+		return nil, _gen_vdlutil.ErrTooManyOptionsToBind
 	}
 	stub := &clientStubDrawInterface{client: client, name: name}
 
@@ -463,7 +463,7 @@
 		},
 	}
 
-	result.TypeDefs = []_gen_vdl.Any{
+	result.TypeDefs = []_gen_vdlutil.Any{
 		_gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}, _gen_wiretype.ArrayType{Elem: 0x19, Len: 0x4, Name: "", Tags: []string(nil)}, _gen_wiretype.StructType{
 			[]_gen_wiretype.FieldType{
 				_gen_wiretype.FieldType{Type: 0x3, Name: "DeviceId"},
diff --git a/examples/fortune/fortune.vdl.go b/examples/fortune/fortune.vdl.go
index ddce22e..4784028 100644
--- a/examples/fortune/fortune.vdl.go
+++ b/examples/fortune/fortune.vdl.go
@@ -12,7 +12,7 @@
 	_gen_ipc "veyron2/ipc"
 	_gen_naming "veyron2/naming"
 	_gen_rt "veyron2/rt"
-	_gen_vdl "veyron2/vdl"
+	_gen_vdlutil "veyron2/vdl/vdlutil"
 	_gen_wiretype "veyron2/wiretype"
 )
 
@@ -57,10 +57,10 @@
 		case _gen_ipc.Client:
 			client = o
 		default:
-			return nil, _gen_vdl.ErrUnrecognizedOption
+			return nil, _gen_vdlutil.ErrUnrecognizedOption
 		}
 	default:
-		return nil, _gen_vdl.ErrTooManyOptionsToBind
+		return nil, _gen_vdlutil.ErrTooManyOptionsToBind
 	}
 	stub := &clientStubFortune{client: client, name: name}
 
@@ -177,7 +177,7 @@
 		},
 	}
 
-	result.TypeDefs = []_gen_vdl.Any{
+	result.TypeDefs = []_gen_vdlutil.Any{
 		_gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}}
 
 	return result, nil
diff --git a/examples/inspector/inspector.vdl.go b/examples/inspector/inspector.vdl.go
index ba04668..436f056 100644
--- a/examples/inspector/inspector.vdl.go
+++ b/examples/inspector/inspector.vdl.go
@@ -10,7 +10,7 @@
 	_gen_ipc "veyron2/ipc"
 	_gen_naming "veyron2/naming"
 	_gen_rt "veyron2/rt"
-	_gen_vdl "veyron2/vdl"
+	_gen_vdlutil "veyron2/vdl/vdlutil"
 	_gen_wiretype "veyron2/wiretype"
 )
 
@@ -169,10 +169,10 @@
 		case _gen_ipc.Client:
 			client = o
 		default:
-			return nil, _gen_vdl.ErrUnrecognizedOption
+			return nil, _gen_vdlutil.ErrUnrecognizedOption
 		}
 	default:
-		return nil, _gen_vdl.ErrTooManyOptionsToBind
+		return nil, _gen_vdlutil.ErrTooManyOptionsToBind
 	}
 	stub := &clientStubInspector{client: client, name: name}
 
@@ -290,7 +290,7 @@
 		OutStream: 66,
 	}
 
-	result.TypeDefs = []_gen_vdl.Any{
+	result.TypeDefs = []_gen_vdlutil.Any{
 		_gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}, _gen_wiretype.StructType{
 			[]_gen_wiretype.FieldType{
 				_gen_wiretype.FieldType{Type: 0x3, Name: "Name"},
diff --git a/examples/netconfigwatcher/main.go b/examples/netconfigwatcher/main.go
new file mode 100644
index 0000000..b935883
--- /dev/null
+++ b/examples/netconfigwatcher/main.go
@@ -0,0 +1,20 @@
+package main
+
+import (
+	"fmt"
+	"log"
+
+	"veyron/runtimes/google/lib/netconfig"
+)
+
+func main() {
+	w, err := netconfig.NewNetConfigWatcher()
+	if err != nil {
+		log.Fatalf("oops: %s", err)
+	}
+	fmt.Println("Do something to your network. You should see one or more dings.")
+	for {
+		<-w.Channel()
+		fmt.Println("ding")
+	}
+}
diff --git a/examples/pipetobrowser/Makefile b/examples/pipetobrowser/Makefile
index 474caf5..e941562 100644
--- a/examples/pipetobrowser/Makefile
+++ b/examples/pipetobrowser/Makefile
@@ -20,8 +20,8 @@
 all: node_modules browser/third-party browser/third-party/veyron browser/build.js browser/index.html $(VEYRON_ROOT)/veyron/go/bin
 
 # Build p2b cli binary
-$(VEYRON_ROOT)/veyron/go/bin: cli/main.go
-	$(VEYRON_BUILD_SCRIPT) install veyron/examples/pipetobrowser/...
+$(VEYRON_ROOT)/veyron/go/bin: p2b/main.go
+	$(VEYRON_BUILD_SCRIPT) install veyron/...
 
 # Install what we need from NPM, tools such as jspm, serve, etc...
 node_modules: package.json
@@ -31,9 +31,9 @@
 
 # Build and copies Veyron from local source
 browser/third-party/veyron: $(VEYRON_JS_API)
-	mkdir browser/third-party -p
+	mkdir -p browser/third-party
 	(cd $(VEYRON_JS_API) && ./vgrunt build)
-	mkdir browser/third-party/veyron -p
+	mkdir -p browser/third-party/veyron
 	cp -rf $(VEYRON_JS_API)/dist/*.* browser/third-party/veyron
 
 # Install JSPM and Bower packages as listed in browser/package.json from JSPM and browser/bower.json from bower
@@ -75,10 +75,6 @@
 
 # Deploys Veyron daemons
 daemons:
-	@if [[ ! -e $(VEYRON_PROXY) ]]; then \
-		echo "Veyron proxy could not be found in $(VEYRON_PROXY). Please build and install veyron2 and services first"; \
-		exit 1; \
-	fi
 	identity --name=veyron_p2b_identity > $(VEYRON_IDENTITY_PATH)
 	export VEYRON_IDENTITY=$(VEYRON_IDENTITY_PATH) ; \
 	identityd --address=:$(VEYRON_IDENTITY_PORT) & \
@@ -86,7 +82,6 @@
 	export NAMESPACE_ROOT=/localhost:$(VEYRON_MOUNTTABLE_PORT) ; \
 	proxyd -address=$(VEYRON_PROXY_ADDR) & \
 	wsprd --v=1 -logtostderr=true -vproxy=$(VEYRON_PROXY_ADDR) --port $(VEYRON_WSPR_PORT) & \
-	$(VEYRON_STORE) --address=:$(VEYRON_STORE_PORT) --name=global/$(USER)/store &
 
 # Kills the running daemons
 clean-daemons:
diff --git a/examples/pipetobrowser/browser/actions/add-pipe-viewer.js b/examples/pipetobrowser/browser/actions/add-pipe-viewer.js
index 419d70d..a284731 100644
--- a/examples/pipetobrowser/browser/actions/add-pipe-viewer.js
+++ b/examples/pipetobrowser/browser/actions/add-pipe-viewer.js
@@ -67,8 +67,11 @@
 
   // Add a new tab and show a loading indicator for now,
   // then replace the loading view with the actual viewer when ready
+  // close the stream when tab closes
   var loadingView = new LoadingView();
-  pipesViewInstance.addTab(tabKey, tabName, loadingView);
+  pipesViewInstance.addTab(tabKey, tabName, loadingView, () => {
+    stream.end();
+  });
 
   // Add the redirect stream action
   var icon = 'hardware:cast';
diff --git a/examples/pipetobrowser/browser/actions/navigate-help.js b/examples/pipetobrowser/browser/actions/navigate-help.js
index d2c0691..01f2117 100644
--- a/examples/pipetobrowser/browser/actions/navigate-help.js
+++ b/examples/pipetobrowser/browser/actions/navigate-help.js
@@ -12,7 +12,7 @@
 import { HelpView } from 'views/help/view'
 
 var log = new Logger('actions/navigate-help');
-const ACTION_NAME = 'help';
+var ACTION_NAME = 'help';
 
 /*
  * Registers the action
diff --git a/examples/pipetobrowser/browser/actions/redirect-pipe.js b/examples/pipetobrowser/browser/actions/redirect-pipe.js
index 28ce6d9..6bcb93b 100644
--- a/examples/pipetobrowser/browser/actions/redirect-pipe.js
+++ b/examples/pipetobrowser/browser/actions/redirect-pipe.js
@@ -61,7 +61,7 @@
   getAllPublishedP2BNames().then((allNames) => {
     // append current plugin name to the veyron names for better UX
     dialog.existingNames = allNames.map((n) => {
-      return n + (currentPluginName || '');
+      return n + '/' + currentPluginName;
     });
   }).catch((e) => {
     log.debug('getAllPublishedP2BNames failed', e);
diff --git a/examples/pipetobrowser/browser/app.html b/examples/pipetobrowser/browser/app.html
index c592cb2..d6dfbd6 100644
--- a/examples/pipetobrowser/browser/app.html
+++ b/examples/pipetobrowser/browser/app.html
@@ -9,6 +9,14 @@
   <title>Pipe To Browser - because life is too short to stare at unformatted stdout text, and is hard enough already not to have a spell-checker for stdin</title>
 
   <script src="third-party/platform/platform.js"></script>
+  <!-- TODO(aghassemi) use CJS version of Veyron and provide an ES6 shim -->
+  <script src="third-party/veyron/veyron.js"></script>
+
+  <script src="third-party/traceur-runtime@0.0.49.js"></script>
+  <script src="third-party/system@0.6.js"></script>
+  <script src="config.js"></script>
+  <script src="build.js"></script>
+
   <link rel="import" href="views/page/component.html"/>
 
   <style type="text/css">
@@ -19,13 +27,7 @@
   </style>
 </head>
 <body>
-  <!-- TODO(aghassemi) use CJS version of Veyron and provide an ES6 shim -->
-  <script src="third-party/veyron/veyron.js"></script>
 
-  <script src="third-party/traceur-runtime@0.0.49.js"></script>
-  <script src="third-party/system@0.6.js"></script>
-  <script src="config.js"></script>
-  <script src="build.js"></script>
 
   <script>
     window.addEventListener('polymer-ready', function(e) {
diff --git a/examples/pipetobrowser/browser/bower.json b/examples/pipetobrowser/browser/bower.json
index 6ebd373..0217621 100644
--- a/examples/pipetobrowser/browser/bower.json
+++ b/examples/pipetobrowser/browser/bower.json
@@ -2,8 +2,8 @@
   "name": "pipe-to-browser",
   "version": "0.0.1",
   "dependencies": {
-    "polymer": "Polymer/polymer#~0.3.2",
-    "core-elements": "Polymer/core-elements#~0.3.2",
-    "paper-elements": "Polymer/paper-elements#~0.3.2"
+    "polymer": "Polymer/polymer#~0.3.4",
+    "core-elements": "Polymer/core-elements#~0.3.4",
+    "paper-elements": "Polymer/paper-elements#~0.3.4"
   }
 }
diff --git a/examples/pipetobrowser/browser/config.js b/examples/pipetobrowser/browser/config.js
index 2e7b142..4206c8a 100644
--- a/examples/pipetobrowser/browser/config.js
+++ b/examples/pipetobrowser/browser/config.js
@@ -6,6 +6,8 @@
     "view": "libs/mvc/view.js",
     "logger": "libs/logs/logger.js",
     "stream-helpers": "libs/utils/stream-helpers.js",
+    "web-component-loader": "libs/utils/web-component-loader.js",
+    "formatting": "libs/utils/formatting.js",
     "npm:*": "third-party/npm/*.js",
     "github:*": "third-party/github/*.js"
   }
@@ -13,41 +15,43 @@
 
 System.config({
   "map": {
+    "npm:humanize": "npm:humanize@^0.0.9",
     "npm:event-stream": "npm:event-stream@^3.1.5",
     "nodelibs": "github:jspm/nodelibs@master",
     "npm:event-stream@3.1.5": {
-      "through": "npm:through@^2.3.1",
-      "pause-stream": "npm:pause-stream@0.0.11",
       "from": "npm:from@0",
-      "stream-combiner": "npm:stream-combiner@^0.0.4",
       "map-stream": "npm:map-stream@0.1",
+      "pause-stream": "npm:pause-stream@0.0.11",
       "duplexer": "npm:duplexer@^0.1.1",
-      "split": "npm:split@0.2"
+      "through": "npm:through@^2.3.1",
+      "split": "npm:split@0.2",
+      "stream-combiner": "npm:stream-combiner@^0.0.4"
     },
+    "npm:humanize@0.0.9": {},
+    "npm:from@0.1.3": {},
     "npm:stream-combiner@0.0.4": {
       "duplexer": "npm:duplexer@^0.1.1"
     },
+    "npm:duplexer@0.1.1": {},
+    "npm:map-stream@0.1.0": {},
     "npm:pause-stream@0.0.11": {
       "through": "npm:through@2.3"
     },
-    "npm:from@0.1.3": {},
-    "npm:through@2.3.4": {},
-    "npm:duplexer@0.1.1": {},
     "npm:split@0.2.10": {
       "through": "npm:through@2"
     },
-    "npm:map-stream@0.1.0": {},
+    "npm:through@2.3.4": {},
     "github:jspm/nodelibs@0.0.2": {
-      "base64-js": "npm:base64-js@^0.0.4",
       "ieee754": "npm:ieee754@^1.1.1",
-      "inherits": "npm:inherits@^2.0.1",
+      "base64-js": "npm:base64-js@^0.0.4",
       "Base64": "npm:Base64@0.2",
+      "inherits": "npm:inherits@^2.0.1",
       "json": "github:systemjs/plugin-json@master"
     },
     "npm:base64-js@0.0.4": {},
+    "npm:ieee754@1.1.3": {},
     "npm:Base64@0.2.1": {},
     "npm:inherits@2.0.1": {},
-    "npm:ieee754@1.1.3": {},
     "github:jspm/nodelibs@master": {
       "Base64": "npm:Base64@0.2",
       "base64-js": "npm:base64-js@^0.0.4",
@@ -60,22 +64,23 @@
 
 System.config({
   "versions": {
+    "npm:humanize": "0.0.9",
     "npm:event-stream": "3.1.5",
-    "npm:through": "2.3.4",
-    "npm:pause-stream": "0.0.11",
     "npm:from": "0.1.3",
-    "npm:stream-combiner": "0.0.4",
     "npm:map-stream": "0.1.0",
+    "npm:pause-stream": "0.0.11",
     "npm:duplexer": "0.1.1",
+    "npm:through": "2.3.4",
     "npm:split": "0.2.10",
+    "npm:stream-combiner": "0.0.4",
     "github:jspm/nodelibs": [
       "master",
       "0.0.2"
     ],
-    "npm:base64-js": "0.0.4",
     "npm:ieee754": "1.1.3",
-    "npm:inherits": "2.0.1",
+    "npm:base64-js": "0.0.4",
     "npm:Base64": "0.2.1",
+    "npm:inherits": "2.0.1",
     "github:systemjs/plugin-json": "master"
   }
 });
diff --git a/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/column/renderer.html b/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/column/renderer.html
index cb2f8c9..208ff49 100644
--- a/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/column/renderer.html
+++ b/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/column/renderer.html
@@ -38,9 +38,9 @@
         }
 
         if (this.gridState.sort.ascending) {
-          return this.data.label + ' \u21A7'; // up wedge unicode character
+          return this.data.label + ' \u21A5'; // up wedge unicode character
         } else {
-          return this.data.label + ' \u21A5'; // down wedge unicode character
+          return this.data.label + ' \u21A7'; // down wedge unicode character
         }
       }
     });
diff --git a/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/component.css b/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/component.css
index 87cdff3..b309a31 100644
--- a/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/component.css
+++ b/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/component.css
@@ -26,6 +26,7 @@
 
 .more-icon {
   fill: #0a7e07;
+  color: #0a7e07;
 }
 
 paper-dialog {
@@ -33,11 +34,6 @@
   width: 80vw;
 }
 
-/* hack: wrong z-index in shadow of paper-dialog disables text selection in dialog */
-paper-dialog /deep/ #shadow {
-  z-index: -1;
-}
-
 .more-dialog-content .heading {
   font-size: 1.0em;
   padding-top: 0.2em;
@@ -85,6 +81,10 @@
   display: initial;
 }
 
+.more-dialog-content [gridOnly] {
+  display:none;
+}
+
 .paginator {
   display: inline-block;
   border: solid 1px rgba(0, 0, 0, 0.05);
@@ -97,4 +97,4 @@
 
 .paginator paper-icon-button {
   vertical-align: middle;
-}
\ No newline at end of file
+}
diff --git a/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/component.html b/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/component.html
index a67f7dd..974cc97 100644
--- a/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/component.html
+++ b/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/component.html
@@ -157,15 +157,15 @@
 
       /*
        * Number if items displayed in each page.
-       * Defaults to 30
+       * Defaults to 20
        * @type {integer}
        */
-      pageSize: 30,
+      pageSize: 20,
 
       showMoreInfo: function(e) {
         var item = e.target.templateInstance.model.item;
         this.selectedItems = [item];
-        this.$.dialog.opened = true;
+        this.$.dialog.toggle();
       },
 
       ready: function() {
@@ -333,7 +333,7 @@
           col.columnData.flex = col.columnData.origFlex;
         }
 
-        if (tableWidth >= minWidth) {
+        if (tableWidth === 0 || tableWidth >= minWidth) {
           return;
         }
 
diff --git a/examples/pipetobrowser/browser/libs/utils/byte-object-stream-adapter.js b/examples/pipetobrowser/browser/libs/utils/byte-object-stream-adapter.js
index d12c998..90593e1 100644
--- a/examples/pipetobrowser/browser/libs/utils/byte-object-stream-adapter.js
+++ b/examples/pipetobrowser/browser/libs/utils/byte-object-stream-adapter.js
@@ -3,9 +3,6 @@
 
 var Transform = Stream.Transform;
 var Buffer = buffer.Buffer;
-// TODO(aghassemi) doesn't look like ES6 and CommonJS modules can use the same
-// syntax to be referenced, but research more, maybe something can be done at
-// built time.
 
 /*
  * Adapts a stream of byte arrays in object mode to a regular stream of Buffer
diff --git a/examples/pipetobrowser/browser/libs/utils/formatting.js b/examples/pipetobrowser/browser/libs/utils/formatting.js
new file mode 100644
index 0000000..26f90e6
--- /dev/null
+++ b/examples/pipetobrowser/browser/libs/utils/formatting.js
@@ -0,0 +1,23 @@
+import { default as humanize } from 'npm:humanize'
+
+export function formatDate(d) {
+  if(d === undefined || d == null) { return; }
+  var naturalDay = humanize.naturalDay(d.getTime() / 1000);
+  var naturalTime = humanize.date('g:i a', d);
+  return naturalDay + ' at ' + naturalTime;
+}
+
+export function formatRelativeTime(d) {
+  if(d === undefined || d == null) { return; }
+  return humanize.relativeTime(d.getTime() / 1000);
+}
+
+export function formatInteger(n) {
+  if(n === undefined || n == null) { return; }
+  return humanize.numberFormat(n, 0);
+}
+
+export function formatBytes(b) {
+  if(b === undefined || b == null) { return; }
+  return humanize.filesize(b);
+}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/libs/utils/stream-copy.js b/examples/pipetobrowser/browser/libs/utils/stream-copy.js
index 4b7e386..c940213 100644
--- a/examples/pipetobrowser/browser/libs/utils/stream-copy.js
+++ b/examples/pipetobrowser/browser/libs/utils/stream-copy.js
@@ -17,6 +17,13 @@
     // TODO(aghassemi) make this a FIFO buffer with reasonable max-size
     this.buffer = [];
     this.copies = [];
+    var self = this;
+    this.on('end', () => {
+      self.ended = true;
+      for (var i=0; i < self.copies.length; i++) {
+        self.copies[i].end();
+      }
+    });
   }
 
   _transform(chunk, encoding, cb) {
@@ -42,7 +49,12 @@
         copy.push(this.buffer[i]);
       }
     }
-    this.copies.push(copy);
+    if (this.ended) {
+      copy.push(null);
+    } else {
+      this.copies.push(copy);
+    }
+
     return copy;
   }
 }
diff --git a/examples/pipetobrowser/browser/libs/utils/time.js b/examples/pipetobrowser/browser/libs/utils/time.js
deleted file mode 100644
index be9b42d..0000000
--- a/examples/pipetobrowser/browser/libs/utils/time.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Given a time duration in seconds, formats it as h' hours, m' minutes, s' seconds
- * in EN-US.
- * @param {integer} durationInSeconds Time period in seconds
- * @return {string} EN-US formatted time period.
- */
-export function formatDuration(durationInSeconds) {
-  var hours = Math.floor(durationInSeconds/3600);
-  var minutes = Math.floor((durationInSeconds - (hours*3600))/60);
-  var seconds = durationInSeconds - (hours*3600) - (minutes*60);
-
-  return _pluralize('hour', hours, true) +
-  _pluralize('minute', minutes, true) +
-  _pluralize('second', seconds, false);
-}
-
-function _pluralize(name, value, returnEmptyIfZero) {
-  if(value == 0 && returnEmptyIfZero) {
-    return '';
-  }
-  if(value != 1) {
-    name = name + 's';
-  }
-  return value + ' ' + name + ' ';
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/libs/utils/web-component-loader.js b/examples/pipetobrowser/browser/libs/utils/web-component-loader.js
new file mode 100644
index 0000000..bb37e0c
--- /dev/null
+++ b/examples/pipetobrowser/browser/libs/utils/web-component-loader.js
@@ -0,0 +1,11 @@
+export function importComponent(path) {
+	return new Promise((resolve, reject) => {
+		var link = document.createElement('link');
+		link.setAttribute('rel', 'import');
+		link.setAttribute('href', path);
+		link.onload = function() {
+		  resolve();
+		};
+		document.body.appendChild(link);
+	});
+}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/package.json b/examples/pipetobrowser/browser/package.json
index 773f16f..93fe433 100644
--- a/examples/pipetobrowser/browser/package.json
+++ b/examples/pipetobrowser/browser/package.json
@@ -6,6 +6,7 @@
   },
   "dependencies": {
     "npm:event-stream": "^3.1.5",
+    "npm:humanize": "^0.0.9",
     "nodelibs": "master"
   }
 }
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/pipe-viewers/builtin/console/component.css b/examples/pipetobrowser/browser/pipe-viewers/builtin/console/component.css
index 2091d34..d1ef530 100644
--- a/examples/pipetobrowser/browser/pipe-viewers/builtin/console/component.css
+++ b/examples/pipetobrowser/browser/pipe-viewers/builtin/console/component.css
@@ -15,3 +15,12 @@
 
   color: #ffffff;
 }
+
+.auto-scroll {
+  position: fixed;
+  right: 40px;
+  bottom: 0;
+  opacity: 0.8;
+  padding: 0.8em;
+  background-color: #ffeb3b;
+}
diff --git a/examples/pipetobrowser/browser/pipe-viewers/builtin/console/component.html b/examples/pipetobrowser/browser/pipe-viewers/builtin/console/component.html
index d9f773c..5505f9b 100644
--- a/examples/pipetobrowser/browser/pipe-viewers/builtin/console/component.html
+++ b/examples/pipetobrowser/browser/pipe-viewers/builtin/console/component.html
@@ -1,19 +1,56 @@
 <link rel="import" href="../../../third-party/polymer/polymer.html">
+<link rel="import" href="../../../third-party/paper-checkbox/paper-checkbox.html">
 
 <polymer-element name="p2b-plugin-console">
   <template>
     <link rel="stylesheet" href="component.css">
+    <link rel="stylesheet" href="../../../libs/css/common-style.css">
+    <div title="Auto Scroll" class="auto-scroll {{ {hidden : !scrolling} | tokenList}}">
+      <paper-checkbox checked="{{autoScroll}}" label="Auto Scroll" id="autoscroll"></paper-checkbox>
+    </div>
     <pre id="console"></pre>
   </template>
   <script>
     Polymer('p2b-plugin-console', {
+      ready: function() {
+        this.textBuffer = [];
+        this.autoScroll = true;
+      },
+
+      attached: function() {
+        this.renderLoop();
+      },
+      detached: function() {
+        this.isDetached = true;
+      },
+      renderLoop: function() {
+        var self = this;
+        if (!this.isDetached) {
+          requestAnimationFrame(function() {
+            self.render();
+            self.renderLoop();
+          });
+        }
+      },
+      render: function() {
+        if (this.textBuffer.length === 0) {
+          return;
+        }
+        var textNode = document.createTextNode(this.textBuffer.join(''));
+        this.textBuffer = [];
+        this.$.console.appendChild(textNode);
+        var scrollTop = this.scrollTop;
+        this.scrolling =  scrollTop > 0;
+        if (this.autoScroll) {
+          this.scrollTop = this.scrollHeight;
+        }
+      },
       /*
        * Appends text to the console
        * @param {string} text Text to add
        */
       addText: function(text) {
-        var textNode = document.createTextNode(text);
-        this.$.console.appendChild(textNode);
+        this.textBuffer.push(text);
       }
     });
     </script>
diff --git a/examples/pipetobrowser/browser/pipe-viewers/builtin/git/status/component.css b/examples/pipetobrowser/browser/pipe-viewers/builtin/git/status/component.css
index 9b266fe..99617a1 100644
--- a/examples/pipetobrowser/browser/pipe-viewers/builtin/git/status/component.css
+++ b/examples/pipetobrowser/browser/pipe-viewers/builtin/git/status/component.css
@@ -7,7 +7,8 @@
 }
 
 ::shadow /deep/ .state-icon.conflicted {
-  fill: #e51c23;
+  fill: #bf360c;
+  -webkit-animation: blink 0.6s infinite alternate;
 }
 
 ::shadow /deep/ .state-icon.untracked {
@@ -15,7 +16,7 @@
 }
 
 ::shadow /deep/ .state-icon.ignored {
-  fill: #bf360c;
+  fill: #689f38;
 }
 
 ::shadow /deep/ .action-icon {
diff --git a/examples/pipetobrowser/browser/pipe-viewers/builtin/git/status/plugin.js b/examples/pipetobrowser/browser/pipe-viewers/builtin/git/status/plugin.js
index 7ac8c63..11583c5 100644
--- a/examples/pipetobrowser/browser/pipe-viewers/builtin/git/status/plugin.js
+++ b/examples/pipetobrowser/browser/pipe-viewers/builtin/git/status/plugin.js
@@ -91,10 +91,10 @@
       iconName = 'warning';
       break;
     case 'conflicted':
-      iconName = 'error';
+      iconName = 'block';
       break;
     case 'untracked':
-      iconName = 'report';
+      iconName = 'error';
       break;
     case 'ignored':
       iconName = 'visibility-off';
@@ -122,7 +122,7 @@
       iconName = 'translate';
       break;
     case 'renamed':
-      iconName = 'sync';
+      iconName = 'swap-horiz';
       break;
     case 'copied':
       iconName = 'content-copy';
diff --git a/examples/pipetobrowser/browser/pipe-viewers/builtin/vlog/component.html b/examples/pipetobrowser/browser/pipe-viewers/builtin/vlog/component.html
index 59f4f28..3a70a5c 100644
--- a/examples/pipetobrowser/browser/pipe-viewers/builtin/vlog/component.html
+++ b/examples/pipetobrowser/browser/pipe-viewers/builtin/vlog/component.html
@@ -12,7 +12,7 @@
     <link rel="stylesheet" href="../../../libs/css/common-style.css">
     <link rel="stylesheet" href="component.css">
 
-    <p2b-grid id="grid" defaultSortKey="date" defaultSortAscending dataSource="{{ dataSource }}" summary="Data Grid displaying veyron log items in a tabular format with filters and search options.">
+    <p2b-grid id="grid" defaultSortKey="date" dataSource="{{ dataSource }}" summary="Data Grid displaying veyron log items in a tabular format with filters and search options.">
 
       <!-- Search -->
       <p2b-grid-search label="Search Logs"></p2b-grid-search>
@@ -48,8 +48,12 @@
       <p2b-grid-column label="Message" key="message" primary flex="8" minFlex="5" priority="1" >
         <template><div class="message-text">{{ item.message }}</div></template>
       </p2b-grid-column>
-      <p2b-grid-column label="Date" key="date" sortable flex="6" minFlex="3" priority="3">
-        <template><span class="smaller-text">{{ item.date }}</span></template>
+      <p2b-grid-column label="Date" key="date" sortable flex="4" minFlex="3" priority="3">
+        <template>
+          <abbr gridOnly title="{{item.date}}">{{ item.formattedDate }}</abbr>
+          <span moreInfoOnly>{{item.date}}</span>
+        </template>
+
       </p2b-grid-column>
       <p2b-grid-column label="Threadid" key="threadid" sortable flex="0" priority="5">
         <template>{{ item.threadId }}</template>
diff --git a/examples/pipetobrowser/browser/pipe-viewers/builtin/vlog/plugin.js b/examples/pipetobrowser/browser/pipe-viewers/builtin/vlog/plugin.js
index 76d52a2..db749ff 100644
--- a/examples/pipetobrowser/browser/pipe-viewers/builtin/vlog/plugin.js
+++ b/examples/pipetobrowser/browser/pipe-viewers/builtin/vlog/plugin.js
@@ -9,6 +9,7 @@
 import { View } from 'view';
 import { PipeViewer } from 'pipe-viewer';
 import { streamUtil } from 'stream-helpers';
+import { formatDate } from 'formatting';
 import { Logger } from 'logger'
 import { vLogDataSource } from './data-source';
 
@@ -51,6 +52,7 @@
  */
 function addAdditionalUIProperties(item) {
   addIconProperty(item);
+  addFormattedDate(item);
 }
 
 /*
@@ -78,4 +80,12 @@
   item.icon = iconName;
 }
 
+/*
+ * Adds a human friendly date field
+ * @private
+ */
+function addFormattedDate(item) {
+  item.formattedDate = formatDate(item.date);
+}
+
 export default vLogPipeViewer;
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/pipe-viewers/manager.js b/examples/pipetobrowser/browser/pipe-viewers/manager.js
index d135741..4c7dea0 100644
--- a/examples/pipetobrowser/browser/pipe-viewers/manager.js
+++ b/examples/pipetobrowser/browser/pipe-viewers/manager.js
@@ -82,7 +82,9 @@
  */
 function getPath(name) {
   if(isAbsoulteUrl(name)) {
-    return name;
+    var encodedName = encodeURIComponent(name);
+    System.paths[encodedName] = name;
+    return encodedName;
   } else {
     return 'pipe-viewers/builtin/' + name + '/plugin';
   }
diff --git a/examples/pipetobrowser/browser/services/pipe-to-browser-server.js b/examples/pipetobrowser/browser/services/pipe-to-browser-server.js
index cf04487..ac4e0f4 100644
--- a/examples/pipetobrowser/browser/services/pipe-to-browser-server.js
+++ b/examples/pipetobrowser/browser/services/pipe-to-browser-server.js
@@ -69,19 +69,32 @@
         var stream = streamCopier.pipe(bufferStream).pipe(streamByteCounter);
         stream.copier = streamCopier;
 
-        bufferStream.on('end', () => {
+        streamByteCounter.on('end', () => {
           log.debug('end of stream');
           // send total number of bytes received for this call as final result
-          resolve(numBytesForThisCall);
+          resolve();
         });
 
-        bufferStream.on('error', (e) => {
+        stream.on('error', (e) => {
           log.debug('stream error', e);
-          reject(e);
+          // TODO(aghassemi) envyor issue #50
+          // we want to reject but because of #50 we can't
+          // reject('Browser P2B threw an exception. Please see browser console for details.');
+          // reject(e);
+          resolve();
         });
 
         state.numPipes++;
-        pipeRequestHandler($suffix, stream);
+        try {
+          pipeRequestHandler($suffix, stream);
+        } catch(e) {
+          // TODO(aghassemi) envyor issue #50
+          // we want to reject but because of #50 we can't
+          // reject('Browser P2B threw an exception. Please see browser console for details.');
+          log.debug('pipeRequestHandler error', e);
+          resolve();
+        }
+
       });
     }
   };
diff --git a/examples/pipetobrowser/browser/views/help/component.css b/examples/pipetobrowser/browser/views/help/component.css
index faf1990..1e2e557 100644
--- a/examples/pipetobrowser/browser/views/help/component.css
+++ b/examples/pipetobrowser/browser/views/help/component.css
@@ -29,4 +29,5 @@
 a {
   color: #5677fc;
   text-decoration: none;
+  cursor: pointer;
 }
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/views/help/component.html b/examples/pipetobrowser/browser/views/help/component.html
index 46e1d2c..ba5112c 100644
--- a/examples/pipetobrowser/browser/views/help/component.html
+++ b/examples/pipetobrowser/browser/views/help/component.html
@@ -1,4 +1,4 @@
-<link rel="import" href="/libs/vendor/polymer/polymer/polymer.html">
+<link rel="import" href="../../third-party/polymer/polymer.html">
 
 <polymer-element name="p2b-help">
 <template>
@@ -40,10 +40,13 @@
   <pre class="code">cat /dev/urandom | p2b {{publishedName}}/dev/null</pre>
 
   <h3>Remote Viewers</h3>
-  <p>In addition to built-in viewers, ad-hoc remote viewers can be hosted anywhere and used with P2B. Remote viewers are referenced by their Url without the .js extension at the end og the plug-in JavaScript file</p>
-  <pre class="code">echo "Hello World" | p2b {{publishedName}}/http://googledrive.com/host/0BzmT5cnKdCAKa3hzNEVCU2tnd3c/helloworld</pre>
+  <p>In addition to built-in viewers, ad-hoc remote viewers can be hosted anywhere and used with P2B. Remote viewers are referenced by the Url of the plug-in JavaScript file</p>
+  <pre class="code">echo "Hello World" | p2b {{publishedName}}/http://googledrive.com/host/0BzmT5cnKdCAKa3hzNEVCU2tnd3c/helloworld.js</pre>
   <p>Writing remote viewers is not different than writing built-in ones and basic plug-ins are pretty straight forward to write.</p>
   <p>At high level, plug-ins are expected to implement a <span class="mono">PipeViewer</span> interface which has a <span class="mono">play(stream)</span> method. A <span class="mono">view</span> (which is a wrapper for a DOM element) is expected to be returned from <span class="mono">play(stream)</span>. You can look at the hello world remote plug-in <a href="http://googledrive.com/host/0BzmT5cnKdCAKa3hzNEVCU2tnd3c/helloworld.js" target="_blank">code on Google drive</a> to get started on writing new remote plug-ins</p>
+  <p>It is also possible to write the UI layer of your plug-in in HTML and CSS as a Web Component to avoid mixing logic and layout/styling in a single file.</p>
+  <p>Grumpy cat meme plug-in takes that approach. You can look at the <a href="http://googledrive.com/host/0BzmT5cnKdCAKV1p6Q0pjak5Kams/meme.js" target="_blank">JavaScript</a> and <a onClick="window.open('view-source:' + 'http://googledrive.com/host/0BzmT5cnKdCAKV1p6Q0pjak5Kams/meme.html');">HTML Web Component</a> source files.</p>
+  <pre class="code">echo "I take stuff from stdin, and send them to /dev/null" | p2b {{publishedName}}/http://googledrive.com/host/0BzmT5cnKdCAKV1p6Q0pjak5Kams/meme.js</pre>
 </template>
 <script>
   Polymer('p2b-help', {
diff --git a/examples/pipetobrowser/browser/views/page/component.css b/examples/pipetobrowser/browser/views/page/component.css
index 787f3bb..793659b 100644
--- a/examples/pipetobrowser/browser/views/page/component.css
+++ b/examples/pipetobrowser/browser/views/page/component.css
@@ -11,12 +11,10 @@
 
 [sidebar] {
   padding: 0.5em;
-  fill: #9e9e9e;
 }
 
 [sidebar] .core-selected {
   color: #00bcd4;
-  fill: #212121;
 }
 
 [main] {
diff --git a/examples/pipetobrowser/browser/views/page/component.html b/examples/pipetobrowser/browser/views/page/component.html
index 0993f2a..f1ab37c 100644
--- a/examples/pipetobrowser/browser/views/page/component.html
+++ b/examples/pipetobrowser/browser/views/page/component.html
@@ -15,6 +15,7 @@
 <link rel="import" href="../../views/publish/component.html"/>
 <link rel="import" href="../../views/status/component.html"/>
 <link rel="import" href="../../views/error/component.html"/>
+<link rel="import" href="../../views/help/component.html"/>
 <link rel="import" href="../../views/loading/component.html"/>
 <link rel="import" href="../../views/pipes/component.html"/>
 <link rel="import" href="../../views/redirect-pipe-dialog/component.html"/>
diff --git a/examples/pipetobrowser/browser/views/pipes/component.html b/examples/pipetobrowser/browser/views/pipes/component.html
index 9558d16..c877519 100644
--- a/examples/pipetobrowser/browser/views/pipes/component.html
+++ b/examples/pipetobrowser/browser/views/pipes/component.html
@@ -61,8 +61,9 @@
        * @param {string} key Key of the tab to add
        * @param {string} name Name of the tab to add
        * @param {DOMElement} el Content of the tab
+       * @param {function} onClose Optional onClose callback.
        */
-      addTab: function(key, name, el) {
+      addTab: function(key, name, el, onClose) {
         var self = this;
 
         // Create a tab thumb
@@ -75,6 +76,9 @@
         tabToolbar.title = name;
         tabToolbar.addEventListener('close-action', function() {
           self.removeTab(key);
+          if (onClose) {
+            onClose();
+          }
         });
         tabToolbar.addEventListener('fullscreen-action', function() {
           var tabContent = self.pipeTabs[key].tabContent;
@@ -88,7 +92,6 @@
         tabContent.appendChild(el);
 
         this.$.tabPages.appendChild(tabContent);
-        this.$.tabs.appendChild(tab);
 
         // Add the tab to our list.
         this.pipeTabs[key] = {
@@ -99,6 +102,9 @@
         };
 
         this.selectedTabKey = key;
+        requestAnimationFrame(function() {
+          self.$.tabs.appendChild(tab);
+        });
       },
 
       /*
@@ -108,6 +114,9 @@
        * @param onClick {function} event handler for the action
        */
       addToolbarAction: function(tabKey, icon, onClick) {
+        if (!this.pipeTabs[tabKey]) {
+          return;
+        }
         var toolbar = this.pipeTabs[tabKey].tabToolbar;
         toolbar.add(icon, onClick);
       },
@@ -117,6 +126,9 @@
        * @param {string} key Key of the tab to remove
        */
       removeTab: function(key) {
+        if (!this.pipeTabs[key]) {
+          return;
+        }
         // Remove tab thumb and content
         var tab = this.pipeTabs[key].tab;
         tab.remove();
@@ -144,6 +156,9 @@
        * @param {DOMElement} el New content of the tab
        */
       replaceTabContent: function(key, newName, newEl) {
+        if (!this.pipeTabs[key]) {
+          return;
+        }
         var tabContent = this.pipeTabs[key].tabContent;
         tabContent.replaceTabContent(newEl);
         if (newName) {
diff --git a/examples/pipetobrowser/browser/views/pipes/view.js b/examples/pipetobrowser/browser/views/pipes/view.js
index 8c9e2b4..78fcd20 100644
--- a/examples/pipetobrowser/browser/views/pipes/view.js
+++ b/examples/pipetobrowser/browser/views/pipes/view.js
@@ -18,9 +18,10 @@
   * @param {string} name A short name for the tab that will be displayed as
   * the tab title
   * @param {View} view View to show inside the tab.
+  * @param {function} onClose Optional onClose callback.
   */
-  addTab(key, name, view) {
-    this.element.addTab(key, name, view.element);
+  addTab(key, name, view, onClose) {
+    this.element.addTab(key, name, view.element, onClose);
   }
 
   /*
diff --git a/examples/pipetobrowser/browser/views/redirect-pipe-dialog/component.css b/examples/pipetobrowser/browser/views/redirect-pipe-dialog/component.css
index a58b136..b1bdca0 100644
--- a/examples/pipetobrowser/browser/views/redirect-pipe-dialog/component.css
+++ b/examples/pipetobrowser/browser/views/redirect-pipe-dialog/component.css
@@ -11,11 +11,6 @@
   width: 80vw;
 }
 
-/* hack: wrong z-index in shadow of paper-dialog disables text selection in dialog */
-paper-dialog /deep/ #shadow {
-  z-index: -1 !important;
-}
-
 paper-button[affirmative] {
   color: #4285f4;
 }
diff --git a/examples/pipetobrowser/browser/views/status/component.html b/examples/pipetobrowser/browser/views/status/component.html
index ca511a2..8362866 100644
--- a/examples/pipetobrowser/browser/views/status/component.html
+++ b/examples/pipetobrowser/browser/views/status/component.html
@@ -1,4 +1,5 @@
 <link rel="import" href="../../third-party/polymer/polymer.html">
+<link rel="import" href="../../third-party/paper-button/paper-button.html">
 
 <polymer-element name="p2b-status" attributes="status">
 
@@ -6,118 +7,83 @@
     <link rel="stylesheet" href="../common/common.css">
     <link rel="stylesheet" href="component.css">
     <h3>Status</h3>
-    <p>{{ statusText }}</p>
-    <div class="{{ {hidden : !serviceState.published} | tokenList}}">
+    <p>{{ serviceState | formatServiceState }}</p>
+    <div class="{{ {hidden : !serviceState.published} | tokenList }}">
       <h3>Name</h3>
       <p>{{ serviceState.fullServiceName }}</p>
 
       <h3>Published on</h3>
-      <p>{{ publishDate }}</p>
+      <p>{{ serviceState.date | formatDate }}</p>
 
-      <h3>Uptime</h3>
-      <p>{{ uptime }}</p>
+      <h3>Running Since</h3>
+      <p>{{ runningSince }}</p>
 
       <h3>Number of pipe requests</h3>
-      <p>{{ numPipes }}</p>
+      <p>{{ serviceState.numPipes | formatInteger }}</p>
 
       <h3>Total bytes received</h3>
-      <p>{{ numBytes }}</p>
+      <p>{{ serviceState.numBytes | formatBytes }}</p>
     </div>
-    <paper-button class="paper colored red" inkColor="#A9352C" on-click="{{ stopAction }}">Stop Service</paper-button>
+    <paper-button class="paper colored red" inkColor="#A9352C" on-click="{{ stopAction }}">Stop</paper-button>
   </template>
   <script>
-    Polymer('p2b-status', {
+    System.import('libs/utils/formatting').then(function(formatter) {
+      Polymer('p2b-status', {
 
-      /*
-       * Dynamic binding for the state of publishing p2b service.
-       * Any changes to this object will be reflected in the UI automatically
-       */
-      serviceState: null,
+        /*
+         * Dynamic binding for the state of publishing p2b service.
+         * Any changes to this object will be reflected in the UI automatically
+         */
+        serviceState: null,
 
-      /*
-       * A function that can format time duration
-       * @private
-       * @type {function}
-       */
-      formatDuration: null,
+        /*
+         * Human friendly formatting functions. Because polymer filter expressions
+         * don't accept obj.func we wrap them here
+         * @private
+         */
+        formatDate: formatter.formatDate,
+        formatInteger: formatter.formatInteger,
+        formatBytes: formatter.formatBytes,
 
-      /*
-       * Status text
-       * @private
-       * @type {string}
-       */
-      get statusText() {
-        if (!this.serviceState) {
-          return '';
+        /*
+         * Auto-updating Uptime text
+         * @private
+         * @type {string}
+         */
+        get runningSince() {
+          if (!this.serviceState) { return; }
+          return formatter.formatRelativeTime(this.serviceState.date);
+        },
+
+        /*
+         * Status text
+         * @private
+         * @type {string}
+         */
+        formatServiceState: function(serviceState) {
+          if (!serviceState) {
+            return '';
+          }
+          if (serviceState.published) {
+            return 'Published';
+          } else if(serviceState.publishing) {
+            return 'Publishing';
+          } else if(serviceState.stopping) {
+            return 'Stopping';
+          }  else {
+            return 'Stopped';
+          }
+        },
+
+        /*
+         * Stop action. Fires when user decides to stop the p2b service.
+         * @event
+         */
+        stopAction: function() {
+          this.fire('stop');
         }
-        if (this.serviceState.published) {
-          return 'Published';
-        } else if(this.serviceState.publishing) {
-          return 'Publishing';
-        } else if(this.serviceState.stopping) {
-          return 'Stopping';
-        }  else {
-          return 'Stopped';
-        }
-      },
 
-      /*
-       * Formatted publish date
-       * @private
-       * @type {string}
-       */
-      get publishDate() {
-        if (!this.serviceState || !this.serviceState.published) {
-          return '';
-        }
-        return this.serviceState.date.toString();
-      },
-
-      /*
-       * Formatted uptime
-       * @private
-       * @type {string}
-       */
-      get uptime() {
-        if (!this.serviceState || !this.serviceState.published) {
-          return '';
-        }
-        var elapsedSeconds = Math.floor((new Date() - this.serviceState.date) / 1000);
-        return this.formatDuration(elapsedSeconds);
-      },
-
-      /*
-       * Formatted number of pipes
-       * @private
-       * @type {string}
-       */
-      get numPipes() {
-        if (!this.serviceState || !this.serviceState.published) {
-          return '';
-        }
-        return this.serviceState.numPipes.toString();
-      },
-
-      /*
-       * Formatted number of bytes
-       * @private
-       * @type {string}
-       */
-      get numBytes() {
-        if (!this.serviceState || !this.serviceState.published) {
-          return '';
-        }
-        return this.serviceState.numBytes.toString();
-      },
-
-      /*
-       * Stop action. Fires when user decides to stop the p2b service.
-       * @event
-       */
-      stopAction: function() {
-        this.fire('stop');
-      }
-
+      });
     });
   </script>
 </polymer-element>
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/views/status/view.js b/examples/pipetobrowser/browser/views/status/view.js
index 0f15358..8792b8c 100644
--- a/examples/pipetobrowser/browser/views/status/view.js
+++ b/examples/pipetobrowser/browser/views/status/view.js
@@ -1,5 +1,4 @@
 import { View } from 'libs/mvc/view'
-import { formatDuration } from 'libs/utils/time'
 
 /*
  * View representing the state and interaction for publishing the p2b service.
@@ -10,11 +9,6 @@
 	constructor(serviceState) {
 		var el = document.createElement('p2b-status');
 		el.serviceState = serviceState;
-
-    // TODO(aghassemi) ES6 import syntax doesn't seem to work inside Polymer
-    // script tag. Test again when compiling server-side with Traceur.
-    el.formatDuration = formatDuration;
-
 		super(el);
 	}
 
diff --git a/examples/pipetobrowser/p2b.vdl b/examples/pipetobrowser/p2b.vdl
index eff991e..3a20904 100644
--- a/examples/pipetobrowser/p2b.vdl
+++ b/examples/pipetobrowser/p2b.vdl
@@ -3,5 +3,5 @@
 // Viewer allows clients to stream data to it and to request a particular viewer to format and display the data.
 type Viewer interface {
   // Pipe creates a bidirectional pipe between client and viewer service, returns total number of bytes received by the service after streaming ends
-  Pipe() stream<[]byte, _> (int64, error)
+  Pipe() stream<[]byte, _> (any, error)
 }
\ No newline at end of file
diff --git a/examples/pipetobrowser/p2b.vdl.go b/examples/pipetobrowser/p2b.vdl.go
index a9d7a3b..bfa0f47 100644
--- a/examples/pipetobrowser/p2b.vdl.go
+++ b/examples/pipetobrowser/p2b.vdl.go
@@ -10,7 +10,7 @@
 	_gen_ipc "veyron2/ipc"
 	_gen_naming "veyron2/naming"
 	_gen_rt "veyron2/rt"
-	_gen_vdl "veyron2/vdl"
+	_gen_vdlutil "veyron2/vdl/vdlutil"
 	_gen_wiretype "veyron2/wiretype"
 )
 
@@ -31,7 +31,7 @@
 type ViewerService interface {
 
 	// Pipe creates a bidirectional pipe between client and viewer service, returns total number of bytes received by the service after streaming ends
-	Pipe(context _gen_ipc.ServerContext, stream ViewerServicePipeStream) (reply int64, err error)
+	Pipe(context _gen_ipc.ServerContext, stream ViewerServicePipeStream) (reply _gen_vdlutil.Any, err error)
 }
 
 // ViewerPipeStream is the interface for streaming responses of the method
@@ -50,7 +50,7 @@
 
 	// Finish closes the stream and returns the positional return values for
 	// call.
-	Finish() (reply int64, err error)
+	Finish() (reply _gen_vdlutil.Any, err error)
 
 	// Cancel cancels the RPC, notifying the server to stop processing.
 	Cancel()
@@ -69,7 +69,7 @@
 	return c.clientCall.CloseSend()
 }
 
-func (c *implViewerPipeStream) Finish() (reply int64, err error) {
+func (c *implViewerPipeStream) Finish() (reply _gen_vdlutil.Any, err error) {
 	if ierr := c.clientCall.Finish(&reply, &err); ierr != nil {
 		err = ierr
 	}
@@ -116,10 +116,10 @@
 		case _gen_ipc.Client:
 			client = o
 		default:
-			return nil, _gen_vdl.ErrUnrecognizedOption
+			return nil, _gen_vdlutil.ErrUnrecognizedOption
 		}
 	default:
-		return nil, _gen_vdl.ErrTooManyOptionsToBind
+		return nil, _gen_vdlutil.ErrTooManyOptionsToBind
 	}
 	stub := &clientStubViewer{client: client, name: name}
 
@@ -208,14 +208,14 @@
 	result.Methods["Pipe"] = _gen_ipc.MethodSignature{
 		InArgs: []_gen_ipc.MethodArgument{},
 		OutArgs: []_gen_ipc.MethodArgument{
-			{Name: "", Type: 37},
 			{Name: "", Type: 65},
+			{Name: "", Type: 66},
 		},
-		InStream: 67,
+		InStream: 68,
 	}
 
-	result.TypeDefs = []_gen_vdl.Any{
-		_gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}, _gen_wiretype.NamedPrimitiveType{Type: 0x32, Name: "byte", Tags: []string(nil)}, _gen_wiretype.SliceType{Elem: 0x42, Name: "", Tags: []string(nil)}}
+	result.TypeDefs = []_gen_vdlutil.Any{
+		_gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "anydata", Tags: []string(nil)}, _gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}, _gen_wiretype.NamedPrimitiveType{Type: 0x32, Name: "byte", Tags: []string(nil)}, _gen_wiretype.SliceType{Elem: 0x43, Name: "", Tags: []string(nil)}}
 
 	return result, nil
 }
@@ -238,7 +238,7 @@
 	return
 }
 
-func (__gen_s *ServerStubViewer) Pipe(call _gen_ipc.ServerCall) (reply int64, err error) {
+func (__gen_s *ServerStubViewer) Pipe(call _gen_ipc.ServerCall) (reply _gen_vdlutil.Any, err error) {
 	stream := &implViewerServicePipeStream{serverCall: call}
 	reply, err = __gen_s.service.Pipe(call, stream)
 	return
diff --git a/examples/pipetobrowser/cli/main.go b/examples/pipetobrowser/p2b/main.go
similarity index 85%
rename from examples/pipetobrowser/cli/main.go
rename to examples/pipetobrowser/p2b/main.go
index 5ecef74..71c2cfb 100644
--- a/examples/pipetobrowser/cli/main.go
+++ b/examples/pipetobrowser/p2b/main.go
@@ -8,6 +8,8 @@
 	"io"
 	"os"
 
+	"veyron2"
+	"veyron2/ipc"
 	"veyron2/rt"
 
 	"veyron/examples/pipetobrowser"
@@ -73,7 +75,7 @@
 		return
 	}
 
-	stream, err := s.Pipe(runtime.NewContext())
+	stream, err := s.Pipe(runtime.NewContext(), veyron2.CallTimeout(ipc.NoTimeout))
 	if err != nil {
 		log.Errorf("failed to pipe to '%s' please ensure p2b service is running in the browser and name is correct.\nERR:%v", name, err)
 		return
@@ -83,24 +85,17 @@
 		stream,
 	}
 
-	numBytes, err := io.Copy(w, os.Stdin)
+	_, err = io.Copy(w, os.Stdin)
 	if err != nil {
 		log.Errorf("failed to copy the stdin pipe to the outgoing stream\nERR:%v", err)
 		return
 	}
 
-	stream.CloseSend()
-	result, err := stream.Finish()
+	_, err = stream.Finish()
 	if err != nil {
 		log.Errorf("error finishing stream: %v", err)
 		return
 	}
 
-	if numBytes != result {
-		log.Infof("*** number of bytes sent and received do NOT match ***")
-	}
-	log.Infof("%d bytes were piped to browser", numBytes)
-	log.Infof("%d bytes were received by browser", result)
-
 	fmt.Println("Finished piping to browser! Thanks for using p2b.")
 }
diff --git a/examples/rockpaperscissors/service.vdl.go b/examples/rockpaperscissors/service.vdl.go
index 946d6e7..268ee07 100644
--- a/examples/rockpaperscissors/service.vdl.go
+++ b/examples/rockpaperscissors/service.vdl.go
@@ -10,7 +10,7 @@
 	_gen_ipc "veyron2/ipc"
 	_gen_naming "veyron2/naming"
 	_gen_rt "veyron2/rt"
-	_gen_vdl "veyron2/vdl"
+	_gen_vdlutil "veyron2/vdl/vdlutil"
 	_gen_wiretype "veyron2/wiretype"
 )
 
@@ -203,10 +203,10 @@
 		case _gen_ipc.Client:
 			client = o
 		default:
-			return nil, _gen_vdl.ErrUnrecognizedOption
+			return nil, _gen_vdlutil.ErrUnrecognizedOption
 		}
 	default:
-		return nil, _gen_vdl.ErrTooManyOptionsToBind
+		return nil, _gen_vdlutil.ErrTooManyOptionsToBind
 	}
 	stub := &clientStubJudge{client: client, name: name}
 
@@ -326,7 +326,7 @@
 		OutStream: 76,
 	}
 
-	result.TypeDefs = []_gen_vdl.Any{
+	result.TypeDefs = []_gen_vdlutil.Any{
 		_gen_wiretype.NamedPrimitiveType{Type: 0x32, Name: "veyron/examples/rockpaperscissors.GameTypeTag", Tags: []string(nil)}, _gen_wiretype.StructType{
 			[]_gen_wiretype.FieldType{
 				_gen_wiretype.FieldType{Type: 0x24, Name: "NumRounds"},
@@ -451,10 +451,10 @@
 		case _gen_ipc.Client:
 			client = o
 		default:
-			return nil, _gen_vdl.ErrUnrecognizedOption
+			return nil, _gen_vdlutil.ErrUnrecognizedOption
 		}
 	default:
-		return nil, _gen_vdl.ErrTooManyOptionsToBind
+		return nil, _gen_vdlutil.ErrTooManyOptionsToBind
 	}
 	stub := &clientStubPlayer{client: client, name: name}
 
@@ -553,7 +553,7 @@
 		},
 	}
 
-	result.TypeDefs = []_gen_vdl.Any{
+	result.TypeDefs = []_gen_vdlutil.Any{
 		_gen_wiretype.StructType{
 			[]_gen_wiretype.FieldType{
 				_gen_wiretype.FieldType{Type: 0x3, Name: "ID"},
@@ -627,10 +627,10 @@
 		case _gen_ipc.Client:
 			client = o
 		default:
-			return nil, _gen_vdl.ErrUnrecognizedOption
+			return nil, _gen_vdlutil.ErrUnrecognizedOption
 		}
 	default:
-		return nil, _gen_vdl.ErrTooManyOptionsToBind
+		return nil, _gen_vdlutil.ErrTooManyOptionsToBind
 	}
 	stub := &clientStubScoreKeeper{client: client, name: name}
 
@@ -727,7 +727,7 @@
 		},
 	}
 
-	result.TypeDefs = []_gen_vdl.Any{
+	result.TypeDefs = []_gen_vdlutil.Any{
 		_gen_wiretype.NamedPrimitiveType{Type: 0x32, Name: "veyron/examples/rockpaperscissors.GameTypeTag", Tags: []string(nil)}, _gen_wiretype.StructType{
 			[]_gen_wiretype.FieldType{
 				_gen_wiretype.FieldType{Type: 0x24, Name: "NumRounds"},
@@ -823,10 +823,10 @@
 		case _gen_ipc.Client:
 			client = o
 		default:
-			return nil, _gen_vdl.ErrUnrecognizedOption
+			return nil, _gen_vdlutil.ErrUnrecognizedOption
 		}
 	default:
-		return nil, _gen_vdl.ErrTooManyOptionsToBind
+		return nil, _gen_vdlutil.ErrTooManyOptionsToBind
 	}
 	stub := &clientStubRockPaperScissors{client: client, name: name}
 	stub.Judge_ExcludingUniversal, _ = BindJudge(name, client)
@@ -922,7 +922,7 @@
 func (__gen_s *ServerStubRockPaperScissors) Signature(call _gen_ipc.ServerCall) (_gen_ipc.ServiceSignature, error) {
 	result := _gen_ipc.ServiceSignature{Methods: make(map[string]_gen_ipc.MethodSignature)}
 
-	result.TypeDefs = []_gen_vdl.Any{}
+	result.TypeDefs = []_gen_vdlutil.Any{}
 	var ss _gen_ipc.ServiceSignature
 	var firstAdded int
 	ss, _ = __gen_s.ServerStubJudge.Signature(call)
diff --git a/examples/tunnel/tunnel.vdl.go b/examples/tunnel/tunnel.vdl.go
index ca892f6..5bc70d2 100644
--- a/examples/tunnel/tunnel.vdl.go
+++ b/examples/tunnel/tunnel.vdl.go
@@ -12,7 +12,7 @@
 	_gen_ipc "veyron2/ipc"
 	_gen_naming "veyron2/naming"
 	_gen_rt "veyron2/rt"
-	_gen_vdl "veyron2/vdl"
+	_gen_vdlutil "veyron2/vdl/vdlutil"
 	_gen_wiretype "veyron2/wiretype"
 )
 
@@ -254,10 +254,10 @@
 		case _gen_ipc.Client:
 			client = o
 		default:
-			return nil, _gen_vdl.ErrUnrecognizedOption
+			return nil, _gen_vdlutil.ErrUnrecognizedOption
 		}
 	default:
-		return nil, _gen_vdl.ErrTooManyOptionsToBind
+		return nil, _gen_vdlutil.ErrTooManyOptionsToBind
 	}
 	stub := &clientStubTunnel{client: client, name: name}
 
@@ -378,7 +378,7 @@
 		OutStream: 70,
 	}
 
-	result.TypeDefs = []_gen_vdl.Any{
+	result.TypeDefs = []_gen_vdlutil.Any{
 		_gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}, _gen_wiretype.NamedPrimitiveType{Type: 0x32, Name: "byte", Tags: []string(nil)}, _gen_wiretype.SliceType{Elem: 0x42, Name: "", Tags: []string(nil)}, _gen_wiretype.StructType{
 			[]_gen_wiretype.FieldType{
 				_gen_wiretype.FieldType{Type: 0x2, Name: "UsePty"},
diff --git a/examples/wspr_sample/cache.vdl.go b/examples/wspr_sample/cache.vdl.go
index 810616d..5f738a3 100644
--- a/examples/wspr_sample/cache.vdl.go
+++ b/examples/wspr_sample/cache.vdl.go
@@ -10,14 +10,14 @@
 	_gen_ipc "veyron2/ipc"
 	_gen_naming "veyron2/naming"
 	_gen_rt "veyron2/rt"
-	_gen_vdl "veyron2/vdl"
+	_gen_vdlutil "veyron2/vdl/vdlutil"
 	_gen_wiretype "veyron2/wiretype"
 )
 
 // KeyValuePair is a representation of a cached key and value pair.
 type KeyValuePair struct {
 	Key   string
-	Value _gen_vdl.Any
+	Value _gen_vdlutil.Any
 }
 
 // A Cache service mimics the memcache interface.
@@ -26,10 +26,10 @@
 // to enable embedding without method collisions.  Not to be used directly by clients.
 type Cache_ExcludingUniversal interface {
 	// Set sets a value for a key.
-	Set(ctx _gen_context.T, key string, value _gen_vdl.Any, opts ..._gen_ipc.CallOpt) (err error)
+	Set(ctx _gen_context.T, key string, value _gen_vdlutil.Any, opts ..._gen_ipc.CallOpt) (err error)
 	// Get returns the value for a key.  If the value is not found, returns
 	// a not found error.
-	Get(ctx _gen_context.T, key string, opts ..._gen_ipc.CallOpt) (reply _gen_vdl.Any, err error)
+	Get(ctx _gen_context.T, key string, opts ..._gen_ipc.CallOpt) (reply _gen_vdlutil.Any, err error)
 	// Same as Get, but casts the return argument to an byte.
 	GetAsByte(ctx _gen_context.T, key string, opts ..._gen_ipc.CallOpt) (reply byte, err error)
 	// Same as Get, but casts the return argument to an int32.
@@ -51,7 +51,7 @@
 	// Same as Get, but casts the return argument to an error.
 	GetAsError(ctx _gen_context.T, key string, opts ..._gen_ipc.CallOpt) (reply error, err error)
 	// AsMap returns the full contents of the cache as a map.
-	AsMap(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply map[string]_gen_vdl.Any, err error)
+	AsMap(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply map[string]_gen_vdlutil.Any, err error)
 	// KeyValuePairs returns the full contents of the cache as a slice of pairs.
 	KeyValuePairs(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply []KeyValuePair, err error)
 	// MostRecentSet returns the key and value and the timestamp for the most
@@ -75,10 +75,10 @@
 type CacheService interface {
 
 	// Set sets a value for a key.
-	Set(context _gen_ipc.ServerContext, key string, value _gen_vdl.Any) (err error)
+	Set(context _gen_ipc.ServerContext, key string, value _gen_vdlutil.Any) (err error)
 	// Get returns the value for a key.  If the value is not found, returns
 	// a not found error.
-	Get(context _gen_ipc.ServerContext, key string) (reply _gen_vdl.Any, err error)
+	Get(context _gen_ipc.ServerContext, key string) (reply _gen_vdlutil.Any, err error)
 	// Same as Get, but casts the return argument to an byte.
 	GetAsByte(context _gen_ipc.ServerContext, key string) (reply byte, err error)
 	// Same as Get, but casts the return argument to an int32.
@@ -100,7 +100,7 @@
 	// Same as Get, but casts the return argument to an error.
 	GetAsError(context _gen_ipc.ServerContext, key string) (reply error, err error)
 	// AsMap returns the full contents of the cache as a map.
-	AsMap(context _gen_ipc.ServerContext) (reply map[string]_gen_vdl.Any, err error)
+	AsMap(context _gen_ipc.ServerContext) (reply map[string]_gen_vdlutil.Any, err error)
 	// KeyValuePairs returns the full contents of the cache as a slice of pairs.
 	KeyValuePairs(context _gen_ipc.ServerContext) (reply []KeyValuePair, err error)
 	// MostRecentSet returns the key and value and the timestamp for the most
@@ -132,7 +132,7 @@
 
 	// Recv returns the next item in the input stream, blocking until
 	// an item is available.  Returns io.EOF to indicate graceful end of input.
-	Recv() (item _gen_vdl.Any, err error)
+	Recv() (item _gen_vdlutil.Any, err error)
 
 	// Finish closes the stream and returns the positional return values for
 	// call.
@@ -155,7 +155,7 @@
 	return c.clientCall.CloseSend()
 }
 
-func (c *implCacheMultiGetStream) Recv() (item _gen_vdl.Any, err error) {
+func (c *implCacheMultiGetStream) Recv() (item _gen_vdlutil.Any, err error) {
 	err = c.clientCall.Recv(&item)
 	return
 }
@@ -176,7 +176,7 @@
 type CacheServiceMultiGetStream interface {
 	// Send places the item onto the output stream, blocking if there is no buffer
 	// space available.
-	Send(item _gen_vdl.Any) error
+	Send(item _gen_vdlutil.Any) error
 
 	// Recv fills itemptr with the next item in the input stream, blocking until
 	// an item is available.  Returns io.EOF to indicate graceful end of input.
@@ -188,7 +188,7 @@
 	serverCall _gen_ipc.ServerCall
 }
 
-func (s *implCacheServiceMultiGetStream) Send(item _gen_vdl.Any) error {
+func (s *implCacheServiceMultiGetStream) Send(item _gen_vdlutil.Any) error {
 	return s.serverCall.Send(item)
 }
 
@@ -214,10 +214,10 @@
 		case _gen_ipc.Client:
 			client = o
 		default:
-			return nil, _gen_vdl.ErrUnrecognizedOption
+			return nil, _gen_vdlutil.ErrUnrecognizedOption
 		}
 	default:
-		return nil, _gen_vdl.ErrTooManyOptionsToBind
+		return nil, _gen_vdlutil.ErrTooManyOptionsToBind
 	}
 	stub := &clientStubCache{client: client, name: name}
 
@@ -240,7 +240,7 @@
 	name   string
 }
 
-func (__gen_c *clientStubCache) Set(ctx _gen_context.T, key string, value _gen_vdl.Any, opts ..._gen_ipc.CallOpt) (err error) {
+func (__gen_c *clientStubCache) Set(ctx _gen_context.T, key string, value _gen_vdlutil.Any, opts ..._gen_ipc.CallOpt) (err error) {
 	var call _gen_ipc.Call
 	if call, err = __gen_c.client.StartCall(ctx, __gen_c.name, "Set", []interface{}{key, value}, opts...); err != nil {
 		return
@@ -251,7 +251,7 @@
 	return
 }
 
-func (__gen_c *clientStubCache) Get(ctx _gen_context.T, key string, opts ..._gen_ipc.CallOpt) (reply _gen_vdl.Any, err error) {
+func (__gen_c *clientStubCache) Get(ctx _gen_context.T, key string, opts ..._gen_ipc.CallOpt) (reply _gen_vdlutil.Any, err error) {
 	var call _gen_ipc.Call
 	if call, err = __gen_c.client.StartCall(ctx, __gen_c.name, "Get", []interface{}{key}, opts...); err != nil {
 		return
@@ -372,7 +372,7 @@
 	return
 }
 
-func (__gen_c *clientStubCache) AsMap(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply map[string]_gen_vdl.Any, err error) {
+func (__gen_c *clientStubCache) AsMap(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply map[string]_gen_vdlutil.Any, err error) {
 	var call _gen_ipc.Call
 	if call, err = __gen_c.client.StartCall(ctx, __gen_c.name, "AsMap", nil, opts...); err != nil {
 		return
@@ -679,7 +679,7 @@
 		},
 	}
 
-	result.TypeDefs = []_gen_vdl.Any{
+	result.TypeDefs = []_gen_vdlutil.Any{
 		_gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "anydata", Tags: []string(nil)}, _gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}, _gen_wiretype.NamedPrimitiveType{Type: 0x32, Name: "byte", Tags: []string(nil)}, _gen_wiretype.MapType{Key: 0x3, Elem: 0x41, Name: "", Tags: []string(nil)}, _gen_wiretype.StructType{
 			[]_gen_wiretype.FieldType{
 				_gen_wiretype.FieldType{Type: 0x3, Name: "Key"},
@@ -709,12 +709,12 @@
 	return
 }
 
-func (__gen_s *ServerStubCache) Set(call _gen_ipc.ServerCall, key string, value _gen_vdl.Any) (err error) {
+func (__gen_s *ServerStubCache) Set(call _gen_ipc.ServerCall, key string, value _gen_vdlutil.Any) (err error) {
 	err = __gen_s.service.Set(call, key, value)
 	return
 }
 
-func (__gen_s *ServerStubCache) Get(call _gen_ipc.ServerCall, key string) (reply _gen_vdl.Any, err error) {
+func (__gen_s *ServerStubCache) Get(call _gen_ipc.ServerCall, key string) (reply _gen_vdlutil.Any, err error) {
 	reply, err = __gen_s.service.Get(call, key)
 	return
 }
@@ -769,7 +769,7 @@
 	return
 }
 
-func (__gen_s *ServerStubCache) AsMap(call _gen_ipc.ServerCall) (reply map[string]_gen_vdl.Any, err error) {
+func (__gen_s *ServerStubCache) AsMap(call _gen_ipc.ServerCall) (reply map[string]_gen_vdlutil.Any, err error) {
 	reply, err = __gen_s.service.AsMap(call)
 	return
 }
diff --git a/examples/wspr_sample/error_thrower.vdl.go b/examples/wspr_sample/error_thrower.vdl.go
index 9eba7a1..54b046c 100644
--- a/examples/wspr_sample/error_thrower.vdl.go
+++ b/examples/wspr_sample/error_thrower.vdl.go
@@ -10,7 +10,7 @@
 	_gen_ipc "veyron2/ipc"
 	_gen_naming "veyron2/naming"
 	_gen_rt "veyron2/rt"
-	_gen_vdl "veyron2/vdl"
+	_gen_vdlutil "veyron2/vdl/vdlutil"
 	_gen_wiretype "veyron2/wiretype"
 )
 
@@ -87,10 +87,10 @@
 		case _gen_ipc.Client:
 			client = o
 		default:
-			return nil, _gen_vdl.ErrUnrecognizedOption
+			return nil, _gen_vdlutil.ErrUnrecognizedOption
 		}
 	default:
-		return nil, _gen_vdl.ErrTooManyOptionsToBind
+		return nil, _gen_vdlutil.ErrTooManyOptionsToBind
 	}
 	stub := &clientStubErrorThrower{client: client, name: name}
 
@@ -357,7 +357,7 @@
 		},
 	}
 
-	result.TypeDefs = []_gen_vdl.Any{
+	result.TypeDefs = []_gen_vdlutil.Any{
 		_gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}}
 
 	return result, nil
diff --git a/examples/wspr_sample/sampled/lib/cache_impl.go b/examples/wspr_sample/sampled/lib/cache_impl.go
index b2dfeff..e99d34e 100644
--- a/examples/wspr_sample/sampled/lib/cache_impl.go
+++ b/examples/wspr_sample/sampled/lib/cache_impl.go
@@ -8,7 +8,7 @@
 	"time"
 
 	"veyron2/ipc"
-	"veyron2/vdl"
+	"veyron2/vdl/vdlutil"
 	"veyron2/verror"
 
 	sample "veyron/examples/wspr_sample"
@@ -18,18 +18,18 @@
 
 // A simple in-memory implementation of a Cache service.
 type cacheImpl struct {
-	cache          map[string]vdl.Any
+	cache          map[string]vdlutil.Any
 	mostRecent     sample.KeyValuePair
 	lastUpdateTime time.Time
 }
 
 // NewCached returns a new implementation of the CacheService.
 func NewCached() sample.CacheService {
-	return &cacheImpl{cache: make(map[string]vdl.Any)}
+	return &cacheImpl{cache: make(map[string]vdlutil.Any)}
 }
 
 // Set sets a value for a key.  This should never return an error.
-func (c *cacheImpl) Set(_ ipc.ServerContext, key string, value vdl.Any) error {
+func (c *cacheImpl) Set(_ ipc.ServerContext, key string, value vdlutil.Any) error {
 	c.cache[key] = value
 	c.mostRecent = sample.KeyValuePair{Key: key, Value: value}
 	c.lastUpdateTime = time.Now()
@@ -38,7 +38,7 @@
 
 // Get returns the value for a key.  If the key is not in the map, it returns
 // an error.
-func (c *cacheImpl) Get(_ ipc.ServerContext, key string) (vdl.Any, error) {
+func (c *cacheImpl) Get(_ ipc.ServerContext, key string) (vdlutil.Any, error) {
 	if value, ok := c.cache[key]; ok {
 		return value, nil
 	}
@@ -122,7 +122,7 @@
 }
 
 // AsMap returns the full contents of the cache as a map.
-func (c *cacheImpl) AsMap(ipc.ServerContext) (map[string]vdl.Any, error) {
+func (c *cacheImpl) AsMap(ipc.ServerContext) (map[string]vdlutil.Any, error) {
 	return c.cache, nil
 }
 
diff --git a/examples/wspr_sample/sampled/lib/sampled_test.go b/examples/wspr_sample/sampled/lib/sampled_test.go
index 62c5950..28bd8d5 100644
--- a/examples/wspr_sample/sampled/lib/sampled_test.go
+++ b/examples/wspr_sample/sampled/lib/sampled_test.go
@@ -10,7 +10,7 @@
 	"veyron2/ipc"
 	"veyron2/naming"
 	"veyron2/rt"
-	"veyron2/vdl"
+	"veyron2/vdl/vdlutil"
 	"veyron2/verror"
 
 	hps "veyron/examples/wspr_sample"
@@ -97,7 +97,7 @@
 
 // settable mirrors the cache's Set method to provide a consistent way to populate test cases.
 type settable interface {
-	Set(ctx context.T, key string, val vdl.Any, opts ...ipc.CallOpt) error
+	Set(ctx context.T, key string, val vdlutil.Any, opts ...ipc.CallOpt) error
 }
 
 // populateObject populates a settable with 12 values.
@@ -168,9 +168,9 @@
 }
 
 // settableMap is a map that implements the settable interface.
-type settableMap map[string]vdl.Any
+type settableMap map[string]vdlutil.Any
 
-func (sm settableMap) Set(ctx context.T, key string, val vdl.Any, opts ...ipc.CallOpt) error {
+func (sm settableMap) Set(ctx context.T, key string, val vdlutil.Any, opts ...ipc.CallOpt) error {
 	sm[key] = val
 	return nil
 }
@@ -187,7 +187,7 @@
 		t.Fatal("error calling AsMap: ", err)
 	}
 
-	m := settableMap(make(map[string]vdl.Any))
+	m := settableMap(make(map[string]vdlutil.Any))
 	if err := populateObject(ctx, m); err != nil {
 		t.Fatal("error populating map: ", err)
 	}
@@ -211,7 +211,7 @@
 		t.Fatal("error calling KeyValuePairs: ", err)
 	}
 
-	m := settableMap(make(map[string]vdl.Any))
+	m := settableMap(make(map[string]vdlutil.Any))
 	if err := populateObject(ctx, m); err != nil {
 		t.Fatal("error populating map: ", err)
 	}
diff --git a/lib/testutil/modules/servers.vdl.go b/lib/testutil/modules/servers.vdl.go
index 7c8748b..26f9ef2 100644
--- a/lib/testutil/modules/servers.vdl.go
+++ b/lib/testutil/modules/servers.vdl.go
@@ -10,7 +10,7 @@
 	_gen_ipc "veyron2/ipc"
 	_gen_naming "veyron2/naming"
 	_gen_rt "veyron2/rt"
-	_gen_vdl "veyron2/vdl"
+	_gen_vdlutil "veyron2/vdl/vdlutil"
 	_gen_wiretype "veyron2/wiretype"
 )
 
@@ -50,10 +50,10 @@
 		case _gen_ipc.Client:
 			client = o
 		default:
-			return nil, _gen_vdl.ErrUnrecognizedOption
+			return nil, _gen_vdlutil.ErrUnrecognizedOption
 		}
 	default:
-		return nil, _gen_vdl.ErrTooManyOptionsToBind
+		return nil, _gen_vdlutil.ErrTooManyOptionsToBind
 	}
 	stub := &clientStubClock{client: client, name: name}
 
@@ -151,7 +151,7 @@
 		},
 	}
 
-	result.TypeDefs = []_gen_vdl.Any{
+	result.TypeDefs = []_gen_vdlutil.Any{
 		_gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}}
 
 	return result, nil
@@ -216,10 +216,10 @@
 		case _gen_ipc.Client:
 			client = o
 		default:
-			return nil, _gen_vdl.ErrUnrecognizedOption
+			return nil, _gen_vdlutil.ErrUnrecognizedOption
 		}
 	default:
-		return nil, _gen_vdl.ErrTooManyOptionsToBind
+		return nil, _gen_vdlutil.ErrTooManyOptionsToBind
 	}
 	stub := &clientStubEcho{client: client, name: name}
 
@@ -317,7 +317,7 @@
 		},
 	}
 
-	result.TypeDefs = []_gen_vdl.Any{
+	result.TypeDefs = []_gen_vdlutil.Any{
 		_gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}}
 
 	return result, nil
diff --git a/runtimes/google/ipc/benchmarks/service.vdl.go b/runtimes/google/ipc/benchmarks/service.vdl.go
index 371285d..2356536 100644
--- a/runtimes/google/ipc/benchmarks/service.vdl.go
+++ b/runtimes/google/ipc/benchmarks/service.vdl.go
@@ -12,7 +12,7 @@
 	_gen_ipc "veyron2/ipc"
 	_gen_naming "veyron2/naming"
 	_gen_rt "veyron2/rt"
-	_gen_vdl "veyron2/vdl"
+	_gen_vdlutil "veyron2/vdl/vdlutil"
 	_gen_wiretype "veyron2/wiretype"
 )
 
@@ -137,10 +137,10 @@
 		case _gen_ipc.Client:
 			client = o
 		default:
-			return nil, _gen_vdl.ErrUnrecognizedOption
+			return nil, _gen_vdlutil.ErrUnrecognizedOption
 		}
 	default:
-		return nil, _gen_vdl.ErrTooManyOptionsToBind
+		return nil, _gen_vdlutil.ErrTooManyOptionsToBind
 	}
 	stub := &clientStubBenchmark{client: client, name: name}
 
@@ -257,7 +257,7 @@
 		OutStream: 66,
 	}
 
-	result.TypeDefs = []_gen_vdl.Any{
+	result.TypeDefs = []_gen_vdlutil.Any{
 		_gen_wiretype.NamedPrimitiveType{Type: 0x32, Name: "byte", Tags: []string(nil)}, _gen_wiretype.SliceType{Elem: 0x41, Name: "", Tags: []string(nil)}, _gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}}
 
 	return result, nil
diff --git a/runtimes/google/ipc/discharges.go b/runtimes/google/ipc/discharges.go
index 75d99f3..c79cf8f 100644
--- a/runtimes/google/ipc/discharges.go
+++ b/runtimes/google/ipc/discharges.go
@@ -6,7 +6,7 @@
 	"veyron2/context"
 	"veyron2/ipc"
 	"veyron2/security"
-	"veyron2/vdl"
+	"veyron2/vdl/vdlutil"
 	"veyron2/vlog"
 )
 
@@ -134,7 +134,7 @@
 					vlog.VI(3).Infof("Discharge fetch for caveat %T from %v failed: %v", cav, cav.Location(), err)
 					return
 				}
-				var dAny vdl.Any
+				var dAny vdlutil.Any
 				// TODO(ashankar): Retry on errors like no-route-to-service, name resolution failures etc.
 				ierr := call.Finish(&dAny, &err)
 				if ierr != nil || err != nil {
diff --git a/runtimes/google/ipc/full_test.go b/runtimes/google/ipc/full_test.go
index dcf068e..9b24996 100644
--- a/runtimes/google/ipc/full_test.go
+++ b/runtimes/google/ipc/full_test.go
@@ -30,7 +30,7 @@
 	"veyron2/ipc/stream"
 	"veyron2/naming"
 	"veyron2/security"
-	"veyron2/vdl"
+	"veyron2/vdl/vdlutil"
 	"veyron2/verror"
 	"veyron2/vlog"
 	"veyron2/vom"
@@ -130,7 +130,7 @@
 
 type dischargeServer struct{}
 
-func (*dischargeServer) Discharge(ctx ipc.ServerCall, caveat vdl.Any) (vdl.Any, error) {
+func (*dischargeServer) Discharge(ctx ipc.ServerCall, caveat vdlutil.Any) (vdlutil.Any, error) {
 	c, ok := caveat.(security.ThirdPartyCaveat)
 	if !ok {
 		return nil, fmt.Errorf("discharger: unknown caveat(%T)", caveat)
diff --git a/runtimes/google/ipc/jni/dispatcher.go b/runtimes/google/ipc/jni/dispatcher.go
index a913b3b..425a6fb 100644
--- a/runtimes/google/ipc/jni/dispatcher.go
+++ b/runtimes/google/ipc/jni/dispatcher.go
@@ -58,7 +58,7 @@
 	defer C.DetachCurrentThread(d.jVM)
 
 	// Call Java dispatcher's lookup() method.
-	lid := C.jmethodID(util.JMethodIDPtr(env, C.GetObjectClass(env, d.jDispatcher), "lookup", fmt.Sprintf("(%s)%s", util.StringSign, util.ObjectSign)))
+	lid := C.jmethodID(util.JMethodIDPtrOrDie(env, C.GetObjectClass(env, d.jDispatcher), "lookup", fmt.Sprintf("(%s)%s", util.StringSign, util.ObjectSign)))
 	jObj := C.CallLookupMethod(env, d.jDispatcher, lid, C.jstring(util.JStringPtr(env, suffix)))
 	if err := util.JExceptionMsg(env); err != nil {
 		return nil, nil, fmt.Errorf("error invoking Java dispatcher's lookup() method: %v", err)
diff --git a/runtimes/google/ipc/jni/invoker.go b/runtimes/google/ipc/jni/invoker.go
index 0c9ba2a..0cda728 100644
--- a/runtimes/google/ipc/jni/invoker.go
+++ b/runtimes/google/ipc/jni/invoker.go
@@ -36,13 +36,13 @@
 
 func newInvoker(env *C.JNIEnv, jVM *C.JavaVM, jObj C.jobject) (*invoker, error) {
 	// Create a new Java VDLInvoker object.
-	cid := C.jmethodID(util.JMethodIDPtr(env, jVDLInvokerClass, "<init>", fmt.Sprintf("(%s)%s", util.ObjectSign, util.VoidSign)))
+	cid := C.jmethodID(util.JMethodIDPtrOrDie(env, jVDLInvokerClass, "<init>", fmt.Sprintf("(%s)%s", util.ObjectSign, util.VoidSign)))
 	jInvoker := C.CallNewInvokerObject(env, jVDLInvokerClass, cid, jObj)
 	if err := util.JExceptionMsg(env); err != nil {
 		return nil, fmt.Errorf("error creating Java VDLInvoker object: %v", err)
 	}
 	// Fetch the argGetter for the object.
-	pid := C.jmethodID(util.JMethodIDPtr(env, jVDLInvokerClass, "getImplementedServices", fmt.Sprintf("()%s", util.ArraySign(util.StringSign))))
+	pid := C.jmethodID(util.JMethodIDPtrOrDie(env, jVDLInvokerClass, "getImplementedServices", fmt.Sprintf("()%s", util.ArraySign(util.StringSign))))
 	jPathArray := C.jobjectArray(C.CallGetInterfacePath(env, jInvoker, pid))
 	paths := util.GoStringArray(env, jPathArray)
 	getter, err := newArgGetter(paths)
@@ -108,7 +108,7 @@
 		err = fmt.Errorf("couldn't find VDL method %q with %d args", method, len(argptrs))
 	}
 	sCall := newServerCall(call, mArgs)
-	cid := C.jmethodID(util.JMethodIDPtr(env, jServerCallClass, "<init>", fmt.Sprintf("(%s)%s", util.LongSign, util.VoidSign)))
+	cid := C.jmethodID(util.JMethodIDPtrOrDie(env, jServerCallClass, "<init>", fmt.Sprintf("(%s)%s", util.LongSign, util.VoidSign)))
 	jServerCall := C.CallNewServerCallObject(env, jServerCallClass, cid, C.jlong(util.PtrValue(sCall)))
 	util.GoRef(sCall) // unref-ed when jServerCall is garbage-collected
 
@@ -120,7 +120,7 @@
 	// Invoke the method.
 	const callSign = "Lcom/veyron2/ipc/ServerCall;"
 	const replySign = "Lcom/veyron/runtimes/google/VDLInvoker$InvokeReply;"
-	mid := C.jmethodID(util.JMethodIDPtr(env, C.GetObjectClass(env, i.jInvoker), "invoke", fmt.Sprintf("(%s%s[%s)%s", util.StringSign, callSign, util.StringSign, replySign)))
+	mid := C.jmethodID(util.JMethodIDPtrOrDie(env, C.GetObjectClass(env, i.jInvoker), "invoke", fmt.Sprintf("(%s%s[%s)%s", util.StringSign, callSign, util.StringSign, replySign)))
 	jReply := C.CallInvokeMethod(env, i.jInvoker, mid, C.jstring(util.JStringPtr(env, util.CamelCase(method))), jServerCall, jArgs)
 	if err := util.JExceptionMsg(env); err != nil {
 		return nil, fmt.Errorf("error invoking Java method %q: %v", method, err)
diff --git a/runtimes/google/jni/util/util.go b/runtimes/google/jni/util/util.go
index 85e73a7..767d62c 100644
--- a/runtimes/google/jni/util/util.go
+++ b/runtimes/google/jni/util/util.go
@@ -180,7 +180,7 @@
 func JThrowV(jEnv interface{}, err error) {
 	env := getEnv(jEnv)
 	verr := verror.Convert(err)
-	id := C.jmethodID(JMethodIDPtr(env, jVeyronExceptionClass, "<init>", fmt.Sprintf("(%s%s)%s", StringSign, StringSign, VoidSign)))
+	id := C.jmethodID(JMethodIDPtrOrDie(env, jVeyronExceptionClass, "<init>", fmt.Sprintf("(%s%s)%s", StringSign, StringSign, VoidSign)))
 	obj := C.jthrowable(C.CallNewVeyronExceptionObject(env, jVeyronExceptionClass, id, C.jstring(JStringPtr(env, verr.Error())), C.jstring(JStringPtr(env, string(verr.ErrorID())))))
 	C.Throw(env, obj)
 }
@@ -197,7 +197,7 @@
 		return nil
 	}
 	C.ExceptionClear(env)
-	id := C.jmethodID(JMethodIDPtr(env, jThrowableClass, "getMessage", fmt.Sprintf("()%s", StringSign)))
+	id := C.jmethodID(JMethodIDPtrOrDie(env, jThrowableClass, "getMessage", fmt.Sprintf("()%s", StringSign)))
 	jMsg := C.CallGetExceptionMessage(env, C.jobject(e), id)
 	return errors.New(GoString(env, jMsg))
 }
@@ -209,11 +209,7 @@
 func JBoolField(jEnv, jObj interface{}, field string) bool {
 	env := getEnv(jEnv)
 	obj := getObject(jObj)
-	cField := C.CString(field)
-	defer C.free(unsafe.Pointer(cField))
-	cSig := C.CString(BoolSign)
-	defer C.free(unsafe.Pointer(cSig))
-	fid := C.GetFieldID(env, C.GetObjectClass(env, obj), cField, cSig)
+	fid := C.jfieldID(JFieldIDPtrOrDie(env, C.GetObjectClass(env, obj), field, BoolSign))
 	return C.GetBooleanField(env, obj, fid) != C.JNI_FALSE
 }
 
@@ -224,11 +220,7 @@
 func JIntField(jEnv, jObj interface{}, field string) int {
 	env := getEnv(jEnv)
 	obj := getObject(jObj)
-	cField := C.CString(field)
-	defer C.free(unsafe.Pointer(cField))
-	cSig := C.CString(IntSign)
-	defer C.free(unsafe.Pointer(cSig))
-	fid := C.GetFieldID(env, C.GetObjectClass(env, obj), cField, cSig)
+	fid := C.jfieldID(JFieldIDPtrOrDie(env, C.GetObjectClass(env, obj), field, IntSign))
 	return int(C.GetIntField(env, obj, fid))
 }
 
@@ -240,11 +232,7 @@
 func JStringField(jEnv, jObj interface{}, field string) string {
 	env := getEnv(jEnv)
 	obj := getObject(jObj)
-	cField := C.CString(field)
-	defer C.free(unsafe.Pointer(cField))
-	cSig := C.CString(StringSign)
-	defer C.free(unsafe.Pointer(cSig))
-	fid := C.GetFieldID(env, C.GetObjectClass(env, obj), cField, cSig)
+	fid := C.jfieldID(JFieldIDPtrOrDie(env, C.GetObjectClass(env, obj), field, StringSign))
 	jStr := C.jstring(C.GetObjectField(env, obj, fid))
 	return GoString(env, jStr)
 }
@@ -257,11 +245,7 @@
 func JStringArrayField(jEnv, jObj interface{}, field string) []string {
 	env := getEnv(jEnv)
 	obj := getObject(jObj)
-	cField := C.CString(field)
-	defer C.free(unsafe.Pointer(cField))
-	cSig := C.CString("[" + StringSign)
-	defer C.free(unsafe.Pointer(cSig))
-	fid := C.GetFieldID(env, C.GetObjectClass(env, obj), cField, cSig)
+	fid := C.jfieldID(JFieldIDPtrOrDie(env, C.GetObjectClass(env, obj), field, ArraySign(StringSign)))
 	jStrArray := C.jobjectArray(C.GetObjectField(env, obj, fid))
 	return GoStringArray(env, jStrArray)
 }
@@ -274,11 +258,7 @@
 func JByteArrayField(jEnv, jObj interface{}, field string) []byte {
 	env := getEnv(jEnv)
 	obj := getObject(jObj)
-	cField := C.CString(field)
-	defer C.free(unsafe.Pointer(cField))
-	cSig := C.CString("[" + StringSign)
-	defer C.free(unsafe.Pointer(cSig))
-	fid := C.GetFieldID(env, C.GetObjectClass(env, obj), cField, cSig)
+	fid := C.jfieldID(JFieldIDPtrOrDie(env, C.GetObjectClass(env, obj), field, ArraySign(ByteSign)))
 	arr := C.jbyteArray(C.GetObjectField(env, obj, fid))
 	if arr == nil {
 		return nil
@@ -345,21 +325,43 @@
 	return
 }
 
-// JMethodID returns the Java method ID for the given method.
+// JFieldIDPtrOrDie returns the Java field ID for the given field.
 // NOTE: Because CGO creates package-local types and because this method may be
 // invoked from a different package, Java types are passed in an empty interface
 // and then cast into their package local types.
-func JMethodIDPtr(jEnv, jClass interface{}, name, signature string) unsafe.Pointer {
+func JFieldIDPtrOrDie(jEnv, jClass interface{}, name, sign string) unsafe.Pointer {
+	env := getEnv(jEnv)
+	class := getClass(jClass)
+	cName := C.CString(name)
+	defer C.free(unsafe.Pointer(cName))
+	cSign := C.CString(sign)
+	defer C.free(unsafe.Pointer(cSign))
+	ptr := unsafe.Pointer(C.GetFieldID(env, class, cName, cSign))
+	if err := JExceptionMsg(env); err != nil || ptr == nil {
+		panic(fmt.Sprintf("couldn't find field %s: %v", name, err))
+	}
+	return ptr
+}
+
+// JMethodIDPtrOrDie returns the Java method ID for the given method.
+// NOTE: Because CGO creates package-local types and because this method may be
+// invoked from a different package, Java types are passed in an empty interface
+// and then cast into their package local types.
+func JMethodIDPtrOrDie(jEnv, jClass interface{}, name, signature string) unsafe.Pointer {
 	env := getEnv(jEnv)
 	class := getClass(jClass)
 	cName := C.CString(name)
 	defer C.free(unsafe.Pointer(cName))
 	cSignature := C.CString(signature)
 	defer C.free(unsafe.Pointer(cSignature))
-	return unsafe.Pointer(C.GetMethodID(env, class, cName, cSignature))
+	ptr := unsafe.Pointer(C.GetMethodID(env, class, cName, cSignature))
+	if err := JExceptionMsg(env); err != nil || ptr == nil {
+		panic(fmt.Sprintf("couldn't find method %s: %v", name, err))
+	}
+	return ptr
 }
 
-// JFindClassOrDie returns the global references to the Java class with the
+// JFindClasPtrsOrDie returns the global references to the Java class with the
 // given pathname, or panic-s if the class cannot be found.
 // NOTE: Because CGO creates package-local types and because this method may be
 // invoked from a different package, Java types are passed in an empty interface
diff --git a/runtimes/google/lib/netconfig/example_test.go b/runtimes/google/lib/netconfig/example_test.go
new file mode 100644
index 0000000..0acef69
--- /dev/null
+++ b/runtimes/google/lib/netconfig/example_test.go
@@ -0,0 +1,20 @@
+package netconfig_test
+
+import (
+	"fmt"
+	"log"
+
+	"veyron/runtimes/google/lib/netconfig"
+)
+
+func ExampleNetConfigWatcher() {
+	w, err := netconfig.NewNetConfigWatcher()
+	if err != nil {
+		log.Fatalf("oops: %s", err)
+	}
+	fmt.Println("Do something to your network. You should see one or more dings.")
+	for {
+		<-w.Channel()
+		fmt.Println("ding")
+	}
+}
diff --git a/runtimes/google/lib/netconfig/ipaux.go b/runtimes/google/lib/netconfig/ipaux.go
new file mode 100644
index 0000000..ffade53
--- /dev/null
+++ b/runtimes/google/lib/netconfig/ipaux.go
@@ -0,0 +1,47 @@
+// +build plan9 windows
+
+package netconfig
+
+// Code to signal a network change every 2 minutes.   We use
+// this for systems where we don't yet have a good way to
+// watch for network changes.
+
+import (
+	"time"
+)
+
+type timerNetConfigWatcher struct {
+	c    chan struct{} // channel to signal confg changes
+	stop chan struct{} // channel to tell the watcher to stop
+}
+
+// Stop any waiter
+func (w *timerNetConfigWatcher) Stop() {
+	w.stop <- struct{}{}
+}
+
+func (w *timerNetConfigWatcher) Channel() chan struct{} {
+	return w.c
+}
+
+func (w *timerNetConfigWatcher) watcher() {
+	for {
+		select {
+		case <-w.stop:
+			close(w.c)
+			return
+		case <-time.NewTimer(2 * time.Minute).C:
+			select {
+			case w.c <- struct{}{}:
+			default:
+			}
+		}
+	}
+}
+
+func NewNetConfigWatcher() (NetConfigWatcher, error) {
+	w.c = make(chan struct{})
+	w.stop = make(chan struct{}, 1)
+	go w.watcher()
+	return w, nil
+}
diff --git a/runtimes/google/lib/netconfig/ipaux_bsd.go b/runtimes/google/lib/netconfig/ipaux_bsd.go
new file mode 100644
index 0000000..1002471
--- /dev/null
+++ b/runtimes/google/lib/netconfig/ipaux_bsd.go
@@ -0,0 +1,120 @@
+// +build darwin dragonfly freebsd netbsd openbsd
+
+package netconfig
+
+// We connect to the Route socket and parse messages to
+// look for network configuration changes.  This is generic
+// to all BSD based systems (including MacOS).  The net
+// library already has code to parse the messages so all
+// we need to do is look for message types.
+
+import (
+	"sync"
+	"syscall"
+	"time"
+	"veyron2/vlog"
+)
+
+/*
+#include <sys/socket.h>
+*/
+import "C"
+
+type bsdNetConfigWatcher struct {
+	sync.Mutex
+	t       *time.Timer
+	c       chan struct{}
+	s       int
+	stopped bool
+}
+
+func (w *bsdNetConfigWatcher) Stop() {
+	w.Lock()
+	defer w.Unlock()
+	if w.stopped {
+		return
+	}
+	w.stopped = true
+	syscall.Close(w.s)
+}
+
+func (w *bsdNetConfigWatcher) Channel() chan struct{} {
+	return w.c
+}
+
+// NewNetConfigWatcher returns a watcher that sends a message
+// on the Channel() whenever the config changes.
+func NewNetConfigWatcher() (NetConfigWatcher, error) {
+	s, err := syscall.Socket(C.PF_ROUTE, syscall.SOCK_RAW, syscall.AF_UNSPEC)
+	if err != nil {
+		vlog.Infof("socket failed: %s", err)
+		return nil, err
+	}
+	w := &bsdNetConfigWatcher{c: make(chan struct{}, 1), s: s}
+	go w.watcher()
+	return w, nil
+}
+
+func (w *bsdNetConfigWatcher) ding() {
+	w.Lock()
+	defer w.Unlock()
+	w.t = nil
+	if w.stopped {
+		return
+	}
+	// Don't let us hang in the lock.  The default is safe because the requirement
+	// is that the client get a message after the last config change.  Since this is
+	// a queued chan, we really don't have to stuff anything in it if there's already
+	// something there.
+	select {
+	case w.c <- struct{}{}:
+	default:
+	}
+}
+
+func (w *bsdNetConfigWatcher) watcher() {
+	defer w.Stop()
+
+	// Loop waiting for messages.
+	for {
+		b := make([]byte, 4096)
+		nr, err := syscall.Read(w.s, b)
+		if err != nil {
+			return
+		}
+		msgs, err := syscall.ParseRoutingMessage(b[:nr])
+		if err != nil {
+			vlog.Infof("Couldn't parse: %s", err)
+			continue
+		}
+
+		// Decode the addresses.
+		for _, m := range msgs {
+			switch m.(type) {
+			case *syscall.InterfaceMessage:
+			case *syscall.InterfaceAddrMessage:
+			default:
+				continue
+			}
+			// Changing networks usually spans many seconds and involves
+			// multiple network config changes.  We add histeresis by
+			// setting an alarm when the first change is detected and
+			// not informing the client till the alarm goes off.
+			// NOTE(p): I chose 3 seconds because that covers all the
+			// events involved in moving from one wifi network to another.
+			w.Lock()
+			if w.t == nil {
+				w.t = time.AfterFunc(3*time.Second, w.ding)
+			}
+			w.Unlock()
+		}
+	}
+
+	w.Stop()
+	w.Lock()
+	close(w.c)
+	if w.t != nil {
+		w.t.Stop()
+	}
+	w.Unlock()
+}
diff --git a/runtimes/google/lib/netconfig/ipaux_linux.go b/runtimes/google/lib/netconfig/ipaux_linux.go
new file mode 100644
index 0000000..9e90003
--- /dev/null
+++ b/runtimes/google/lib/netconfig/ipaux_linux.go
@@ -0,0 +1,371 @@
+package netconfig
+
+// We connect to the Netlink Route socket and parse messages to
+// look for network configuration changes.  This is very Linux
+// specific, hence the file name.
+
+import (
+	"errors"
+	"fmt"
+	"net"
+	"sync"
+	"syscall"
+	"time"
+	"unsafe"
+	"veyron2/vlog"
+)
+
+/*
+#include <linux/rtnetlink.h>
+*/
+import "C"
+
+// All rtnetlink attributes start with this header.
+type rtAttrHdr C.struct_rtattr
+
+const rtAttrHdrLen = C.sizeof_struct_rtattr
+
+// The address change messages (RTM_NEWADDR, RTM_DELADDR, RTM_GETADDR).
+type ifaddrMsgHdr C.struct_ifaddrmsg
+
+const ifaddrMsgHdrLen = C.sizeof_struct_ifaddrmsg
+
+type rtAttribute fmt.Stringer
+
+type rtAddressMessage struct {
+	name       string
+	hdr        ifaddrMsgHdr
+	attributes []rtAttribute
+}
+
+// Attribute types (see rtnetlink(7))
+type ifaAddress net.IP
+type ifaLocal net.IP
+type ifaBroadcast net.IP
+type ifaAnycast net.IP
+type ifaMulticast net.IP
+type ifaLabel string
+type ifaCacheInfo C.struct_ifa_cacheinfo
+
+const ifaCacheInfoLen = C.sizeof_struct_ifa_cacheinfo
+
+// String routines to make debugging easier.
+func (a ifaAddress) String() string   { return "Address=" + net.IP(a).String() }
+func (a ifaLocal) String() string     { return "Local=" + net.IP(a).String() }
+func (a ifaBroadcast) String() string { return "Braodcast=" + net.IP(a).String() }
+func (a ifaAnycast) String() string   { return "Anycast=" + net.IP(a).String() }
+func (a ifaMulticast) String() string { return "Anycast=" + net.IP(a).String() }
+func (a ifaLabel) String() string     { return "Label=" + string(a) }
+func (a ifaCacheInfo) String() string {
+	return fmt.Sprintf("CacheInfo[preferred %d valid %d cstamp %d tstamp %d]", a.ifa_prefered, a.ifa_valid, a.cstamp, a.tstamp)
+}
+func (m *rtAddressMessage) String() string {
+	return fmt.Sprintf("%s: index %d %v", m.name, m.hdr.ifa_index, m.attributes)
+}
+
+// Address looks for the address attribute in an rtAddressMessage.  If it isn't there, just assume the null address.
+func (m *rtAddressMessage) Address() net.IP {
+	for _, a := range m.attributes {
+		switch a.(type) {
+		case ifaAddress:
+			return net.IP(a.(ifaAddress))
+		}
+	}
+	return net.IPv4zero
+}
+
+func parsertAddressAttribute(b []byte) (rtAttribute, []byte, error) {
+	if len(b) == 0 {
+		return nil, nil, nil
+	}
+	if len(b) < rtAttrHdrLen {
+		return nil, nil, errors.New("attribute too short")
+	}
+	ahdr := (*rtAttrHdr)(unsafe.Pointer(&b[0]))
+	rounded := ((ahdr.rta_len + 3) / 4) * 4
+	if len(b) < int(rounded) {
+		return nil, nil, errors.New("attribute too short")
+	}
+	remaining := b[rounded:]
+	b = b[rtAttrHdrLen:ahdr.rta_len]
+	switch ahdr.rta_type {
+	case C.IFA_ADDRESS:
+		return rtAttribute(ifaAddress(net.IP(b))), remaining, nil
+	case C.IFA_LOCAL:
+		return rtAttribute(ifaLocal(b)), remaining, nil
+	case C.IFA_LABEL:
+		return rtAttribute(ifaLabel(b)), remaining, nil
+	case C.IFA_BROADCAST:
+		return rtAttribute(ifaBroadcast(b)), remaining, nil
+	case C.IFA_ANYCAST:
+		return rtAttribute(ifaAnycast(b)), remaining, nil
+	case C.IFA_CACHEINFO:
+		if len(b) < ifaCacheInfoLen {
+			return nil, nil, errors.New("attribute too short")
+		}
+		return rtAttribute(ifaCacheInfo(*(*C.struct_ifa_cacheinfo)(unsafe.Pointer(&b[0])))), remaining, nil
+	case C.IFA_MULTICAST:
+		return rtAttribute(ifaMulticast(b)), remaining, nil
+	}
+	return nil, remaining, errors.New("unknown attribute")
+}
+
+func parsertAddressMessage(nlm syscall.NetlinkMessage) (*rtAddressMessage, error) {
+	var name string
+	switch nlm.Header.Type {
+	case C.RTM_NEWADDR:
+		name = "RTM_NEWADDR"
+	case C.RTM_DELADDR:
+		name = "RTM_DELADDR"
+	case C.RTM_GETADDR:
+		name = "RTM_GETADDR"
+	default:
+		return nil, fmt.Errorf("unknown message type")
+	}
+	if len(nlm.Data) < ifaddrMsgHdrLen {
+		return nil, errors.New("bad length")
+	}
+	m := &rtAddressMessage{name: name, hdr: *(*ifaddrMsgHdr)(unsafe.Pointer(&nlm.Data[0]))}
+	b := nlm.Data[ifaddrMsgHdrLen:]
+	for {
+		var a rtAttribute
+		var err error
+		a, b, err = parsertAddressAttribute(b)
+		if b == nil {
+			break
+		}
+		if err == nil {
+			m.attributes = append(m.attributes, a)
+		}
+	}
+	return m, nil
+}
+
+// The link change messages (RTM_NEWLINK, RTM_DELLINK, RTM_GETLINK).
+type ifInfoMsgHdr C.struct_ifinfomsg
+
+const ifInfoMsgHdrLen = C.sizeof_struct_ifinfomsg
+
+type rtLinkMessage struct {
+	name       string
+	hdr        ifInfoMsgHdr
+	attributes []rtAttribute
+}
+
+// Attribute types (see rtnetlink(7))
+type iflaAddress []byte
+type iflaBroadcast []byte
+type iflaIFName string
+type iflaMTU uint32
+type iflaLink int
+type iflaQDisc string
+type iflaOperstate int
+type iflaStats C.struct_rtnl_link_stats
+
+const iflaStatsLen = C.sizeof_struct_rtnl_link_stats
+
+// String routines to make debugging easier.
+func (a iflaAddress) String() string   { return fmt.Sprintf("HWAddress=%v", []byte(a)) }
+func (a iflaBroadcast) String() string { return fmt.Sprintf("HWBroadcast=%v", []byte(a)) }
+func (a iflaIFName) String() string    { return "Name=" + string(a) }
+func (a iflaMTU) String() string       { return fmt.Sprintf("MTU=%d", uint32(a)) }
+func (a iflaLink) String() string      { return fmt.Sprintf("Type=%d", int(a)) }
+func (a iflaQDisc) String() string     { return "Qdisc=" + string(a) }
+func (a iflaStats) String() string {
+	return fmt.Sprintf("Stats[rx %d tx %d ...]", a.rx_packets, a.tx_packets)
+}
+func (a iflaOperstate) String() string { return fmt.Sprintf("Operstate=%d", int(a)) }
+func (m *rtLinkMessage) String() string {
+	return fmt.Sprintf("%s: index %d %v", m.name, m.hdr.ifi_index, m.attributes)
+}
+
+func parseRTLinkAttribute(b []byte) (rtAttribute, []byte, error) {
+	if len(b) == 0 {
+		return nil, nil, nil
+	}
+	if len(b) < rtAttrHdrLen {
+		return nil, nil, errors.New("attribute too short")
+	}
+	ahdr := (*rtAttrHdr)(unsafe.Pointer(&b[0]))
+	rounded := ((ahdr.rta_len + 3) / 4) * 4
+	if len(b) < int(rounded) {
+		return nil, nil, errors.New("attribute too short")
+	}
+	remaining := b[rounded:]
+	b = b[rtAttrHdrLen:ahdr.rta_len]
+	switch ahdr.rta_type {
+	case C.IFLA_ADDRESS:
+		return rtAttribute(iflaAddress(b)), remaining, nil
+	case C.IFLA_BROADCAST:
+		return rtAttribute(iflaBroadcast(b)), remaining, nil
+	case C.IFLA_IFNAME:
+		return rtAttribute(iflaIFName(string(b))), remaining, nil
+	case C.IFLA_MTU:
+		return rtAttribute(iflaMTU(*(*C.uint)(unsafe.Pointer(&b[0])))), remaining, nil
+	case C.IFLA_LINK:
+		return rtAttribute(iflaMTU(*(*C.int)(unsafe.Pointer(&b[0])))), remaining, nil
+	case C.IFLA_QDISC:
+		return rtAttribute(iflaQDisc(string(b))), remaining, nil
+	case C.IFLA_STATS:
+		if len(b) < iflaStatsLen {
+			return nil, remaining, errors.New("attribute too short")
+		}
+		return rtAttribute(iflaStats(*(*C.struct_rtnl_link_stats)(unsafe.Pointer(&b[0])))), remaining, nil
+	case C.IFLA_OPERSTATE:
+		return rtAttribute(iflaOperstate(*(*C.int)(unsafe.Pointer(&b[0])))), remaining, nil
+	}
+	return nil, remaining, errors.New("unknown attribute")
+}
+
+func parsertLinkMessage(nlm syscall.NetlinkMessage) (*rtLinkMessage, error) {
+	var name string
+	switch nlm.Header.Type {
+	case C.RTM_NEWLINK:
+		name = "RTM_NEWLINK"
+	case C.RTM_DELLINK:
+		name = "RTM_DELLINK"
+	case C.RTM_GETLINK:
+		name = "RTM_GETLINK"
+	default:
+		return nil, fmt.Errorf("unknown message type")
+	}
+	if len(nlm.Data) < ifInfoMsgHdrLen {
+		return nil, errors.New("bad length")
+	}
+	m := &rtLinkMessage{name: name, hdr: *(*ifInfoMsgHdr)(unsafe.Pointer(&nlm.Data[0]))}
+	b := nlm.Data[ifInfoMsgHdrLen:]
+	for {
+		var a rtAttribute
+		var err error
+		a, b, err = parseRTLinkAttribute(b)
+		if b == nil {
+			break
+		}
+		if err == nil {
+			m.attributes = append(m.attributes, a)
+		}
+	}
+	return m, nil
+}
+
+type rtnetlinkWatcher struct {
+	sync.Mutex
+	t       *time.Timer
+	c       chan struct{}
+	s       int
+	stopped bool
+}
+
+func (w *rtnetlinkWatcher) Stop() {
+	w.Lock()
+	defer w.Unlock()
+	if w.stopped {
+		return
+	}
+	w.stopped = true
+	syscall.Close(w.s)
+}
+
+func (w *rtnetlinkWatcher) Channel() chan struct{} {
+	return w.c
+}
+
+const (
+	GROUPS = C.RTMGRP_LINK | C.RTMGRP_IPV4_IFADDR | C.RTMGRP_IPV6_IFADDR | C.RTMGRP_NOTIFY
+)
+
+// NewNetConfigWatcher returns a watcher that wakes up anyone
+// calling the Wait routine whenever the configuration changes.
+func NewNetConfigWatcher() (NetConfigWatcher, error) {
+	s, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, syscall.NETLINK_ROUTE)
+	if err != nil {
+		vlog.Infof("netconfig socket failed: %s", err)
+		return nil, err
+	}
+
+	lsa := &syscall.SockaddrNetlink{Family: syscall.AF_NETLINK, Groups: GROUPS}
+	if err := syscall.Bind(s, lsa); err != nil {
+		vlog.Infof("netconfig bind failed: %s", err)
+		return nil, err
+	}
+
+	w := &rtnetlinkWatcher{c: make(chan struct{}, 1), s: s}
+	go w.watcher()
+	return w, nil
+}
+
+func (w *rtnetlinkWatcher) ding() {
+	w.Lock()
+	defer w.Unlock()
+	w.t = nil
+	if w.stopped {
+		return
+	}
+	// Don't let us hang in the lock.  The default is safe because the requirement
+	// is that the client get a message after the last config change.  Since this is
+	// a queued chan, we really don't have to stuff anything in it if there's already
+	// something there.
+	select {
+	case w.c <- struct{}{}:
+	default:
+	}
+}
+
+func (w *rtnetlinkWatcher) watcher() {
+	var newAddrs []net.IP
+	for {
+		rb := make([]byte, 4096)
+		nr, _, err := syscall.Recvfrom(w.s, rb, 0)
+		if err != nil {
+			break
+		}
+		rb = rb[:nr]
+		msgs, err := syscall.ParseNetlinkMessage(rb)
+		if err != nil {
+			vlog.Infof("ParseNetlinkMessage failed: %s", err)
+			continue
+		}
+	L:
+		for _, m := range msgs {
+			if am, err := parsertAddressMessage(m); err == nil {
+				// NOTE(p): We get continuous NEWADDR messages about some
+				// IPv6 addresses in Google corp.  Just ignore duplicate back
+				// to back NEWADDRs about the same addresses.
+				if am.name == "RTM_NEWADDR" {
+					addr := am.Address()
+					for _, a := range newAddrs {
+						if addr.Equal(a) {
+							break L
+						}
+					}
+					newAddrs = append(newAddrs, addr)
+				} else {
+					newAddrs = nil
+				}
+			} else if _, err := parsertLinkMessage(m); err == nil {
+				newAddrs = nil
+			} else {
+				continue
+			}
+			// Changing networks usually spans many seconds and involves
+			// multiple network config changes.  We add histeresis by
+			// setting an alarm when the first change is detected and
+			// not informing the client till the alarm goes off.
+			// NOTE(p): I chose 3 seconds because that covers all the
+			// events involved in moving from one wifi network to another.
+			w.Lock()
+			if w.t == nil {
+				w.t = time.AfterFunc(3*time.Second, w.ding)
+			}
+			w.Unlock()
+		}
+	}
+
+	w.Stop()
+	w.Lock()
+	close(w.c)
+	if w.t != nil {
+		w.t.Stop()
+	}
+	w.Unlock()
+}
diff --git a/runtimes/google/lib/netconfig/model.go b/runtimes/google/lib/netconfig/model.go
new file mode 100644
index 0000000..c65afb6
--- /dev/null
+++ b/runtimes/google/lib/netconfig/model.go
@@ -0,0 +1,17 @@
+// package netconfig implements a network configuration watcher.
+// NOTE(p): This is also where we should put any code that changes
+//          network configuration.
+
+package netconfig
+
+// NetConfigWatcher sends on channel whenever an interface or interface address
+// is added or deleted.
+type NetConfigWatcher interface {
+	// Stop watching.
+	Stop()
+
+	// A channel that returns an item whenever the network addresses or
+	// interfaces have changed. It is up to the caller to reread the
+	// network configuration in such cases.
+	Channel() chan struct{}
+}
diff --git a/runtimes/google/naming/namespace/all_test.go b/runtimes/google/naming/namespace/all_test.go
index 3925350..e921c39 100644
--- a/runtimes/google/naming/namespace/all_test.go
+++ b/runtimes/google/naming/namespace/all_test.go
@@ -383,6 +383,13 @@
 	for _, test := range globTests {
 		out := doGlob(t, r, ns, test.pattern)
 		compare(t, "Glob", test.pattern, test.expected, out)
+		// Do the same with a full rooted name.
+		out = doGlob(t, r, ns, naming.JoinAddressName(root.name, test.pattern))
+		var expectedWithRoot []string
+		for _, s := range test.expected {
+			expectedWithRoot = append(expectedWithRoot, naming.JoinAddressName(root.name, s))
+		}
+		compare(t, "Glob", test.pattern, expectedWithRoot, out)
 	}
 }
 
diff --git a/runtimes/google/naming/namespace/glob.go b/runtimes/google/naming/namespace/glob.go
index e6071a8..2560bfb 100644
--- a/runtimes/google/naming/namespace/glob.go
+++ b/runtimes/google/naming/namespace/glob.go
@@ -80,7 +80,8 @@
 
 // Glob implements naming.MountTable.Glob.
 func (ns *namespace) Glob(ctx context.T, pattern string) (chan naming.MountEntry, error) {
-	g, err := glob.Parse(pattern)
+	root, globPattern := naming.SplitAddressName(pattern)
+	g, err := glob.Parse(globPattern)
 	if err != nil {
 		return nil, err
 	}
@@ -90,6 +91,9 @@
 	var prefixElements []string
 	prefixElements, g = g.SplitFixedPrefix()
 	prefix := strings.Join(prefixElements, "/")
+	if len(root) != 0 {
+		prefix = naming.JoinAddressName(root, prefix)
+	}
 
 	// Start a thread to get the results and return the reply channel to the caller.
 	servers := ns.rootName(prefix)
diff --git a/runtimes/google/rt/mgmt.go b/runtimes/google/rt/mgmt.go
index ecb62f1..e476ec0 100644
--- a/runtimes/google/rt/mgmt.go
+++ b/runtimes/google/rt/mgmt.go
@@ -7,7 +7,6 @@
 	"time"
 
 	"veyron/runtimes/google/appcycle"
-	vflag "veyron/security/flag"
 	"veyron/services/mgmt/lib/exec"
 
 	"veyron2"
@@ -57,7 +56,7 @@
 	if ep, err = m.server.Listen("tcp", "127.0.0.1:0"); err != nil {
 		return err
 	}
-	if err := m.server.Serve("", ipc.SoloDispatcher(appcycle.NewServerAppCycle(m), vflag.NewAuthorizerOrDie())); err != nil {
+	if err := m.server.Serve("", ipc.SoloDispatcher(appcycle.NewServerAppCycle(m), nil)); err != nil {
 		return err
 	}
 	return m.callbackToParent(parentName, naming.JoinAddressName(ep.String(), ""))
diff --git a/runtimes/google/security/jni/authorizer.go b/runtimes/google/security/jni/authorizer.go
index 9a00b91..e1bf576 100644
--- a/runtimes/google/security/jni/authorizer.go
+++ b/runtimes/google/security/jni/authorizer.go
@@ -65,11 +65,11 @@
 	defer C.DetachCurrentThread(a.jVM)
 	// Create a Java context.
 	util.GoRef(&context) // Un-refed when the Java Context object is finalized.
-	cid := C.jmethodID(util.JMethodIDPtr(env, jContextImplClass, "<init>", fmt.Sprintf("(%s)%s", util.LongSign, util.VoidSign)))
+	cid := C.jmethodID(util.JMethodIDPtrOrDie(env, jContextImplClass, "<init>", fmt.Sprintf("(%s)%s", util.LongSign, util.VoidSign)))
 	jContext := C.CallAuthorizerNewContextObject(env, jContextImplClass, cid, C.jlong(util.PtrValue(&context)))
 	// Run Java Authorizer.
 	contextSign := "Lcom/veyron2/security/Context;"
-	mid := C.jmethodID(util.JMethodIDPtr(env, C.GetObjectClass(env, a.jAuth), "authorize", fmt.Sprintf("(%s)%s", contextSign, util.VoidSign)))
+	mid := C.jmethodID(util.JMethodIDPtrOrDie(env, C.GetObjectClass(env, a.jAuth), "authorize", fmt.Sprintf("(%s)%s", contextSign, util.VoidSign)))
 	if mid == nil {
 		return fmt.Errorf("Srdjan's error")
 	}
diff --git a/runtimes/google/security/jni/caveat.go b/runtimes/google/security/jni/caveat.go
index e3901dc..b09885a 100644
--- a/runtimes/google/security/jni/caveat.go
+++ b/runtimes/google/security/jni/caveat.go
@@ -58,10 +58,10 @@
 	C.AttachCurrentThread(c.jVM, &env, nil)
 	defer C.DetachCurrentThread(c.jVM)
 	util.GoRef(&context) // un-refed when the Java Context object is finalized.
-	cid := C.jmethodID(util.JMethodIDPtr(env, jContextImplClass, "<init>", fmt.Sprintf("(%s)%s", util.LongSign, util.VoidSign)))
+	cid := C.jmethodID(util.JMethodIDPtrOrDie(env, jContextImplClass, "<init>", fmt.Sprintf("(%s)%s", util.LongSign, util.VoidSign)))
 	jContext := C.CallCaveatNewContextObject(env, jContextClass, cid, C.jlong(util.PtrValue(&context)))
 	contextSign := "Lcom/veyron2/security/Context;"
-	mid := C.jmethodID(util.JMethodIDPtr(env, C.GetObjectClass(env, c.jCaveat), "validate", fmt.Sprintf("(%s)%s", contextSign, util.VoidSign)))
+	mid := C.jmethodID(util.JMethodIDPtrOrDie(env, C.GetObjectClass(env, c.jCaveat), "validate", fmt.Sprintf("(%s)%s", contextSign, util.VoidSign)))
 	C.CallCaveatValidateMethod(env, c.jCaveat, mid, jContext)
 	return util.JExceptionMsg(env)
 }
diff --git a/runtimes/google/security/jni/context.go b/runtimes/google/security/jni/context.go
index 57e6a31..533f2d9 100644
--- a/runtimes/google/security/jni/context.go
+++ b/runtimes/google/security/jni/context.go
@@ -62,7 +62,7 @@
 	var env *C.JNIEnv
 	C.AttachCurrentThread(c.jVM, &env, nil)
 	defer C.DetachCurrentThread(c.jVM)
-	mid := C.jmethodID(util.JMethodIDPtr(env, C.GetObjectClass(env, c.jContext), "method", fmt.Sprintf("()%s", util.StringSign)))
+	mid := C.jmethodID(util.JMethodIDPtrOrDie(env, C.GetObjectClass(env, c.jContext), "method", fmt.Sprintf("()%s", util.StringSign)))
 	return util.GoString(env, C.CallContextStringMethod(env, c.jContext, mid))
 }
 
@@ -70,7 +70,7 @@
 	var env *C.JNIEnv
 	C.AttachCurrentThread(c.jVM, &env, nil)
 	defer C.DetachCurrentThread(c.jVM)
-	mid := C.jmethodID(util.JMethodIDPtr(env, C.GetObjectClass(env, c.jContext), "name", fmt.Sprintf("()%s", util.StringSign)))
+	mid := C.jmethodID(util.JMethodIDPtrOrDie(env, C.GetObjectClass(env, c.jContext), "name", fmt.Sprintf("()%s", util.StringSign)))
 	return util.GoString(env, C.CallContextStringMethod(env, c.jContext, mid))
 }
 
@@ -78,7 +78,7 @@
 	var env *C.JNIEnv
 	C.AttachCurrentThread(c.jVM, &env, nil)
 	defer C.DetachCurrentThread(c.jVM)
-	mid := C.jmethodID(util.JMethodIDPtr(env, C.GetObjectClass(env, c.jContext), "suffix", fmt.Sprintf("()%s", util.StringSign)))
+	mid := C.jmethodID(util.JMethodIDPtrOrDie(env, C.GetObjectClass(env, c.jContext), "suffix", fmt.Sprintf("()%s", util.StringSign)))
 	return util.GoString(env, C.CallContextStringMethod(env, c.jContext, mid))
 }
 
@@ -86,7 +86,7 @@
 	var env *C.JNIEnv
 	C.AttachCurrentThread(c.jVM, &env, nil)
 	defer C.DetachCurrentThread(c.jVM)
-	mid := C.jmethodID(util.JMethodIDPtr(env, C.GetObjectClass(env, c.jContext), "label", fmt.Sprintf("()%s", util.IntSign)))
+	mid := C.jmethodID(util.JMethodIDPtrOrDie(env, C.GetObjectClass(env, c.jContext), "label", fmt.Sprintf("()%s", util.IntSign)))
 	return security.Label(C.CallContextIntMethod(env, c.jContext, mid))
 }
 
@@ -100,7 +100,7 @@
 	C.AttachCurrentThread(c.jVM, &env, nil)
 	defer C.DetachCurrentThread(c.jVM)
 	publicIDSign := "Lcom/veyron2/security/PublicID;"
-	mid := C.jmethodID(util.JMethodIDPtr(env, C.GetObjectClass(env, c.jContext), "localID", fmt.Sprintf("()%s", publicIDSign)))
+	mid := C.jmethodID(util.JMethodIDPtrOrDie(env, C.GetObjectClass(env, c.jContext), "localID", fmt.Sprintf("()%s", publicIDSign)))
 	jID := C.CallContextPublicIDMethod(env, c.jContext, mid)
 	return newPublicID(env, jID)
 }
@@ -110,7 +110,7 @@
 	C.AttachCurrentThread(c.jVM, &env, nil)
 	defer C.DetachCurrentThread(c.jVM)
 	publicIDSign := "Lcom/veyron2/security/PublicID;"
-	mid := C.jmethodID(util.JMethodIDPtr(env, C.GetObjectClass(env, c.jContext), "remoteID", fmt.Sprintf("()%s", publicIDSign)))
+	mid := C.jmethodID(util.JMethodIDPtrOrDie(env, C.GetObjectClass(env, c.jContext), "remoteID", fmt.Sprintf("()%s", publicIDSign)))
 	jID := C.CallContextPublicIDMethod(env, c.jContext, mid)
 	return newPublicID(env, jID)
 }
@@ -119,7 +119,7 @@
 	var env *C.JNIEnv
 	C.AttachCurrentThread(c.jVM, &env, nil)
 	defer C.DetachCurrentThread(c.jVM)
-	mid := C.jmethodID(util.JMethodIDPtr(env, C.GetObjectClass(env, c.jContext), "localEndpoint", fmt.Sprintf("()%s", util.StringSign)))
+	mid := C.jmethodID(util.JMethodIDPtrOrDie(env, C.GetObjectClass(env, c.jContext), "localEndpoint", fmt.Sprintf("()%s", util.StringSign)))
 	// TODO(spetrovic): create a Java Endpoint interface.
 	epStr := util.GoString(env, C.CallContextStringMethod(env, c.jContext, mid))
 	ep, err := inaming.NewEndpoint(epStr)
@@ -133,7 +133,7 @@
 	var env *C.JNIEnv
 	C.AttachCurrentThread(c.jVM, &env, nil)
 	defer C.DetachCurrentThread(c.jVM)
-	mid := C.jmethodID(util.JMethodIDPtr(env, C.GetObjectClass(env, c.jContext), "remoteEndpoint", fmt.Sprintf("()%s", util.StringSign)))
+	mid := C.jmethodID(util.JMethodIDPtrOrDie(env, C.GetObjectClass(env, c.jContext), "remoteEndpoint", fmt.Sprintf("()%s", util.StringSign)))
 	// TODO(spetrovic): create a Java Endpoint interface.
 	epStr := util.GoString(env, C.CallContextStringMethod(env, c.jContext, mid))
 	ep, err := inaming.NewEndpoint(epStr)
diff --git a/runtimes/google/security/jni/jni.go b/runtimes/google/security/jni/jni.go
index 7f89560..2e50950 100644
--- a/runtimes/google/security/jni/jni.go
+++ b/runtimes/google/security/jni/jni.go
@@ -87,7 +87,7 @@
 		util.JThrowV(env, err)
 		return C.jobject(nil)
 	}
-	cid := C.jmethodID(util.JMethodIDPtr(env, jECPublicKeyInfoClass, "<init>", fmt.Sprintf("([%s[%s[%s%s)%s", util.ByteSign, util.ByteSign, util.ByteSign, util.IntSign, util.VoidSign)))
+	cid := C.jmethodID(util.JMethodIDPtrOrDie(env, jECPublicKeyInfoClass, "<init>", fmt.Sprintf("([%s[%s[%s%s)%s", util.ByteSign, util.ByteSign, util.ByteSign, util.IntSign, util.VoidSign)))
 	return C.CallNewECPublicKeyInfoObject(env, jECPublicKeyInfoClass, cid, C.jbyteArray(util.JByteArrayPtr(env, key.X.Bytes())), C.jbyteArray(util.JByteArrayPtr(env, key.Y.Bytes())), C.jbyteArray(util.JByteArrayPtr(env, encoded)), C.jint(key.Params().BitSize))
 }
 
@@ -109,9 +109,9 @@
 	jServiceCaveats := C.NewObjectArray(env, C.jsize(len(sCaveats)), jServiceCaveatClass, nil)
 	for i, sCaveat := range sCaveats {
 		util.GoRef(&sCaveat) // Un-refed when the Java Caveat object is finalized.
-		cid := C.jmethodID(util.JMethodIDPtr(env, jCaveatImplClass, "<init>", fmt.Sprintf("(%s)%s", util.LongSign, util.VoidSign)))
+		cid := C.jmethodID(util.JMethodIDPtrOrDie(env, jCaveatImplClass, "<init>", fmt.Sprintf("(%s)%s", util.LongSign, util.VoidSign)))
 		jCaveat := C.CallNewCaveatObject(env, jCaveatImplClass, cid, C.jlong(util.PtrValue(&sCaveat)))
-		scid := C.jmethodID(util.JMethodIDPtr(env, jServiceCaveatClass, "<init>", fmt.Sprintf("(%s%s)%s", util.StringSign, caveatSign, util.VoidSign)))
+		scid := C.jmethodID(util.JMethodIDPtrOrDie(env, jServiceCaveatClass, "<init>", fmt.Sprintf("(%s%s)%s", util.StringSign, caveatSign, util.VoidSign)))
 		jServiceCaveat := C.CallNewServiceCaveatObject(env, jServiceCaveatClass, scid, C.jstring(util.JStringPtr(env, string(sCaveat.Service))), jCaveat)
 		C.SetObjectArrayElement(env, jServiceCaveats, C.jsize(i), jServiceCaveat)
 	}
diff --git a/runtimes/google/security/jni/publicid.go b/runtimes/google/security/jni/publicid.go
index dd4e778..32af0b5 100644
--- a/runtimes/google/security/jni/publicid.go
+++ b/runtimes/google/security/jni/publicid.go
@@ -75,7 +75,7 @@
 	var env *C.JNIEnv
 	C.AttachCurrentThread(id.jVM, &env, nil)
 	defer C.DetachCurrentThread(id.jVM)
-	mid := C.jmethodID(util.JMethodIDPtr(env, C.GetObjectClass(env, id.jPublicID), "names", fmt.Sprintf("()[%s", util.StringSign)))
+	mid := C.jmethodID(util.JMethodIDPtrOrDie(env, C.GetObjectClass(env, id.jPublicID), "names", fmt.Sprintf("()[%s", util.StringSign)))
 	names := C.CallPublicIDNamesMethod(env, id.jPublicID, mid)
 	ret := make([]string, int(C.GetArrayLength(env, C.jarray(names))))
 	for i := 0; i < len(ret); i++ {
@@ -88,7 +88,7 @@
 	var env *C.JNIEnv
 	C.AttachCurrentThread(id.jVM, &env, nil)
 	defer C.DetachCurrentThread(id.jVM)
-	mid := C.jmethodID(util.JMethodIDPtr(env, C.GetObjectClass(env, id.jPublicID), "match", fmt.Sprintf("(%s)%s", util.StringSign, util.BoolSign)))
+	mid := C.jmethodID(util.JMethodIDPtrOrDie(env, C.GetObjectClass(env, id.jPublicID), "match", fmt.Sprintf("(%s)%s", util.StringSign, util.BoolSign)))
 	return C.CallPublicIDMatchMethod(env, id.jPublicID, mid, C.jstring(util.JStringPtr(env, string(pattern)))) == C.JNI_TRUE
 }
 
@@ -96,7 +96,7 @@
 	var env *C.JNIEnv
 	C.AttachCurrentThread(id.jVM, &env, nil)
 	defer C.DetachCurrentThread(id.jVM)
-	mid := C.jmethodID(util.JMethodIDPtr(env, C.GetObjectClass(env, id.jPublicID), "publicKey", fmt.Sprintf("()%s", util.ObjectSign)))
+	mid := C.jmethodID(util.JMethodIDPtrOrDie(env, C.GetObjectClass(env, id.jPublicID), "publicKey", fmt.Sprintf("()%s", util.ObjectSign)))
 	jPublicKey := C.CallPublicIDPublicKeyMethod(env, id.jPublicID, mid)
 	return newPublicKey(env, jPublicKey)
 }
@@ -108,9 +108,9 @@
 	util.GoRef(&context) // un-refed when the Java Context object is finalized.
 	contextSign := "Lcom/veyron2/security/Context;"
 	publicIDSign := "Lcom/veyron2/security/PublicID;"
-	cid := C.jmethodID(util.JMethodIDPtr(env, jContextImplClass, "<init>", fmt.Sprintf("(%s)%s", util.LongSign, util.VoidSign)))
+	cid := C.jmethodID(util.JMethodIDPtrOrDie(env, jContextImplClass, "<init>", fmt.Sprintf("(%s)%s", util.LongSign, util.VoidSign)))
 	jContext := C.CallPublicIDNewContextObject(env, jContextImplClass, cid, C.jlong(util.PtrValue(&context)))
-	mid := C.jmethodID(util.JMethodIDPtr(env, C.GetObjectClass(env, id.jPublicID), "authorize", fmt.Sprintf("(%s)%s", contextSign, publicIDSign)))
+	mid := C.jmethodID(util.JMethodIDPtrOrDie(env, C.GetObjectClass(env, id.jPublicID), "authorize", fmt.Sprintf("(%s)%s", contextSign, publicIDSign)))
 	jPublicID := C.CallPublicIDAuthorizeMethod(env, id.jPublicID, mid, jContext)
 	if err := util.JExceptionMsg(env); err != nil {
 		return nil, err
@@ -123,7 +123,7 @@
 	C.AttachCurrentThread(id.jVM, &env, nil)
 	defer C.DetachCurrentThread(id.jVM)
 	serviceCaveatSign := "Lcom/veyron2/security/ServiceCaveat;"
-	mid := C.jmethodID(util.JMethodIDPtr(env, C.GetObjectClass(env, id.jPublicID), "thirdPartyCaveats", fmt.Sprintf("()[%s", serviceCaveatSign)))
+	mid := C.jmethodID(util.JMethodIDPtrOrDie(env, C.GetObjectClass(env, id.jPublicID), "thirdPartyCaveats", fmt.Sprintf("()[%s", serviceCaveatSign)))
 	jServiceCaveats := C.CallPublicIDThirdPartyCaveatsMethod(env, id.jPublicID, mid)
 	length := int(C.GetArrayLength(env, C.jarray(jServiceCaveats)))
 	sCaveats := make([]security.ServiceCaveat, length)
@@ -140,7 +140,7 @@
 func newPublicKey(env *C.JNIEnv, jPublicKey C.jobject) *ecdsa.PublicKey {
 	keySign := "Ljava/security/interfaces/ECPublicKey;"
 	keyInfoSign := "Lcom/veyron/runtimes/google/security/JNIPublicID$ECPublicKeyInfo;"
-	mid := C.jmethodID(util.JMethodIDPtr(env, jPublicIDImplClass, "getKeyInfo", fmt.Sprintf("(%s)%s", keySign, keyInfoSign)))
+	mid := C.jmethodID(util.JMethodIDPtrOrDie(env, jPublicIDImplClass, "getKeyInfo", fmt.Sprintf("(%s)%s", keySign, keyInfoSign)))
 	jKeyInfo := C.CallPublicIDGetKeyInfoMethod(env, jPublicIDImplClass, mid, jPublicKey)
 	keyX := new(big.Int).SetBytes(util.JByteArrayField(env, jKeyInfo, "keyX"))
 	keyY := new(big.Int).SetBytes(util.JByteArrayField(env, jKeyInfo, "keyY"))
diff --git a/runtimes/google/vsync/vsync.vdl.go b/runtimes/google/vsync/vsync.vdl.go
index fb9834a..f81a4b7 100644
--- a/runtimes/google/vsync/vsync.vdl.go
+++ b/runtimes/google/vsync/vsync.vdl.go
@@ -14,7 +14,7 @@
 	_gen_ipc "veyron2/ipc"
 	_gen_naming "veyron2/naming"
 	_gen_rt "veyron2/rt"
-	_gen_vdl "veyron2/vdl"
+	_gen_vdlutil "veyron2/vdl/vdlutil"
 	_gen_wiretype "veyron2/wiretype"
 )
 
@@ -174,10 +174,10 @@
 		case _gen_ipc.Client:
 			client = o
 		default:
-			return nil, _gen_vdl.ErrUnrecognizedOption
+			return nil, _gen_vdlutil.ErrUnrecognizedOption
 		}
 	default:
-		return nil, _gen_vdl.ErrTooManyOptionsToBind
+		return nil, _gen_vdlutil.ErrTooManyOptionsToBind
 	}
 	stub := &clientStubSync{client: client, name: name}
 
@@ -276,7 +276,7 @@
 		OutStream: 82,
 	}
 
-	result.TypeDefs = []_gen_vdl.Any{
+	result.TypeDefs = []_gen_vdlutil.Any{
 		_gen_wiretype.NamedPrimitiveType{Type: 0x3, Name: "veyron/runtimes/google/vsync.DeviceID", Tags: []string(nil)}, _gen_wiretype.NamedPrimitiveType{Type: 0x35, Name: "veyron/runtimes/google/vsync.GenID", Tags: []string(nil)}, _gen_wiretype.MapType{Key: 0x41, Elem: 0x42, Name: "veyron/runtimes/google/vsync.GenVector", Tags: []string(nil)}, _gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}, _gen_wiretype.NamedPrimitiveType{Type: 0x35, Name: "veyron/runtimes/google/vsync.LSN", Tags: []string(nil)}, _gen_wiretype.NamedPrimitiveType{Type: 0x32, Name: "byte", Tags: []string(nil)}, _gen_wiretype.ArrayType{Elem: 0x46, Len: 0x10, Name: "veyron2/storage.ID", Tags: []string(nil)}, _gen_wiretype.NamedPrimitiveType{Type: 0x35, Name: "veyron2/storage.Version", Tags: []string(nil)}, _gen_wiretype.SliceType{Elem: 0x48, Name: "", Tags: []string(nil)}, _gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "anydata", Tags: []string(nil)}, _gen_wiretype.NamedPrimitiveType{Type: 0x32, Name: "veyron2/storage.TagOp", Tags: []string(nil)}, _gen_wiretype.StructType{
 			[]_gen_wiretype.FieldType{
 				_gen_wiretype.FieldType{Type: 0x4b, Name: "Op"},
diff --git a/services/mgmt/build/constants.go b/services/mgmt/build/constants.go
deleted file mode 100644
index d150780..0000000
--- a/services/mgmt/build/constants.go
+++ /dev/null
@@ -1,64 +0,0 @@
-package build
-
-type OperatingSystem uint8
-
-const (
-	LINUX OperatingSystem = iota
-	DARWIN
-	WINDOWS
-)
-
-func (os OperatingSystem) String() string {
-	switch os {
-	case LINUX:
-		return "linux"
-	case DARWIN:
-		return "darwin"
-	case WINDOWS:
-		return "windows"
-	default:
-		return "unknown"
-	}
-}
-
-type Format uint8
-
-const (
-	ELF Format = iota
-	MACH
-	PE
-)
-
-func (format Format) String() string {
-	switch format {
-	case ELF:
-		return "elf"
-	case MACH:
-		return "mach-o"
-	case PE:
-		return "pe"
-	default:
-		return "unknown"
-	}
-}
-
-type Architecture uint8
-
-const (
-	AMD64 Architecture = iota
-	ARM
-	X86
-)
-
-func (arch Architecture) String() string {
-	switch arch {
-	case AMD64:
-		return "amd64"
-	case ARM:
-		return "arm"
-	case X86:
-		return "x86"
-	default:
-		return "unknown"
-	}
-}
diff --git a/services/mgmt/build/impl/impl_test.go b/services/mgmt/build/impl/impl_test.go
index 31b2d71..0404e7b 100644
--- a/services/mgmt/build/impl/impl_test.go
+++ b/services/mgmt/build/impl/impl_test.go
@@ -1,6 +1,7 @@
 package impl
 
 import (
+	"io"
 	"os"
 	"path/filepath"
 	"strings"
@@ -49,31 +50,43 @@
 	}
 }
 
-func invokeBuild(t *testing.T, client build.Build, files []build.File) ([]byte, error) {
+func invokeBuild(t *testing.T, client build.Build, files []build.File) ([]byte, []build.File, error) {
 	stream, err := client.Build(rt.R().NewContext())
 	if err != nil {
 		t.Errorf("Build() failed: %v", err)
-		return nil, err
+		return nil, nil, err
 	}
 	for _, file := range files {
 		if err := stream.Send(file); err != nil {
 			t.Logf("Send() failed: %v", err)
 			stream.Cancel()
-			return nil, err
+			return nil, nil, err
 		}
 	}
 	if err := stream.CloseSend(); err != nil {
 		t.Logf("CloseSend() failed: %v", err)
 		stream.Cancel()
-		return nil, err
+		return nil, nil, err
+	}
+	bins := make([]build.File, 0)
+	for {
+		bin, err := stream.Recv()
+		if err != nil && err != io.EOF {
+			t.Logf("Recv() failed: %v", err)
+			return nil, nil, err
+		}
+		if err == io.EOF {
+			break
+		}
+		bins = append(bins, bin)
 	}
 	output, err := stream.Finish()
 	if err != nil {
 		t.Logf("Finish() failed: %v", err)
 		stream.Cancel()
-		return nil, err
+		return nil, nil, err
 	}
-	return output, nil
+	return output, bins, nil
 }
 
 const mainSrc = `package main
@@ -97,13 +110,16 @@
 			Contents: []byte(mainSrc),
 		},
 	}
-	output, err := invokeBuild(t, client, files)
+	output, bins, err := invokeBuild(t, client, files)
 	if err != nil {
 		t.FailNow()
 	}
 	if got, expected := strings.TrimSpace(string(output)), "test"; got != expected {
 		t.Fatalf("Unexpected output: got %v, expected %v", got, expected)
 	}
+	if got, expected := len(bins), 1; got != expected {
+		t.Fatalf("Unexpected number of binaries: got %v, expected %v", got, expected)
+	}
 }
 
 // TestFailure checks that the build server fails to build a package
@@ -118,7 +134,7 @@
 			Contents: []byte(""),
 		},
 	}
-	if _, err := invokeBuild(t, client, files); err == nil {
+	if _, _, err := invokeBuild(t, client, files); err == nil {
 		t.FailNow()
 	}
 }
diff --git a/services/mgmt/build/impl/invoker.go b/services/mgmt/build/impl/invoker.go
index b2b9c52..2ef2585 100644
--- a/services/mgmt/build/impl/invoker.go
+++ b/services/mgmt/build/impl/invoker.go
@@ -1,6 +1,7 @@
 package impl
 
 import (
+	"bytes"
 	"errors"
 	"io"
 	"io/ioutil"
@@ -15,7 +16,8 @@
 )
 
 var (
-	errOperationFailed = errors.New("operation failed")
+	errBuildFailed   = errors.New("build failed")
+	errInternalError = errors.New("internal error")
 )
 
 // invoker holds the state of a build server invocation.
@@ -33,25 +35,28 @@
 
 // BUILD INTERFACE IMPLEMENTATION
 
+// TODO(jsimsa): Add support for building for a specific profile
+// specified as a suffix the Build().
 func (i *invoker) Build(_ ipc.ServerContext, stream build.BuildServiceBuildStream) ([]byte, error) {
+	vlog.VI(1).Infof("Build() called.")
 	dir, prefix := "", ""
 	dirPerm, filePerm := os.FileMode(0700), os.FileMode(0600)
 	root, err := ioutil.TempDir(dir, prefix)
 	if err != nil {
 		vlog.Errorf("TempDir(%v, %v) failed: %v", dir, prefix, err)
-		return nil, errOperationFailed
+		return nil, errInternalError
 	}
 	defer os.RemoveAll(root)
 	srcDir := filepath.Join(root, "go", "src")
 	if err := os.MkdirAll(srcDir, dirPerm); err != nil {
 		vlog.Errorf("MkdirAll(%v, %v) failed: %v", srcDir, dirPerm, err)
-		return nil, errOperationFailed
+		return nil, errInternalError
 	}
 	for {
 		srcFile, err := stream.Recv()
 		if err != nil && err != io.EOF {
 			vlog.Errorf("Recv() failed: %v", err)
-			return nil, errOperationFailed
+			return nil, errInternalError
 		}
 		if err == io.EOF {
 			break
@@ -60,21 +65,50 @@
 		dir := filepath.Dir(filePath)
 		if err := os.MkdirAll(dir, dirPerm); err != nil {
 			vlog.Errorf("MkdirAll(%v, %v) failed: %v", dir, dirPerm, err)
-			return nil, errOperationFailed
+			return nil, errInternalError
 		}
 		if err := ioutil.WriteFile(filePath, srcFile.Contents, filePerm); err != nil {
 			vlog.Errorf("WriteFile(%v, %v) failed: %v", filePath, filePerm, err)
-			return nil, errOperationFailed
+			return nil, errInternalError
 		}
 	}
-	cmd := exec.Command(i.gobin, "build", "-v", "...")
+	cmd := exec.Command(i.gobin, "install", "-v", "...")
 	cmd.Env = append(cmd.Env, "GOPATH="+filepath.Dir(srcDir))
-	bytes, err := cmd.CombinedOutput()
-	if err != nil {
-		vlog.Errorf("CombinedOutput() failed: %v", err)
-		return nil, errOperationFailed
+	var output bytes.Buffer
+	cmd.Stdout = &output
+	cmd.Stderr = &output
+	if err := cmd.Run(); err != nil {
+		vlog.Errorf("Run() failed: %v", err)
+		if output.Len() != 0 {
+			vlog.Errorf("%v", output.String())
+		}
+		return output.Bytes(), errBuildFailed
 	}
-	return bytes, nil
+	binDir := filepath.Join(root, "go", "bin")
+	files, err := ioutil.ReadDir(binDir)
+	if err != nil {
+		vlog.Errorf("ReadDir(%v) failed: %v", binDir, err)
+		return nil, errInternalError
+	}
+	// TODO(jsimsa): Analyze the binary files for non-standard shared
+	// library dependencies.
+	for _, file := range files {
+		binPath := filepath.Join(root, "go", "bin", file.Name())
+		bytes, err := ioutil.ReadFile(binPath)
+		if err != nil {
+			vlog.Errorf("ReadFile(%v) failed: %v", binPath, err)
+			return nil, errInternalError
+		}
+		result := build.File{
+			Name:     "bin/" + file.Name(),
+			Contents: bytes,
+		}
+		if err := stream.Send(result); err != nil {
+			vlog.Errorf("Send() failed: %v", err)
+			return nil, errInternalError
+		}
+	}
+	return output.Bytes(), nil
 }
 
 func (i *invoker) Describe(_ ipc.ServerContext, name string) (binary.Description, error) {
diff --git a/services/mgmt/build/impl/util.go b/services/mgmt/build/impl/util.go
new file mode 100644
index 0000000..2710ae9
--- /dev/null
+++ b/services/mgmt/build/impl/util.go
@@ -0,0 +1,59 @@
+package impl
+
+import (
+	"runtime"
+
+	"veyron2/services/mgmt/build"
+)
+
+func getArch() build.Architecture {
+	switch runtime.GOARCH {
+	case "386":
+		return build.X86
+	case "amd64":
+		return build.AMD64
+	case "arm":
+		return build.ARM
+	default:
+		return build.UnsupportedArchitecture
+	}
+}
+
+func getOS() build.OperatingSystem {
+	switch runtime.GOOS {
+	case "darwin":
+		return build.Darwin
+	case "linux":
+		return build.Linux
+	case "windows":
+		return build.Windows
+	default:
+		return build.UnsupportedOperatingSystem
+	}
+}
+
+func archString(arch build.Architecture) string {
+	switch arch {
+	case build.X86:
+		return "x86"
+	case build.AMD64:
+		return "amd64"
+	case build.ARM:
+		return "arm"
+	default:
+		return "unsupported"
+	}
+}
+
+func osString(os build.OperatingSystem) string {
+	switch os {
+	case build.Darwin:
+		return "darwin"
+	case build.Linux:
+		return "linux"
+	case build.Windows:
+		return "windows"
+	default:
+		return "unsupported"
+	}
+}
diff --git a/services/mgmt/node/impl/invoker.go b/services/mgmt/node/impl/invoker.go
index 565d6d8..ed450c6 100644
--- a/services/mgmt/node/impl/invoker.go
+++ b/services/mgmt/node/impl/invoker.go
@@ -41,8 +41,7 @@
 	"time"
 
 	"veyron/lib/config"
-	"veyron/services/mgmt/build"
-	cbinary "veyron/services/mgmt/lib/binary"
+	blib "veyron/services/mgmt/lib/binary"
 	vexec "veyron/services/mgmt/lib/exec"
 	"veyron/services/mgmt/profile"
 
@@ -52,6 +51,7 @@
 	"veyron2/rt"
 	"veyron2/services/mgmt/application"
 	"veyron2/services/mgmt/binary"
+	"veyron2/services/mgmt/build"
 	"veyron2/services/mgmt/node"
 	"veyron2/services/mgmt/repository"
 	"veyron2/verror"
@@ -119,30 +119,30 @@
 // TODO(jsimsa): Avoid computing the host node description from
 // scratch if a recent cached copy exists.
 func (i *invoker) computeNodeProfile() (*profile.Specification, error) {
-	result := profile.Specification{Format: profile.Format{Attributes: make(map[string]string)}}
+	result := profile.Specification{}
 
 	// Find out what the supported file format, operating system, and
 	// architecture is.
 	switch runtime.GOOS {
-	case "linux":
-		result.Format.Name = build.ELF.String()
-		result.Format.Attributes["os"] = build.LINUX.String()
 	case "darwin":
-		result.Format.Name = build.MACH.String()
-		result.Format.Attributes["os"] = build.DARWIN.String()
+		result.Format = build.MACH
+		result.OS = build.Darwin
+	case "linux":
+		result.Format = build.ELF
+		result.OS = build.Linux
 	case "windows":
-		result.Format.Name = build.PE.String()
-		result.Format.Attributes["os"] = build.WINDOWS.String()
+		result.Format = build.PE
+		result.OS = build.Windows
 	default:
 		return nil, errors.New("Unsupported operating system: " + runtime.GOOS)
 	}
 	switch runtime.GOARCH {
 	case "amd64":
-		result.Format.Attributes["arch"] = build.AMD64.String()
+		result.Arch = build.AMD64
 	case "arm":
-		result.Format.Attributes["arch"] = build.AMD64.String()
+		result.Arch = build.ARM
 	case "x86":
-		result.Format.Attributes["arch"] = build.AMD64.String()
+		result.Arch = build.X86
 	default:
 		return nil, errors.New("Unsupported hardware architecture: " + runtime.GOARCH)
 	}
@@ -269,13 +269,13 @@
 	result := node.Description{Profiles: make(map[string]struct{})}
 loop:
 	for _, profile := range known {
-		if profile.Format.Name != p.Format.Name {
+		if profile.Format != p.Format {
 			continue
 		}
-		if profile.Format.Attributes["os"] != p.Format.Attributes["os"] {
+		if profile.OS != p.OS {
 			continue
 		}
-		if profile.Format.Attributes["arch"] != p.Format.Attributes["arch"] {
+		if profile.Arch != p.Arch {
 			continue
 		}
 		for library := range profile.Libraries {
@@ -331,7 +331,7 @@
 // APPLICATION INTERFACE IMPLEMENTATION
 
 func downloadBinary(workspace, name string) error {
-	data, err := cbinary.Download(name)
+	data, err := blib.Download(name)
 	if err != nil {
 		vlog.Errorf("Download(%v) failed: %v", name, err)
 		return errOperationFailed
diff --git a/services/mgmt/node/node.vdl.go b/services/mgmt/node/node.vdl.go
index 0aff95a..4a922f3 100644
--- a/services/mgmt/node/node.vdl.go
+++ b/services/mgmt/node/node.vdl.go
@@ -14,7 +14,7 @@
 	_gen_ipc "veyron2/ipc"
 	_gen_naming "veyron2/naming"
 	_gen_rt "veyron2/rt"
-	_gen_vdl "veyron2/vdl"
+	_gen_vdlutil "veyron2/vdl/vdlutil"
 	_gen_wiretype "veyron2/wiretype"
 )
 
@@ -55,10 +55,10 @@
 		case _gen_ipc.Client:
 			client = o
 		default:
-			return nil, _gen_vdl.ErrUnrecognizedOption
+			return nil, _gen_vdlutil.ErrUnrecognizedOption
 		}
 	default:
-		return nil, _gen_vdl.ErrTooManyOptionsToBind
+		return nil, _gen_vdlutil.ErrTooManyOptionsToBind
 	}
 	stub := &clientStubConfig{client: client, name: name}
 
@@ -156,7 +156,7 @@
 		},
 	}
 
-	result.TypeDefs = []_gen_vdl.Any{
+	result.TypeDefs = []_gen_vdlutil.Any{
 		_gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}}
 
 	return result, nil
@@ -229,10 +229,10 @@
 		case _gen_ipc.Client:
 			client = o
 		default:
-			return nil, _gen_vdl.ErrUnrecognizedOption
+			return nil, _gen_vdlutil.ErrUnrecognizedOption
 		}
 	default:
-		return nil, _gen_vdl.ErrTooManyOptionsToBind
+		return nil, _gen_vdlutil.ErrTooManyOptionsToBind
 	}
 	stub := &clientStubNode{client: client, name: name}
 	stub.Node_ExcludingUniversal, _ = node.BindNode(name, client)
@@ -321,7 +321,7 @@
 func (__gen_s *ServerStubNode) Signature(call _gen_ipc.ServerCall) (_gen_ipc.ServiceSignature, error) {
 	result := _gen_ipc.ServiceSignature{Methods: make(map[string]_gen_ipc.MethodSignature)}
 
-	result.TypeDefs = []_gen_vdl.Any{}
+	result.TypeDefs = []_gen_vdlutil.Any{}
 	var ss _gen_ipc.ServiceSignature
 	var firstAdded int
 	ss, _ = __gen_s.ServerStubNode.Signature(call)
diff --git a/services/mgmt/profile/impl/impl_test.go b/services/mgmt/profile/impl/impl_test.go
index bb52ef9..ca9ff10 100644
--- a/services/mgmt/profile/impl/impl_test.go
+++ b/services/mgmt/profile/impl/impl_test.go
@@ -10,15 +10,18 @@
 
 	"veyron2/naming"
 	"veyron2/rt"
+	"veyron2/services/mgmt/build"
 )
 
 var (
 	// spec is an example profile specification used throughout the test.
 	spec = profile.Specification{
-		Format:      profile.Format{Name: "elf", Attributes: map[string]string{"os": "linux", "arch": "amd64"}},
+		Arch:        build.AMD64,
+		Description: "Example profile to test the profile repository implementation.",
+		Format:      build.ELF,
 		Libraries:   map[profile.Library]struct{}{profile.Library{Name: "foo", MajorVersion: "1", MinorVersion: "0"}: struct{}{}},
 		Label:       "example",
-		Description: "Example profile to test the profile repository implementation.",
+		OS:          build.Linux,
 	}
 )
 
diff --git a/services/mgmt/profile/profile.vdl b/services/mgmt/profile/profile.vdl
index d37c59b..0f6338b 100644
--- a/services/mgmt/profile/profile.vdl
+++ b/services/mgmt/profile/profile.vdl
@@ -2,16 +2,7 @@
 // types used by the implementation of Veyron profiles.
 package profile
 
-// Format includes a type (e.g. ELF) and each instance of the format
-// has some specific attributes. The key attributes are the target
-// operating system (e.g. for ELF this could be one of System V,
-// HP-UX, NetBSD, Linux, Solaris, AIX, IRIX, FreeBSD, and OpenBSD) and
-// the target instruction set architecture (e.g. for ELF this could be
-// one of SPARC, x86, PowerPC, ARM, IA-64, x86-64, and AArch64).
-type Format struct {
-	Name       string
-	Attributes map[string]string
-}
+import "veyron2/services/mgmt/build"
 
 // Library describes a shared library that applications may use.
 type Library struct {
@@ -26,12 +17,17 @@
 // Specification is how we represent a profile internally. It should
 // provide enough information to allow matching of binaries to nodes.
 type Specification struct {
-	// Format is the file format of the application binary.
-	Format      Format
-	// Libraries is a set of libraries the application binary depends on.
-	Libraries   set[Library]
-	// A human-friendly concise label for the profile, e.g. "linux-media"
-	Label       string
-	// A human-friendly description of the profile.
+	// Arch is the target hardware architecture of the profile.
+	Arch        build.Architecture
+	// Description is a human-friendly description of the profile.
 	Description string
+	// Format is the file format supported by the profile.
+	Format      build.Format
+	// Libraries is a set of libraries the profile requires.
+	Libraries   set[Library]
+	// Label is a human-friendly concise label for the profile,
+	// e.g. "linux-media".
+	Label       string
+	// OS is the target operating system of the profile.
+	OS          build.OperatingSystem
 }
diff --git a/services/mgmt/profile/profile.vdl.go b/services/mgmt/profile/profile.vdl.go
index c219f26..8ece520 100644
--- a/services/mgmt/profile/profile.vdl.go
+++ b/services/mgmt/profile/profile.vdl.go
@@ -5,16 +5,9 @@
 // types used by the implementation of Veyron profiles.
 package profile
 
-// Format includes a type (e.g. ELF) and each instance of the format
-// has some specific attributes. The key attributes are the target
-// operating system (e.g. for ELF this could be one of System V,
-// HP-UX, NetBSD, Linux, Solaris, AIX, IRIX, FreeBSD, and OpenBSD) and
-// the target instruction set architecture (e.g. for ELF this could be
-// one of SPARC, x86, PowerPC, ARM, IA-64, x86-64, and AArch64).
-type Format struct {
-	Name       string
-	Attributes map[string]string
-}
+import (
+	"veyron2/services/mgmt/build"
+)
 
 // Library describes a shared library that applications may use.
 type Library struct {
@@ -29,12 +22,17 @@
 // Specification is how we represent a profile internally. It should
 // provide enough information to allow matching of binaries to nodes.
 type Specification struct {
-	// Format is the file format of the application binary.
-	Format Format
-	// Libraries is a set of libraries the application binary depends on.
-	Libraries map[Library]struct{}
-	// A human-friendly concise label for the profile, e.g. "linux-media"
-	Label string
-	// A human-friendly description of the profile.
+	// Arch is the target hardware architecture of the profile.
+	Arch build.Architecture
+	// Description is a human-friendly description of the profile.
 	Description string
+	// Format is the file format supported by the profile.
+	Format build.Format
+	// Libraries is a set of libraries the profile requires.
+	Libraries map[Library]struct{}
+	// Label is a human-friendly concise label for the profile,
+	// e.g. "linux-media".
+	Label string
+	// OS is the target operating system of the profile.
+	OS build.OperatingSystem
 }
diff --git a/services/mgmt/repository/repository.vdl.go b/services/mgmt/repository/repository.vdl.go
index 683d069..83bc841 100644
--- a/services/mgmt/repository/repository.vdl.go
+++ b/services/mgmt/repository/repository.vdl.go
@@ -20,7 +20,7 @@
 	_gen_ipc "veyron2/ipc"
 	_gen_naming "veyron2/naming"
 	_gen_rt "veyron2/rt"
-	_gen_vdl "veyron2/vdl"
+	_gen_vdlutil "veyron2/vdl/vdlutil"
 	_gen_wiretype "veyron2/wiretype"
 )
 
@@ -105,10 +105,10 @@
 		case _gen_ipc.Client:
 			client = o
 		default:
-			return nil, _gen_vdl.ErrUnrecognizedOption
+			return nil, _gen_vdlutil.ErrUnrecognizedOption
 		}
 	default:
-		return nil, _gen_vdl.ErrTooManyOptionsToBind
+		return nil, _gen_vdlutil.ErrTooManyOptionsToBind
 	}
 	stub := &clientStubApplication{client: client, name: name}
 	stub.Application_ExcludingUniversal, _ = repository.BindApplication(name, client)
@@ -236,9 +236,10 @@
 		},
 	}
 
-	result.TypeDefs = []_gen_vdl.Any{
+	result.TypeDefs = []_gen_vdlutil.Any{
 		_gen_wiretype.StructType{
 			[]_gen_wiretype.FieldType{
+				_gen_wiretype.FieldType{Type: 0x3, Name: "Title"},
 				_gen_wiretype.FieldType{Type: 0x3d, Name: "Args"},
 				_gen_wiretype.FieldType{Type: 0x3, Name: "Binary"},
 				_gen_wiretype.FieldType{Type: 0x3d, Name: "Env"},
@@ -394,10 +395,10 @@
 		case _gen_ipc.Client:
 			client = o
 		default:
-			return nil, _gen_vdl.ErrUnrecognizedOption
+			return nil, _gen_vdlutil.ErrUnrecognizedOption
 		}
 	default:
-		return nil, _gen_vdl.ErrTooManyOptionsToBind
+		return nil, _gen_vdlutil.ErrTooManyOptionsToBind
 	}
 	stub := &clientStubProfile{client: client, name: name}
 	stub.Profile_ExcludingUniversal, _ = repository.BindProfile(name, client)
@@ -522,46 +523,42 @@
 	result := _gen_ipc.ServiceSignature{Methods: make(map[string]_gen_ipc.MethodSignature)}
 	result.Methods["Put"] = _gen_ipc.MethodSignature{
 		InArgs: []_gen_ipc.MethodArgument{
-			{Name: "Specification", Type: 69},
+			{Name: "Specification", Type: 70},
 		},
 		OutArgs: []_gen_ipc.MethodArgument{
-			{Name: "", Type: 70},
+			{Name: "", Type: 71},
 		},
 	}
 	result.Methods["Remove"] = _gen_ipc.MethodSignature{
 		InArgs: []_gen_ipc.MethodArgument{},
 		OutArgs: []_gen_ipc.MethodArgument{
-			{Name: "", Type: 70},
+			{Name: "", Type: 71},
 		},
 	}
 	result.Methods["Specification"] = _gen_ipc.MethodSignature{
 		InArgs: []_gen_ipc.MethodArgument{},
 		OutArgs: []_gen_ipc.MethodArgument{
-			{Name: "", Type: 69},
 			{Name: "", Type: 70},
+			{Name: "", Type: 71},
 		},
 	}
 
-	result.TypeDefs = []_gen_vdl.Any{
-		_gen_wiretype.MapType{Key: 0x3, Elem: 0x3, Name: "", Tags: []string(nil)}, _gen_wiretype.StructType{
-			[]_gen_wiretype.FieldType{
-				_gen_wiretype.FieldType{Type: 0x3, Name: "Name"},
-				_gen_wiretype.FieldType{Type: 0x41, Name: "Attributes"},
-			},
-			"veyron/services/mgmt/profile.Format", []string(nil)},
-		_gen_wiretype.StructType{
+	result.TypeDefs = []_gen_vdlutil.Any{
+		_gen_wiretype.NamedPrimitiveType{Type: 0x32, Name: "veyron2/services/mgmt/build.Architecture", Tags: []string(nil)}, _gen_wiretype.NamedPrimitiveType{Type: 0x32, Name: "veyron2/services/mgmt/build.Format", Tags: []string(nil)}, _gen_wiretype.StructType{
 			[]_gen_wiretype.FieldType{
 				_gen_wiretype.FieldType{Type: 0x3, Name: "Name"},
 				_gen_wiretype.FieldType{Type: 0x3, Name: "MajorVersion"},
 				_gen_wiretype.FieldType{Type: 0x3, Name: "MinorVersion"},
 			},
 			"veyron/services/mgmt/profile.Library", []string(nil)},
-		_gen_wiretype.MapType{Key: 0x43, Elem: 0x2, Name: "", Tags: []string(nil)}, _gen_wiretype.StructType{
+		_gen_wiretype.MapType{Key: 0x43, Elem: 0x2, Name: "", Tags: []string(nil)}, _gen_wiretype.NamedPrimitiveType{Type: 0x32, Name: "veyron2/services/mgmt/build.OperatingSystem", Tags: []string(nil)}, _gen_wiretype.StructType{
 			[]_gen_wiretype.FieldType{
+				_gen_wiretype.FieldType{Type: 0x41, Name: "Arch"},
+				_gen_wiretype.FieldType{Type: 0x3, Name: "Description"},
 				_gen_wiretype.FieldType{Type: 0x42, Name: "Format"},
 				_gen_wiretype.FieldType{Type: 0x44, Name: "Libraries"},
 				_gen_wiretype.FieldType{Type: 0x3, Name: "Label"},
-				_gen_wiretype.FieldType{Type: 0x3, Name: "Description"},
+				_gen_wiretype.FieldType{Type: 0x45, Name: "OS"},
 			},
 			"veyron/services/mgmt/profile.Specification", []string(nil)},
 		_gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}}
diff --git a/services/mgmt/root/root.vdl.go b/services/mgmt/root/root.vdl.go
index 5f62698..90f5103 100644
--- a/services/mgmt/root/root.vdl.go
+++ b/services/mgmt/root/root.vdl.go
@@ -12,7 +12,7 @@
 	_gen_ipc "veyron2/ipc"
 	_gen_naming "veyron2/naming"
 	_gen_rt "veyron2/rt"
-	_gen_vdl "veyron2/vdl"
+	_gen_vdlutil "veyron2/vdl/vdlutil"
 	_gen_wiretype "veyron2/wiretype"
 )
 
@@ -56,10 +56,10 @@
 		case _gen_ipc.Client:
 			client = o
 		default:
-			return nil, _gen_vdl.ErrUnrecognizedOption
+			return nil, _gen_vdlutil.ErrUnrecognizedOption
 		}
 	default:
-		return nil, _gen_vdl.ErrTooManyOptionsToBind
+		return nil, _gen_vdlutil.ErrTooManyOptionsToBind
 	}
 	stub := &clientStubRoot{client: client, name: name}
 
@@ -156,7 +156,7 @@
 		},
 	}
 
-	result.TypeDefs = []_gen_vdl.Any{
+	result.TypeDefs = []_gen_vdlutil.Any{
 		_gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}}
 
 	return result, nil
diff --git a/services/mounttable/lib/collection_test.vdl.go b/services/mounttable/lib/collection_test.vdl.go
index 986224c..75cf8fb 100644
--- a/services/mounttable/lib/collection_test.vdl.go
+++ b/services/mounttable/lib/collection_test.vdl.go
@@ -10,7 +10,7 @@
 	_gen_ipc "veyron2/ipc"
 	_gen_naming "veyron2/naming"
 	_gen_rt "veyron2/rt"
-	_gen_vdl "veyron2/vdl"
+	_gen_vdlutil "veyron2/vdl/vdlutil"
 	_gen_wiretype "veyron2/wiretype"
 )
 
@@ -62,10 +62,10 @@
 		case _gen_ipc.Client:
 			client = o
 		default:
-			return nil, _gen_vdl.ErrUnrecognizedOption
+			return nil, _gen_vdlutil.ErrUnrecognizedOption
 		}
 	default:
-		return nil, _gen_vdl.ErrTooManyOptionsToBind
+		return nil, _gen_vdlutil.ErrTooManyOptionsToBind
 	}
 	stub := &clientStubCollection{client: client, name: name}
 
@@ -183,7 +183,7 @@
 		},
 	}
 
-	result.TypeDefs = []_gen_vdl.Any{
+	result.TypeDefs = []_gen_vdlutil.Any{
 		_gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}, _gen_wiretype.NamedPrimitiveType{Type: 0x32, Name: "byte", Tags: []string(nil)}, _gen_wiretype.SliceType{Elem: 0x42, Name: "", Tags: []string(nil)}}
 
 	return result, nil
diff --git a/services/security/discharger.vdl.go b/services/security/discharger.vdl.go
index 34ab8fc..7a2b5a8 100644
--- a/services/security/discharger.vdl.go
+++ b/services/security/discharger.vdl.go
@@ -12,7 +12,7 @@
 	_gen_ipc "veyron2/ipc"
 	_gen_naming "veyron2/naming"
 	_gen_rt "veyron2/rt"
-	_gen_vdl "veyron2/vdl"
+	_gen_vdlutil "veyron2/vdl/vdlutil"
 	_gen_wiretype "veyron2/wiretype"
 )
 
@@ -28,7 +28,7 @@
 	// respectively. (not enforced here because vdl does not know these types)
 	// TODO(ataly,ashankar): Figure out a VDL representation for ThirdPartyCaveat
 	// and Discharge and use those here?
-	Discharge(ctx _gen_context.T, Caveat _gen_vdl.Any, opts ..._gen_ipc.CallOpt) (reply _gen_vdl.Any, err error)
+	Discharge(ctx _gen_context.T, Caveat _gen_vdlutil.Any, opts ..._gen_ipc.CallOpt) (reply _gen_vdlutil.Any, err error)
 }
 type Discharger interface {
 	_gen_ipc.UniversalServiceMethods
@@ -45,7 +45,7 @@
 	// respectively. (not enforced here because vdl does not know these types)
 	// TODO(ataly,ashankar): Figure out a VDL representation for ThirdPartyCaveat
 	// and Discharge and use those here?
-	Discharge(context _gen_ipc.ServerContext, Caveat _gen_vdl.Any) (reply _gen_vdl.Any, err error)
+	Discharge(context _gen_ipc.ServerContext, Caveat _gen_vdlutil.Any) (reply _gen_vdlutil.Any, err error)
 }
 
 // BindDischarger returns the client stub implementing the Discharger
@@ -65,10 +65,10 @@
 		case _gen_ipc.Client:
 			client = o
 		default:
-			return nil, _gen_vdl.ErrUnrecognizedOption
+			return nil, _gen_vdlutil.ErrUnrecognizedOption
 		}
 	default:
-		return nil, _gen_vdl.ErrTooManyOptionsToBind
+		return nil, _gen_vdlutil.ErrTooManyOptionsToBind
 	}
 	stub := &clientStubDischarger{client: client, name: name}
 
@@ -91,7 +91,7 @@
 	name   string
 }
 
-func (__gen_c *clientStubDischarger) Discharge(ctx _gen_context.T, Caveat _gen_vdl.Any, opts ..._gen_ipc.CallOpt) (reply _gen_vdl.Any, err error) {
+func (__gen_c *clientStubDischarger) Discharge(ctx _gen_context.T, Caveat _gen_vdlutil.Any, opts ..._gen_ipc.CallOpt) (reply _gen_vdlutil.Any, err error) {
 	var call _gen_ipc.Call
 	if call, err = __gen_c.client.StartCall(ctx, __gen_c.name, "Discharge", []interface{}{Caveat}, opts...); err != nil {
 		return
@@ -166,7 +166,7 @@
 		},
 	}
 
-	result.TypeDefs = []_gen_vdl.Any{
+	result.TypeDefs = []_gen_vdlutil.Any{
 		_gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "anydata", Tags: []string(nil)}, _gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}}
 
 	return result, nil
@@ -190,7 +190,7 @@
 	return
 }
 
-func (__gen_s *ServerStubDischarger) Discharge(call _gen_ipc.ServerCall, Caveat _gen_vdl.Any) (reply _gen_vdl.Any, err error) {
+func (__gen_s *ServerStubDischarger) Discharge(call _gen_ipc.ServerCall, Caveat _gen_vdlutil.Any) (reply _gen_vdlutil.Any, err error) {
 	reply, err = __gen_s.service.Discharge(call, Caveat)
 	return
 }
diff --git a/services/security/discharger/discharger.go b/services/security/discharger/discharger.go
new file mode 100644
index 0000000..9bcb9ae
--- /dev/null
+++ b/services/security/discharger/discharger.go
@@ -0,0 +1,31 @@
+package discharger
+
+import (
+	"fmt"
+	"time"
+	ssecurity "veyron/services/security"
+	"veyron2/ipc"
+	"veyron2/security"
+	"veyron2/vdl/vdlutil"
+)
+
+// dischargerd issues discharges for all caveats present in the current
+// namespace with no additional caveats iff the caveat is valid.
+type dischargerd struct {
+	id security.PrivateID
+}
+
+// TODO(andreser,ataly): make it easier for third party public key caveats to specify the caveats on their discharges
+
+func (d dischargerd) Discharge(ctx ipc.ServerContext, caveatAny vdlutil.Any) (vdlutil.Any, error) {
+	caveat, ok := caveatAny.(security.ThirdPartyCaveat)
+	if !ok {
+		return nil, fmt.Errorf("type %T does not implement security.ThirdPartyCaveat", caveatAny)
+	}
+	return d.id.MintDischarge(caveat, ctx, time.Minute, nil)
+}
+
+// New returns a Discharger server that can be passed to a dispatcher
+func New(id security.PrivateID) interface{} {
+	return ssecurity.NewServerDischarger(&dischargerd{id})
+}
diff --git a/services/security/discharger/revoker.go b/services/security/discharger/revoker.go
new file mode 100644
index 0000000..4f32574
--- /dev/null
+++ b/services/security/discharger/revoker.go
@@ -0,0 +1,123 @@
+package discharger
+
+import (
+	"crypto/rand"
+	"crypto/sha256"
+	"encoding/hex"
+	"fmt"
+	"path/filepath"
+	"strings"
+	"sync"
+	"veyron/security/caveat"
+	ssecurity "veyron/services/security"
+	"veyron2/ipc"
+	"veyron2/naming"
+	"veyron2/rt"
+	"veyron2/security"
+	"veyron2/storage"
+	"veyron2/storage/vstore"
+	"veyron2/storage/vstore/primitives"
+	"veyron2/vlog"
+	"veyron2/vom"
+)
+
+// TODO(ataly, andreser) This package uses a global variable to store the
+// revoker state to make it accessible to caveat.Validate. Ideally, we would
+// pass this in through the context (or something equivalent).
+
+type revocationServiceT struct {
+	store       storage.Store
+	pathInStore string
+}
+
+var revocationService struct {
+	*revocationServiceT
+	sync.Mutex
+}
+
+type revocationCaveat [32]byte
+
+func (cav revocationCaveat) Validate(security.Context) error {
+	// TODO(ashankar,mattr): Figure out how to get the context of an existing RPC here
+	rctx := rt.R().NewContext()
+	revocation := revocationService.store.Bind(naming.Join(revocationService.pathInStore,
+		hex.EncodeToString(cav[:])))
+	tx := primitives.NewTransaction(rctx)
+	defer tx.Abort(rctx)
+	exists, err := revocation.Exists(rctx, tx)
+	if err != nil {
+		return err
+	}
+	if exists {
+		return fmt.Errorf("revoked")
+	}
+	return nil
+}
+
+// NewRevocationCaveat returns a security.ThirdPartyCaveat that discharger will
+// mint discharges until explicitly told not to by calling Revoke on it
+// (using the returned revocation token)
+func NewRevocationCaveat(dischargerID security.PublicID, dischargerLocation string) (ssecurity.RevocationToken, security.ThirdPartyCaveat, error) {
+	var revocation ssecurity.RevocationToken
+	if _, err := rand.Read(revocation[:]); err != nil {
+		return revocation, nil, err
+	}
+	restriction := revocationCaveat(sha256.Sum256(revocation[:]))
+	cav, err := caveat.NewPublicKeyCaveat(restriction, dischargerID, dischargerLocation)
+	return revocation, cav, err
+}
+
+func (revoceationService *revocationServiceT) Revoke(ctx ipc.ServerContext, caveatPreimage ssecurity.RevocationToken) error {
+	caveatNonce := sha256.Sum256(caveatPreimage[:])
+	tx := primitives.NewTransaction(ctx)
+	revocation := revocationService.store.Bind(naming.Join(revocationService.pathInStore, hex.EncodeToString(caveatNonce[:])))
+	if _, err := revocation.Put(ctx, tx, caveatPreimage[:]); err != nil {
+		tx.Abort(ctx)
+		return err
+	}
+	return tx.Commit(ctx)
+}
+
+// NewRevoker returns a new revoker service that can be passed to a dispatcher.
+// Currently, due to the use of global variables, this function can be called only once.
+func NewRevoker(storeName, pathInStore string) (interface{}, error) {
+	revocationService.Lock()
+	defer revocationService.Unlock()
+	if revocationService.revocationServiceT != nil {
+		return nil, fmt.Errorf("revoker.Revoker called more than once")
+	}
+	var err error
+	revocationService.revocationServiceT = new(revocationServiceT)
+	revocationService.store, err = vstore.New(storeName)
+	if err != nil {
+		return nil, err
+	}
+
+	rctx := rt.R().NewContext()
+	tx := primitives.NewTransaction(rctx)
+
+	// Create parent directories for the revoker root, if necessary
+	// TODO(tilaks,andreser): provide a `mkdir -p` equivalent in store
+	l := strings.Split(pathInStore, "/")
+	fmt.Println(l)
+	for i := 0; i <= len(l); i++ {
+		fmt.Println(i, filepath.Join(l[:i]...))
+		prefix := filepath.Join(l[:i]...)
+		o := revocationService.store.Bind(prefix)
+		if exist, err := o.Exists(rctx, tx); err != nil {
+			vlog.Infof("Error checking existence at %q: %s", prefix, err)
+		} else if !exist {
+			if _, err := o.Put(rctx, tx, &Dir{}); err != nil {
+				vlog.Infof("Error creating directory %q: %s", prefix, err)
+			}
+		}
+	}
+	if err := tx.Commit(rctx); err != nil {
+		vlog.Fatalf("Commit creation of revocer root et %s: %s", pathInStore, err)
+	}
+	return ssecurity.NewServerRevoker(revocationService.revocationServiceT), nil
+}
+
+func init() {
+	vom.Register(revocationCaveat{})
+}
diff --git a/services/security/discharger/revoker_test.go b/services/security/discharger/revoker_test.go
new file mode 100644
index 0000000..acb89e9
--- /dev/null
+++ b/services/security/discharger/revoker_test.go
@@ -0,0 +1,97 @@
+package discharger
+
+import (
+	"testing"
+	ssecurity "veyron/services/security"
+	teststore "veyron/services/store/testutil"
+	"veyron2/ipc"
+	"veyron2/naming"
+	"veyron2/rt"
+	"veyron2/security"
+)
+
+func init() {
+	rt.Init()
+}
+
+func setup(t *testing.T) (dischargerID security.PublicID, dischargerEndpoint, revokerEndpoint string, closeFunc func()) {
+	// Create and start the store instance that the revoker will use
+	storeServer, err := rt.R().NewServer()
+	if err != nil {
+		t.Fatalf("rt.R().NewServer: %s", err)
+	}
+	storeVeyronName, closeStore := teststore.NewStore(t, storeServer, rt.R().Identity().PublicID())
+
+	// Create and start revoker and revocation discharge service
+	revokerServer, err := rt.R().NewServer()
+	if err != nil {
+		t.Fatalf("rt.R().NewServer: %s", err)
+	}
+	revokerEP, err := revokerServer.Listen("tcp", "127.0.0.1:0")
+	if err != nil {
+		t.Fatalf("revokerServer.Listen failed: %v", err)
+	}
+	revokerService, err := NewRevoker(storeVeyronName, "/testrevoker")
+	if err != nil {
+		t.Fatalf("setup revoker service: %s", err)
+	}
+	err = revokerServer.Serve("", ipc.SoloDispatcher(revokerService, nil))
+	if err != nil {
+		t.Fatalf("revokerServer.Serve discharger: %s", err)
+	}
+
+	dischargerServer, err := rt.R().NewServer()
+	if err != nil {
+		t.Fatalf("rt.R().NewServer: %s", err)
+	}
+	dischargerEP, err := dischargerServer.Listen("tcp", "127.0.0.1:0")
+	if err != nil {
+		t.Fatalf("revokerServer.Listen failed: %v", err)
+	}
+	err = dischargerServer.Serve("", ipc.SoloDispatcher(New(rt.R().Identity()), nil))
+	if err != nil {
+		t.Fatalf("revokerServer.Serve revoker: %s", err)
+	}
+	return rt.R().Identity().PublicID(),
+		naming.JoinAddressName(dischargerEP.String(), ""),
+		naming.JoinAddressName(revokerEP.String(), ""),
+		func() {
+			revokerServer.Stop()
+			dischargerServer.Stop()
+			closeStore()
+		}
+}
+
+func TestDischargeRevokeDischargeRevokeDischarge(t *testing.T) {
+	dcID, dc, rv, closeFunc := setup(t)
+	defer closeFunc()
+	revoker, err := ssecurity.BindRevoker(rv)
+	if err != nil {
+		t.Fatalf("error binding to server: ", err)
+	}
+	discharger, err := ssecurity.BindDischarger(dc)
+	if err != nil {
+		t.Fatalf("error binding to server: ", err)
+	}
+
+	preimage, cav, err := NewRevocationCaveat(dcID, dc)
+	if err != nil {
+		t.Fatalf("failed to create public key caveat: %s", err)
+	}
+
+	if _, err = discharger.Discharge(rt.R().NewContext(), cav); err != nil {
+		t.Fatalf("failed to get discharge: %s", err)
+	}
+	if err = revoker.Revoke(rt.R().NewContext(), preimage); err != nil {
+		t.Fatalf("failed to revoke: %s", err)
+	}
+	if discharge, err := discharger.Discharge(rt.R().NewContext(), cav); err == nil || discharge != nil {
+		t.Fatalf("got a discharge for a revoked caveat: %s", err)
+	}
+	if err = revoker.Revoke(rt.R().NewContext(), preimage); err != nil {
+		t.Fatalf("failed to revoke again: %s", err)
+	}
+	if discharge, err := discharger.Discharge(rt.R().NewContext(), cav); err == nil || discharge != nil {
+		t.Fatalf("got a discharge for a doubly revoked caveat: %s", err)
+	}
+}
diff --git a/services/security/discharger/schema.vdl b/services/security/discharger/schema.vdl
new file mode 100644
index 0000000..d92d035
--- /dev/null
+++ b/services/security/discharger/schema.vdl
@@ -0,0 +1,3 @@
+package discharger
+
+type Dir struct {} // TODO(tilaks, andreser): move this to store?
diff --git a/services/security/discharger/schema.vdl.go b/services/security/discharger/schema.vdl.go
new file mode 100644
index 0000000..462d255
--- /dev/null
+++ b/services/security/discharger/schema.vdl.go
@@ -0,0 +1,7 @@
+// This file was auto-generated by the veyron vdl tool.
+// Source: schema.vdl
+
+package discharger
+
+type Dir struct {
+} // TODO(tilaks, andreser): move this to store?
diff --git a/services/security/dischargerd/main.go b/services/security/dischargerd/main.go
new file mode 100644
index 0000000..cde9103
--- /dev/null
+++ b/services/security/dischargerd/main.go
@@ -0,0 +1,73 @@
+package main
+
+import (
+	"flag"
+
+	"veyron/lib/signals"
+	"veyron/services/security/discharger"
+	"veyron2/ipc"
+	"veyron2/rt"
+	"veyron2/security"
+	"veyron2/vlog"
+)
+
+var (
+	protocol = flag.String("protocol", "tcp", "protocol to listen on")
+	address  = flag.String("address", ":0", "address to listen on")
+	aclFile  = flag.String("discharger-acl", "", "ACL to use for the discharge service")
+	publish  = flag.String("publish", "discharger", "the Object Name under which to publish this service")
+
+	storeName      = flag.String("revocation-store", "", "Object Name of the Veyron store to be used for revocation. Omit to disable revocation functionality.")
+	publishRevoker = flag.String("publish-revoker", "revoker", "the Object Name under which to publish this service")
+	pathInStore    = flag.String("path-in-store", "/revoker", "the location in store where the revoker keeps its state")
+	revokerAclFile = flag.String("revoker-acl", "", "ACL to use for the revocation service")
+)
+
+func authorizer(file string) security.Authorizer {
+	if file == "" {
+		return security.NewACLAuthorizer(security.ACL{security.AllPrincipals: security.AllLabels})
+	}
+	return security.NewFileACLAuthorizer(file)
+}
+
+func main() {
+	r := rt.Init()
+	defer r.Cleanup()
+
+	dischargerServer, err := r.NewServer()
+	if err != nil {
+		vlog.Fatal(err)
+	}
+	defer dischargerServer.Stop()
+	dischargerEndpoint, err := dischargerServer.Listen(*protocol, *address)
+	if err != nil {
+		vlog.Fatal(err)
+	}
+	if err = dischargerServer.Serve(*publish, ipc.SoloDispatcher(discharger.New(r.Identity()), authorizer(*aclFile))); err != nil {
+		vlog.Fatal(err)
+	}
+	vlog.Infof("discharger: %s", dischargerEndpoint.String())
+
+	if *storeName != "" {
+		revokerServer, err := r.NewServer()
+		if err != nil {
+			vlog.Fatal(err)
+		}
+		defer revokerServer.Stop()
+		revokerEndpoint, err := revokerServer.Listen(*protocol, *address)
+		if err != nil {
+			vlog.Fatal(err)
+		}
+		revokerService, err := discharger.NewRevoker(*storeName, *pathInStore)
+		if err != nil {
+			vlog.Fatal(err)
+		}
+		err = revokerServer.Serve(*publish, ipc.SoloDispatcher(revokerService, authorizer(*revokerAclFile)))
+		if err != nil {
+			vlog.Fatal(err)
+		}
+		vlog.Infof("revoker: %s", revokerEndpoint.String())
+	}
+
+	<-signals.ShutdownOnSignals()
+}
diff --git a/services/security/revoker.vdl b/services/security/revoker.vdl
new file mode 100644
index 0000000..da13597
--- /dev/null
+++ b/services/security/revoker.vdl
@@ -0,0 +1,27 @@
+package security
+
+import "veyron2/security"
+
+// RevocationToken can be presented to a revocation service to revoke a caveat
+type RevocationToken [16]byte
+
+// Revoker is the interface for preventing discharges from being issued. The
+// dicharger ensures that no discharges will be issued for caveats that
+// have been explicitly revoked using this interface. To prevent discharge
+// stealing caveats just have to be unique; the exact structure is not relevant
+// to the client or the verifier. To make Revoker's job easy, each caveat
+// contains a SHA256 hash of its revocation token. To revoke a caveat C and
+// have it added to the discharger's blacklist, one simply needs to call
+// Revoke(x) with an x s.t.  SHA256(x) = C. All caveats for which this has not
+// been revoked will get discharges, irrespective of who created them. This
+// means that the existence of a valid discharge does not imply that a
+// corresponding caveat exists, and even if it does, it may not be meant for
+// use with this revocation service. Just looking at discharges is meaningless,
+// a valid (Caveat, Discharge) pair is what can be relied on for
+// authentication. Not keeping track of non-revoked caveats enables
+// performance improvements on the Discharger side.
+type Revoker interface {
+	// Revoke ensures that iff a nil is returned, all discharge requests to the
+	// caveat with nonce sha256(caveatPreimage) are going to be denied.
+	Revoke(caveatPreimage RevocationToken) error {security.WriteLabel}
+}
diff --git a/services/security/revoker.vdl.go b/services/security/revoker.vdl.go
new file mode 100644
index 0000000..811fbe2
--- /dev/null
+++ b/services/security/revoker.vdl.go
@@ -0,0 +1,202 @@
+// This file was auto-generated by the veyron vdl tool.
+// Source: revoker.vdl
+
+package security
+
+import (
+	"veyron2/security"
+
+	// The non-user imports are prefixed with "_gen_" to prevent collisions.
+	_gen_veyron2 "veyron2"
+	_gen_context "veyron2/context"
+	_gen_ipc "veyron2/ipc"
+	_gen_naming "veyron2/naming"
+	_gen_rt "veyron2/rt"
+	_gen_vdlutil "veyron2/vdl/vdlutil"
+	_gen_wiretype "veyron2/wiretype"
+)
+
+// RevocationToken can be presented to a revocation service to revoke a caveat
+type RevocationToken [16]byte
+
+// Revoker is the interface for preventing discharges from being issued. The
+// dicharger ensures ensures that no discharges will be issued for caveats that
+// have been explicitly revoked using this interface. To prevent discharge
+// stealing caveats just have to be unique; the exact structure is not relevant
+// to the client or the verifier. To make Revoker's job easy, each caveat
+// contains a SHA256 hash of its revocation token. To revoke a caveat C and
+// have it added to the discharger's blacklist, one simply needs to call
+// Revoke(x) with an x s.t.  SHA256(x) = C. All caveats for which this has not
+// been revoked will get discharges, irrespective of who created them. This
+// means that the existence of a valid discharge does not imply that a
+// corresponding caveat exists, and even if it does, it may not be meant for
+// use with this revocation service. Just looking at discharges is meaningless,
+// a valid (Caveat, Discharge) pair is what can be relied on for
+// authentication. Not keeping track of non-revoked caveats enables
+// performance improvements on the Discharger side.
+// Revoker is the interface the client binds and uses.
+// Revoker_ExcludingUniversal is the interface without internal framework-added methods
+// to enable embedding without method collisions.  Not to be used directly by clients.
+type Revoker_ExcludingUniversal interface {
+	// Revoke ensures that iff a nil is returned, all discharge requests to the
+	// caveat with nonce sha256(caveatPreimage) are going to be denied.
+	Revoke(ctx _gen_context.T, caveatPreimage RevocationToken, opts ..._gen_ipc.CallOpt) (err error)
+}
+type Revoker interface {
+	_gen_ipc.UniversalServiceMethods
+	Revoker_ExcludingUniversal
+}
+
+// RevokerService is the interface the server implements.
+type RevokerService interface {
+
+	// Revoke ensures that iff a nil is returned, all discharge requests to the
+	// caveat with nonce sha256(caveatPreimage) are going to be denied.
+	Revoke(context _gen_ipc.ServerContext, caveatPreimage RevocationToken) (err error)
+}
+
+// BindRevoker returns the client stub implementing the Revoker
+// interface.
+//
+// If no _gen_ipc.Client is specified, the default _gen_ipc.Client in the
+// global Runtime is used.
+func BindRevoker(name string, opts ..._gen_ipc.BindOpt) (Revoker, error) {
+	var client _gen_ipc.Client
+	switch len(opts) {
+	case 0:
+		client = _gen_rt.R().Client()
+	case 1:
+		switch o := opts[0].(type) {
+		case _gen_veyron2.Runtime:
+			client = o.Client()
+		case _gen_ipc.Client:
+			client = o
+		default:
+			return nil, _gen_vdlutil.ErrUnrecognizedOption
+		}
+	default:
+		return nil, _gen_vdlutil.ErrTooManyOptionsToBind
+	}
+	stub := &clientStubRevoker{client: client, name: name}
+
+	return stub, nil
+}
+
+// NewServerRevoker creates a new server stub.
+//
+// It takes a regular server implementing the RevokerService
+// interface, and returns a new server stub.
+func NewServerRevoker(server RevokerService) interface{} {
+	return &ServerStubRevoker{
+		service: server,
+	}
+}
+
+// clientStubRevoker implements Revoker.
+type clientStubRevoker struct {
+	client _gen_ipc.Client
+	name   string
+}
+
+func (__gen_c *clientStubRevoker) Revoke(ctx _gen_context.T, caveatPreimage RevocationToken, opts ..._gen_ipc.CallOpt) (err error) {
+	var call _gen_ipc.Call
+	if call, err = __gen_c.client.StartCall(ctx, __gen_c.name, "Revoke", []interface{}{caveatPreimage}, opts...); err != nil {
+		return
+	}
+	if ierr := call.Finish(&err); ierr != nil {
+		err = ierr
+	}
+	return
+}
+
+func (__gen_c *clientStubRevoker) UnresolveStep(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply []string, err error) {
+	var call _gen_ipc.Call
+	if call, err = __gen_c.client.StartCall(ctx, __gen_c.name, "UnresolveStep", nil, opts...); err != nil {
+		return
+	}
+	if ierr := call.Finish(&reply, &err); ierr != nil {
+		err = ierr
+	}
+	return
+}
+
+func (__gen_c *clientStubRevoker) Signature(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply _gen_ipc.ServiceSignature, err error) {
+	var call _gen_ipc.Call
+	if call, err = __gen_c.client.StartCall(ctx, __gen_c.name, "Signature", nil, opts...); err != nil {
+		return
+	}
+	if ierr := call.Finish(&reply, &err); ierr != nil {
+		err = ierr
+	}
+	return
+}
+
+func (__gen_c *clientStubRevoker) GetMethodTags(ctx _gen_context.T, method string, opts ..._gen_ipc.CallOpt) (reply []interface{}, err error) {
+	var call _gen_ipc.Call
+	if call, err = __gen_c.client.StartCall(ctx, __gen_c.name, "GetMethodTags", []interface{}{method}, opts...); err != nil {
+		return
+	}
+	if ierr := call.Finish(&reply, &err); ierr != nil {
+		err = ierr
+	}
+	return
+}
+
+// ServerStubRevoker wraps a server that implements
+// RevokerService and provides an object that satisfies
+// the requirements of veyron2/ipc.ReflectInvoker.
+type ServerStubRevoker struct {
+	service RevokerService
+}
+
+func (__gen_s *ServerStubRevoker) GetMethodTags(call _gen_ipc.ServerCall, method string) ([]interface{}, error) {
+	// TODO(bprosnitz) GetMethodTags() will be replaces with Signature().
+	// Note: This exhibits some weird behavior like returning a nil error if the method isn't found.
+	// This will change when it is replaced with Signature().
+	switch method {
+	case "Revoke":
+		return []interface{}{security.Label(2)}, nil
+	default:
+		return nil, nil
+	}
+}
+
+func (__gen_s *ServerStubRevoker) Signature(call _gen_ipc.ServerCall) (_gen_ipc.ServiceSignature, error) {
+	result := _gen_ipc.ServiceSignature{Methods: make(map[string]_gen_ipc.MethodSignature)}
+	result.Methods["Revoke"] = _gen_ipc.MethodSignature{
+		InArgs: []_gen_ipc.MethodArgument{
+			{Name: "caveatPreimage", Type: 66},
+		},
+		OutArgs: []_gen_ipc.MethodArgument{
+			{Name: "", Type: 67},
+		},
+	}
+
+	result.TypeDefs = []_gen_vdlutil.Any{
+		_gen_wiretype.NamedPrimitiveType{Type: 0x32, Name: "byte", Tags: []string(nil)}, _gen_wiretype.ArrayType{Elem: 0x41, Len: 0x10, Name: "veyron/services/security.RevocationToken", Tags: []string(nil)}, _gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}}
+
+	return result, nil
+}
+
+func (__gen_s *ServerStubRevoker) UnresolveStep(call _gen_ipc.ServerCall) (reply []string, err error) {
+	if unresolver, ok := __gen_s.service.(_gen_ipc.Unresolver); ok {
+		return unresolver.UnresolveStep(call)
+	}
+	if call.Server() == nil {
+		return
+	}
+	var published []string
+	if published, err = call.Server().Published(); err != nil || published == nil {
+		return
+	}
+	reply = make([]string, len(published))
+	for i, p := range published {
+		reply[i] = _gen_naming.Join(p, call.Name())
+	}
+	return
+}
+
+func (__gen_s *ServerStubRevoker) Revoke(call _gen_ipc.ServerCall, caveatPreimage RevocationToken) (err error) {
+	err = __gen_s.service.Revoke(call, caveatPreimage)
+	return
+}
diff --git a/services/security/simpledischarged/main.go b/services/security/simpledischarged/main.go
deleted file mode 100644
index bb1db9f..0000000
--- a/services/security/simpledischarged/main.go
+++ /dev/null
@@ -1,78 +0,0 @@
-package main
-
-import (
-	"errors"
-	"flag"
-	"fmt"
-	"log"
-	"time"
-
-	"veyron/lib/signals"
-	isecurity "veyron/services/security"
-	"veyron2/ipc"
-	"veyron2/rt"
-	"veyron2/security"
-	"veyron2/vdl"
-)
-
-// TODO(ataly, andreser): ideally, the expiration time (and other caveats) of
-// the discharge would be determined by a function much like ThirdPartyCaveat.Validate
-var expiration = flag.String("expiration", "10s", "time interval after which a discharge will expire")
-var protocol = flag.String("protocol", "bluetooth", "protocol to listen on")
-var address = flag.String("address", "", "address to listen on")
-var port = flag.Int("port", 0, "port to listen on")
-var publish = flag.String("publish", "", "the namespace where to publish this service")
-
-type dischargeAuthorizer struct{}
-
-func (dischargeAuthorizer) Authorize(c security.Context) error {
-	if c.Method() == "Discharge" {
-		return nil
-	}
-	return fmt.Errorf("Only authorized for method \"Discharge\"")
-}
-
-// discharged implements ipc.Dispatcher. It issues discharges for all caveats
-// present in the current namespace with no additional caveats iff the caveat
-// is valid.
-type discharged struct {
-	id         security.PrivateID
-	expiration time.Duration
-}
-
-func (d *discharged) Discharge(ctx ipc.ServerContext, Caveat vdl.Any) (
-	Discharge vdl.Any, err error) {
-	caveat, ok := Caveat.(security.ThirdPartyCaveat)
-	if !ok {
-		err = errors.New("unknown caveat")
-		return
-	}
-	return d.id.MintDischarge(caveat, ctx, d.expiration, nil)
-}
-
-func main() {
-	flag.Parse()
-	expiration, err := time.ParseDuration(*expiration)
-	if err != nil {
-		log.Fatalf("--expiration: ", err)
-	}
-
-	r := rt.Init()
-	server, err := r.NewServer()
-	if err != nil {
-		log.Fatal(err)
-	}
-
-	discharger := isecurity.NewServerDischarger(&discharged{
-		id: r.Identity(), expiration: expiration})
-	dispatcher := ipc.SoloDispatcher(discharger, dischargeAuthorizer{})
-	endpoint, err := server.Listen(*protocol, *address+":"+fmt.Sprint(*port))
-	if err != nil {
-		log.Fatal(err)
-	}
-	if err := server.Serve(*publish, dispatcher); err != nil {
-		log.Fatal(err)
-	}
-	fmt.Println(endpoint)
-	<-signals.ShutdownOnSignals()
-}
diff --git a/services/store/memstore/blackbox/sync_integration_test.go b/services/store/memstore/blackbox/sync_integration_test.go
index 8e326ce..87de9a6 100644
--- a/services/store/memstore/blackbox/sync_integration_test.go
+++ b/services/store/memstore/blackbox/sync_integration_test.go
@@ -4,7 +4,7 @@
 	"testing"
 
 	"veyron/services/store/memstore"
-	watchtesting "veyron/services/store/memstore/watch/testing"
+	watchtesting "veyron/services/store/memstore/testing"
 	"veyron/services/store/raw"
 )
 
diff --git a/services/store/memstore/blackbox/team_player_test.go b/services/store/memstore/blackbox/team_player_test.go
index fc9c3d0..61a1255 100644
--- a/services/store/memstore/blackbox/team_player_test.go
+++ b/services/store/memstore/blackbox/team_player_test.go
@@ -122,7 +122,9 @@
 	// Iterate over the rockets.
 	players := make(map[storage.ID]*Player)
 	name := storage.ParsePath("/teamsapp/players")
-	for it := st.Snapshot().NewIterator(rootPublicID, name, nil); it.IsValid(); it.Next() {
+	for it := st.Snapshot().NewIterator(rootPublicID, name,
+		state.ListPaths, nil); it.IsValid(); it.Next() {
+
 		e := it.Get()
 		if p, ok := e.Value.(*Player); ok {
 			if _, ok := players[e.Stat.ID]; ok {
@@ -148,7 +150,9 @@
 	// Iterate over all teams, nonrecursively.
 	teams := make(map[storage.ID]*Team)
 	name = storage.ParsePath("/teamsapp/teams")
-	for it := st.Snapshot().NewIterator(rootPublicID, name, state.ImmediateFilter); it.IsValid(); it.Next() {
+	for it := st.Snapshot().NewIterator(rootPublicID, name,
+		state.ListPaths, state.ImmediateFilter); it.IsValid(); it.Next() {
+
 		e := it.Get()
 		v := e.Value
 		if _, ok := v.(*Player); ok {
@@ -173,17 +177,19 @@
 	}
 
 	// Iterate over all teams, recursively.
-	playerCount := 0
+	contractCount := 0
 	teamCount := 0
 	players = make(map[storage.ID]*Player)
 	teams = make(map[storage.ID]*Team)
 	name = storage.ParsePath("/teamsapp/teams")
-	for it := st.Snapshot().NewIterator(rootPublicID, name, nil); it.IsValid(); it.Next() {
+	for it := st.Snapshot().NewIterator(rootPublicID, name,
+		state.ListPaths, nil); it.IsValid(); it.Next() {
+
 		e := it.Get()
 		v := e.Value
 		if p, ok := v.(*Player); ok {
 			players[e.Stat.ID] = p
-			playerCount++
+			contractCount++
 		}
 		if team, ok := v.(*Team); ok {
 			teams[e.Stat.ID] = team
@@ -202,8 +208,8 @@
 	if team, ok := teams[hornetsID]; !ok || team.FullName != "Hornets" {
 		t.Errorf("Should have Hornets, have %v", team)
 	}
-	if playerCount != 3 {
-		t.Errorf("Should have 3 players: have %d", playerCount)
+	if contractCount != 4 {
+		t.Errorf("Should have 4 contracts: have %d", contractCount)
 	}
 	if len(players) != 3 {
 		t.Errorf("Should have 3 players: have %v", players)
diff --git a/services/store/memstore/log.go b/services/store/memstore/log.go
index 0aaf460..3b69326 100644
--- a/services/store/memstore/log.go
+++ b/services/store/memstore/log.go
@@ -12,7 +12,6 @@
 // There are separate interfaces for reading writing; *wlog is used for writing,
 // and *rlog is used for reading.
 import (
-	"errors"
 	"io"
 	"os"
 	"path"
@@ -23,6 +22,7 @@
 	"veyron/services/store/memstore/state"
 
 	"veyron2/security"
+	"veyron2/verror"
 	"veyron2/vom"
 )
 
@@ -34,7 +34,7 @@
 )
 
 var (
-	errLogIsClosed = errors.New("log is closed")
+	errLogIsClosed = verror.Abortedf("log is closed")
 )
 
 // wlog is the type of log writers.
diff --git a/services/store/memstore/pathregex/parser.go b/services/store/memstore/pathregex/parser.go
index ae45194..101cce1 100644
--- a/services/store/memstore/pathregex/parser.go
+++ b/services/store/memstore/pathregex/parser.go
@@ -2,10 +2,11 @@
 
 import (
 	"bytes"
-	"fmt"
 	"io"
 	"regexp"
 	"strings"
+
+	"veyron2/verror"
 )
 
 // parser is a recursive-descent parser for path regular expressions.
@@ -47,7 +48,7 @@
 	re := p.parsePath()
 	if p.isErrored || p.reader.Len() != 0 {
 		pos, _ := p.reader.Seek(0, 1)
-		err := fmt.Errorf("Syntax error at char %d: %q", pos, s)
+		err := verror.BadArgf("Syntax error at char %d: %q", pos, s)
 		return nil, err
 	}
 	return re, nil
diff --git a/services/store/memstore/query/eval.go b/services/store/memstore/query/eval.go
index 10a490d..48e991a 100644
--- a/services/store/memstore/query/eval.go
+++ b/services/store/memstore/query/eval.go
@@ -20,7 +20,7 @@
 	"veyron2/security"
 	"veyron2/services/store"
 	"veyron2/storage"
-	"veyron2/vdl"
+	"veyron2/vdl/vdlutil"
 )
 
 // maxChannelSize is the maximum size of the channels used for concurrent
@@ -357,7 +357,9 @@
 		path := storage.ParsePath(naming.Join(c.suffix, basepath))
 		vlog.VI(2).Infof("nameEvaluator suffix: %s, result.Name: %s, VName: %s",
 			c.suffix, result.Name, e.wildcardName.VName)
-		for it := c.sn.NewIterator(c.clientID, path, state.ImmediateFilter); it.IsValid(); it.Next() {
+		for it := c.sn.NewIterator(c.clientID, path,
+			state.ListObjects, state.ImmediateFilter); it.IsValid(); it.Next() {
+
 			entry := it.Get()
 			result := &store.QueryResult{
 				Name:  naming.Join(basepath, it.Name()),
@@ -533,7 +535,7 @@
 	vlog.VI(2).Info("selection: ", result.Name)
 	sel := &store.QueryResult{
 		Name:   result.Name,
-		Fields: make(map[string]vdl.Any),
+		Fields: make(map[string]vdlutil.Any),
 	}
 	for _, a := range e.subpipelines {
 		// We create a new channel for each intermediate result, so there's no need to
@@ -1031,7 +1033,7 @@
 	return entry.Value
 }
 
-func mapKeys(m map[string]vdl.Any) string {
+func mapKeys(m map[string]vdlutil.Any) string {
 	s := make([]string, 0, len(m))
 	for key, _ := range m {
 		s = append(s, key)
diff --git a/services/store/memstore/query/eval_test.go b/services/store/memstore/query/eval_test.go
index 148ace0..2985265 100644
--- a/services/store/memstore/query/eval_test.go
+++ b/services/store/memstore/query/eval_test.go
@@ -13,7 +13,7 @@
 	"veyron2/security"
 	"veyron2/services/store"
 	"veyron2/storage"
-	"veyron2/vdl"
+	"veyron2/vdl/vdlutil"
 	"veyron2/vlog"
 )
 
@@ -308,25 +308,25 @@
 		{
 			"", "'teams/cardinals' | {Name}",
 			[]*store.QueryResult{
-				&store.QueryResult{0, "teams/cardinals", map[string]vdl.Any{"Name": "cardinals"}, nil},
+				&store.QueryResult{0, "teams/cardinals", map[string]vdlutil.Any{"Name": "cardinals"}, nil},
 			},
 		},
 		{
 			"teams", "'cardinals' | {Name}",
 			[]*store.QueryResult{
-				&store.QueryResult{0, "cardinals", map[string]vdl.Any{"Name": "cardinals"}, nil},
+				&store.QueryResult{0, "cardinals", map[string]vdlutil.Any{"Name": "cardinals"}, nil},
 			},
 		},
 		{
 			"teams/cardinals", ". | {Name}",
 			[]*store.QueryResult{
-				&store.QueryResult{0, "", map[string]vdl.Any{"Name": "cardinals"}, nil},
+				&store.QueryResult{0, "", map[string]vdlutil.Any{"Name": "cardinals"}, nil},
 			},
 		},
 		{
 			"", "'teams/cardinals' | {Name as Name}",
 			[]*store.QueryResult{
-				&store.QueryResult{0, "teams/cardinals", map[string]vdl.Any{"Name": "cardinals"}, nil},
+				&store.QueryResult{0, "teams/cardinals", map[string]vdlutil.Any{"Name": "cardinals"}, nil},
 			},
 		},
 		{
@@ -335,7 +335,7 @@
 				&store.QueryResult{
 					0,
 					"teams/cardinals",
-					map[string]vdl.Any{
+					map[string]vdlutil.Any{
 						"myname": "cardinals",
 						"myloc":  "CA",
 					},
@@ -349,7 +349,7 @@
 				&store.QueryResult{
 					0,
 					"teams/cardinals",
-					map[string]vdl.Any{
+					map[string]vdlutil.Any{
 						"myname": "cardinals",
 						"myloc":  "CA",
 					},
@@ -368,7 +368,7 @@
 				&store.QueryResult{
 					0,
 					"teams/bears",
-					map[string]vdl.Any{
+					map[string]vdlutil.Any{
 						"myname":      "bears",
 						"drinkers":    store.NestedResult(1),
 						"nondrinkers": store.NestedResult(2),
@@ -378,7 +378,7 @@
 				&store.QueryResult{
 					0,
 					"teams/cardinals",
-					map[string]vdl.Any{
+					map[string]vdlutil.Any{
 						"myname":      "cardinals",
 						"drinkers":    store.NestedResult(3),
 						"nondrinkers": store.NestedResult(4),
@@ -394,7 +394,7 @@
 				&store.QueryResult{
 					0,
 					"teams/sharks",
-					map[string]vdl.Any{
+					map[string]vdlutil.Any{
 						"myname":      "sharks",
 						"drinkers":    store.NestedResult(5),
 						"nondrinkers": store.NestedResult(6),
@@ -492,7 +492,7 @@
 	it state.Iterator
 }
 
-func (m *mockSnapshot) NewIterator(pid security.PublicID, path storage.PathName, filter state.IterFilter) state.Iterator {
+func (m *mockSnapshot) NewIterator(pid security.PublicID, path storage.PathName, pathFilter state.PathFilter, filter state.IterFilter) state.Iterator {
 	return m.it
 }
 
diff --git a/services/store/memstore/query/glob.go b/services/store/memstore/query/glob.go
index 3614af3..8b1722e 100644
--- a/services/store/memstore/query/glob.go
+++ b/services/store/memstore/query/glob.go
@@ -32,7 +32,7 @@
 		pathLen: len(path),
 		glob:    parsed,
 	}
-	g.Iterator = sn.NewIterator(clientID, path, state.IterFilter(g.filter))
+	g.Iterator = sn.NewIterator(clientID, path, state.ListPaths, state.IterFilter(g.filter))
 
 	return g, nil
 }
diff --git a/services/store/memstore/query/glob_test.go b/services/store/memstore/query/glob_test.go
index 70ff580..6690d98 100644
--- a/services/store/memstore/query/glob_test.go
+++ b/services/store/memstore/query/glob_test.go
@@ -9,51 +9,64 @@
 	"veyron2/storage"
 )
 
-type nameOptions []string
-
 type globTest struct {
 	path     string
 	pattern  string
-	expected []nameOptions
+	expected []string
 }
 
 var globTests = []globTest{
-	{"", "mvps/...", []nameOptions{
-		{"mvps"},
-		{"mvps/Links/0"},
-		{"mvps/Links/1"},
+	{"", "...", []string{
+		"",
+		"mvps",
+		"mvps/Links/0",
+		"mvps/Links/1",
+		"players",
+		"players/alfred",
+		"players/alice",
+		"players/betty",
+		"players/bob",
+		"teams",
+		"teams/bears",
+		"teams/cardinals",
+		"teams/sharks",
 	}},
-	{"", "players/...", []nameOptions{
-		{"players"},
-		{"players/alfred"},
-		{"players/alice"},
-		{"players/betty"},
-		{"players/bob"},
+	{"", "mvps/...", []string{
+		"mvps",
+		"mvps/Links/0",
+		"mvps/Links/1",
+	}},
+	{"", "players/...", []string{
+		"players",
+		"players/alfred",
+		"players/alice",
+		"players/betty",
+		"players/bob",
 	}},
 	// Note(mattr): This test case shows that Glob does not return
 	// subfield nodes.
-	{"", "mvps/*", []nameOptions{}},
-	{"", "mvps/Links/*", []nameOptions{
-		{"mvps/Links/0"},
-		{"mvps/Links/1"},
+	{"", "mvps/*", []string{}},
+	{"", "mvps/Links/*", []string{
+		"mvps/Links/0",
+		"mvps/Links/1",
 	}},
-	{"", "players/alfred", []nameOptions{
-		{"players/alfred"},
+	{"", "players/alfred", []string{
+		"players/alfred",
 	}},
-	{"", "mvps/Links/0", []nameOptions{
-		{"mvps/Links/0"},
+	{"", "mvps/Links/0", []string{
+		"mvps/Links/0",
 	}},
 	// An empty pattern returns the element referred to by the path.
-	{"/mvps/Links/0", "", []nameOptions{
-		{""},
+	{"/mvps/Links/0", "", []string{
+		"",
 	}},
-	{"mvps", "Links/*", []nameOptions{
-		{"Links/0"},
-		{"Links/1"},
+	{"mvps", "Links/*", []string{
+		"Links/0",
+		"Links/1",
 	}},
-	{"mvps/Links", "*", []nameOptions{
-		{"0"},
-		{"1"},
+	{"mvps/Links", "*", []string{
+		"0",
+		"1",
 	}},
 }
 
@@ -102,16 +115,9 @@
 			t.Errorf("Wrong number of names for %s.  got %v, wanted %v",
 				gt.pattern, names, gt.expected)
 		}
-		for _, options := range gt.expected {
-			found := false
-			for _, name := range options {
-				if names[name] {
-					found = true
-					break
-				}
-			}
-			if !found {
-				t.Errorf("Expected to find one of %v in %v", options, names)
+		for _, name := range gt.expected {
+			if !names[name] {
+				t.Errorf("Expected to find %v in %v", name, names)
 			}
 		}
 	}
diff --git a/services/store/memstore/state/iterator.go b/services/store/memstore/state/iterator.go
index 92614be..70eac5c 100644
--- a/services/store/memstore/state/iterator.go
+++ b/services/store/memstore/state/iterator.go
@@ -37,10 +37,13 @@
 type iterator struct {
 	snapshot Snapshot
 
-	// Set of IDs already visited.
+	// Set of IDs already visited on this path.
 	visited map[storage.ID]struct{}
 
-	// Stack of IDs to visit next.  Some of these may already have been visited.
+	// Stack of actions to consider next. Actions are one of:
+	// - visit a node accessible from the current path (the node may already
+	//   have been visited on the current path).
+	// - unvisit a node (backtrack the current path).
 	next []next
 
 	// Depth of starting path.
@@ -50,6 +53,8 @@
 	entry *storage.Entry
 	path  *refs.FullPath
 
+	pathFilter PathFilter
+
 	filter IterFilter
 }
 
@@ -59,13 +64,32 @@
 	parent  *refs.FullPath
 	path    *refs.Path
 	id      storage.ID
+	action  action
 }
 
+type action int
+
+const (
+	visit = action(iota)
+	unvisit
+)
+
 var (
 	_ Iterator = (*iterator)(nil)
 	_ Iterator = (*errorIterator)(nil)
 )
 
+// A PathFilter automatically limits the traversal of certain paths,
+type PathFilter int
+
+const (
+	// ListPaths permits any path that does not visit the same object twice.
+	ListPaths = PathFilter(iota)
+	// ListObjects permits any path that does not revisit any object on a
+	// previously traversed path 'Q', even if Q did not satisfy it.filter.
+	ListObjects
+)
+
 // An IterFilter examines entries as they are considered by the
 // iterator and allows it to give two boolean inputs to the process:
 // ret: True if the iterator should return this value in its iteration.
@@ -84,11 +108,14 @@
 	return true, path == nil
 }
 
-// NewIterator returns an Iterator that starts with the value at
-// <path>.  If filter is given it is used to limit traversal beneath
-// certain paths. filter can be specified to limit the results of the iteration.
-// If filter is nil, all decendents of the specified path are returned.
-func (sn *snapshot) NewIterator(pid security.PublicID, path storage.PathName, filter IterFilter) Iterator {
+// NewIterator returns an Iterator that starts with the value at <path>.
+// pathFilter is used to automatically limit traversal of certain paths.
+// If filter is given, it is used to limit traversal beneath certain paths and
+// limit the results of the iteration. If filter is nil, all decendents of the
+// specified path are returned.
+func (sn *snapshot) NewIterator(pid security.PublicID, path storage.PathName,
+	pathFilter PathFilter, filter IterFilter) Iterator {
+
 	checker := sn.newPermChecker(pid)
 	cell, suffix, v := sn.resolveCell(checker, path, nil)
 	if cell == nil {
@@ -104,6 +131,7 @@
 		visited:      make(map[storage.ID]struct{}),
 		initialDepth: len(path),
 		path:         refs.NewFullPathFromName(path),
+		pathFilter:   pathFilter,
 		filter:       filter,
 	}
 
@@ -120,11 +148,12 @@
 	} else {
 		it.entry = cell.GetEntry()
 		it.visited[cell.ID] = struct{}{}
+		it.pushUnvisit(nil, cell.ID)
 		set = cell.refs
 	}
 
 	if expand {
-		it.pushAll(checker, it.path, set)
+		it.pushVisitAll(checker, it.path, set)
 	}
 	if !ret {
 		it.Next()
@@ -133,11 +162,25 @@
 	return it
 }
 
-func (it *iterator) pushAll(checker *acl.Checker, parentPath *refs.FullPath, set refs.Set) {
+func (it *iterator) pushUnvisit(path *refs.Path, id storage.ID) {
+	switch it.pathFilter {
+	case ListPaths:
+		it.next = append(it.next, next{nil, nil, path, id, unvisit})
+	case ListObjects:
+		// Do not unvisit the object, as it is on a path already seen by
+		// it.filter.
+	default:
+		panic("unknown PathFilter")
+	}
+}
+
+func (it *iterator) pushVisitAll(checker *acl.Checker,
+	parentPath *refs.FullPath, set refs.Set) {
+
 	set.Iter(func(x interface{}) bool {
 		ref := x.(*refs.Ref)
 		if checker.IsAllowed(ref.Label) {
-			it.next = append(it.next, next{checker, parentPath, ref.Path, ref.ID})
+			it.next = append(it.next, next{checker, parentPath, ref.Path, ref.ID, visit})
 		}
 		return true
 	})
@@ -171,10 +214,20 @@
 			return
 		}
 		n, it.next = it.next[topIndex], it.next[:topIndex]
+
+		if n.action == unvisit {
+			delete(it.visited, n.id)
+			continue
+		}
+
 		if _, ok := it.visited[n.id]; ok {
 			continue
 		}
 
+		// Mark as visited.
+		it.visited[n.id] = struct{}{}
+		it.pushUnvisit(n.path, n.id)
+
 		// Fetch the cell.
 		c = it.snapshot.Find(n.id)
 		if c == nil {
@@ -193,7 +246,7 @@
 		ret, expand := it.filter(n.parent, n.path)
 		fullPath = n.parent.AppendPath(n.path)
 		if expand {
-			it.pushAll(checker, fullPath, c.refs)
+			it.pushVisitAll(checker, fullPath, c.refs)
 		}
 		if ret {
 			// Found a value.
@@ -201,8 +254,6 @@
 		}
 	}
 
-	// Mark as visited.
-	it.visited[n.id] = struct{}{}
 	it.entry, it.path = c.GetEntry(), fullPath
 }
 
diff --git a/services/store/memstore/state/iterator_test.go b/services/store/memstore/state/iterator_test.go
index 344f69b..a9f3b2b 100644
--- a/services/store/memstore/state/iterator_test.go
+++ b/services/store/memstore/state/iterator_test.go
@@ -4,16 +4,48 @@
 	"runtime"
 	"testing"
 
+	"veyron/services/store/memstore/refs"
 	"veyron/services/store/memstore/state"
 	"veyron2/security"
 	"veyron2/storage"
 )
 
+// check that the iterator produces a set of names.
+func checkAcyclicIterator(t *testing.T, sn *state.MutableSnapshot, id security.PublicID, filter state.IterFilter, names []string) {
+	_, file, line, _ := runtime.Caller(1)
+
+	// Construct an index of names.
+	index := map[string]bool{}
+	for _, name := range names {
+		index[name] = false
+	}
+
+	// Compute the found names.
+	for it := sn.NewIterator(id, storage.ParsePath("/"), state.ListPaths, filter); it.IsValid(); it.Next() {
+		name := it.Name()
+		if found, ok := index[name]; ok {
+			if found {
+				t.Errorf("%s(%d): duplicate name %q", file, line, name)
+			}
+			index[name] = true
+		} else {
+			t.Errorf("%s(%d): unexpected name %q", file, line, name)
+		}
+	}
+
+	// Print the not found names.
+	for name, found := range index {
+		if !found {
+			t.Errorf("%s(%d): expected: %v", file, line, name)
+		}
+	}
+}
+
 // check that the iterator produces a set of names.  Since entries in the store
 // can have multiple names, the names are provided using a set of equivalence
 // classes.  The requirement is that the iterator produces exactly one name from
-// each equivalence class.  Order doesn't matter.
-func checkIterator(t *testing.T, sn *state.MutableSnapshot, id security.PublicID, names [][]string) {
+// each equivalence class. Order doesn't matter.
+func checkUniqueObjectsIterator(t *testing.T, sn *state.MutableSnapshot, id security.PublicID, filter state.IterFilter, names [][]string) {
 	_, file, line, _ := runtime.Caller(1)
 
 	// Construct an index of name to equivalence class.
@@ -26,7 +58,7 @@
 
 	// Compute the found set of equivalence classes.
 	found := map[int]bool{}
-	for it := sn.NewIterator(id, storage.ParsePath("/"), nil); it.IsValid(); it.Next() {
+	for it := sn.NewIterator(id, storage.ParsePath("/"), state.ListObjects, filter); it.IsValid(); it.Next() {
 		name := it.Name()
 		if i, ok := index[name]; ok {
 			if _, ok := found[i]; ok {
@@ -46,6 +78,55 @@
 	}
 }
 
+// Tests that an iterator returns all non-cyclic paths that reach an object.
+func TestDuplicatePaths(t *testing.T) {
+	st := state.New(rootPublicID)
+	sn := st.MutableSnapshot()
+
+	// Add some objects
+	put(t, sn, rootPublicID, "/", "")
+	put(t, sn, rootPublicID, "/teams", "")
+	put(t, sn, rootPublicID, "/teams/cardinals", "")
+	put(t, sn, rootPublicID, "/players", "")
+	mattID := put(t, sn, rootPublicID, "/players/matt", "")
+
+	// Add some hard links
+	put(t, sn, rootPublicID, "/teams/cardinals/mvp", mattID)
+
+	checkAcyclicIterator(t, sn, rootPublicID, nil, []string{
+		"",
+		"teams",
+		"players",
+		"teams/cardinals",
+		"players/matt",
+		"teams/cardinals/mvp",
+	})
+	checkUniqueObjectsIterator(t, sn, rootPublicID, nil, [][]string{
+		{""},
+		{"teams"},
+		{"players"},
+		{"teams/cardinals"},
+		{"players/matt", "teams/cardinals/mvp"},
+	})
+
+	// Test that the iterator does not revisit objects on previously rejected paths.
+	rejected := false
+	rejectMatt := func(fullPath *refs.FullPath, path *refs.Path) (bool, bool) {
+		name := fullPath.Append(path.Suffix(1)).Name().String()
+		if !rejected && (name == "players/matt" || name == "teams/cardinals/mvp") {
+			rejected = true
+			return false, true
+		}
+		return true, true
+	}
+	checkUniqueObjectsIterator(t, sn, rootPublicID, rejectMatt, [][]string{
+		{""},
+		{"teams"},
+		{"players"},
+		{"teams/cardinals"},
+	})
+}
+
 // Test that an iterator doesn't get stuck in cycles.
 func TestCyclicStructure(t *testing.T) {
 	st := state.New(rootPublicID)
@@ -63,7 +144,17 @@
 	put(t, sn, rootPublicID, "/players/matt/team", cardinalsID)
 	put(t, sn, rootPublicID, "/teams/cardinals/mvp", mattID)
 
-	checkIterator(t, sn, rootPublicID, [][]string{
+	checkAcyclicIterator(t, sn, rootPublicID, nil, []string{
+		"",
+		"teams",
+		"players",
+		"players/joe",
+		"players/matt",
+		"teams/cardinals/mvp",
+		"teams/cardinals",
+		"players/matt/team",
+	})
+	checkUniqueObjectsIterator(t, sn, rootPublicID, nil, [][]string{
 		{""},
 		{"teams"},
 		{"players"},
@@ -108,7 +199,21 @@
 	put(t, sn, rootPublicID, "/Users/john/shared", sharedID)
 
 	// Root gets everything.
-	checkIterator(t, sn, rootPublicID, [][]string{
+	checkAcyclicIterator(t, sn, rootPublicID, nil, []string{
+		"",
+		"Users",
+		"Users/jane",
+		"Users/jane/acls",
+		"Users/jane/acls/janeRWA",
+		"Users/jane/aaa",
+		"Users/john",
+		"Users/john/acls",
+		"Users/john/acls/johnRWA",
+		"Users/john/aaa",
+		"Users/jane/shared",
+		"Users/john/shared",
+	})
+	checkUniqueObjectsIterator(t, sn, rootPublicID, nil, [][]string{
 		{""},
 		{"Users"},
 		{"Users/jane"},
@@ -123,7 +228,16 @@
 	})
 
 	// Jane sees only her names.
-	checkIterator(t, sn, janePublicID, [][]string{
+	checkAcyclicIterator(t, sn, janePublicID, nil, []string{
+		"",
+		"Users",
+		"Users/jane",
+		"Users/jane/acls",
+		"Users/jane/acls/janeRWA",
+		"Users/jane/aaa",
+		"Users/jane/shared",
+	})
+	checkUniqueObjectsIterator(t, sn, janePublicID, nil, [][]string{
 		{""},
 		{"Users"},
 		{"Users/jane"},
@@ -134,7 +248,16 @@
 	})
 
 	// John sees only his names.
-	checkIterator(t, sn, johnPublicID, [][]string{
+	checkAcyclicIterator(t, sn, johnPublicID, nil, []string{
+		"",
+		"Users",
+		"Users/john",
+		"Users/john/acls",
+		"Users/john/acls/johnRWA",
+		"Users/john/aaa",
+		"Users/john/shared",
+	})
+	checkUniqueObjectsIterator(t, sn, johnPublicID, nil, [][]string{
 		{""},
 		{"Users"},
 		{"Users/john"},
diff --git a/services/store/memstore/state/log.go b/services/store/memstore/state/log.go
index afee1ea..68aea9c 100644
--- a/services/store/memstore/state/log.go
+++ b/services/store/memstore/state/log.go
@@ -1,11 +1,10 @@
 package state
 
 import (
-	"errors"
-
 	"veyron/services/store/memstore/refs"
 
 	"veyron2/storage"
+	"veyron2/verror"
 	"veyron2/vom"
 )
 
@@ -16,7 +15,7 @@
 )
 
 var (
-	errUnsupportedLogVersion = errors.New("unsupported log version")
+	errUnsupportedLogVersion = verror.Internalf("unsupported log version")
 )
 
 // header contains the meta-information for a log file.
diff --git a/services/store/memstore/state/mutable_snapshot.go b/services/store/memstore/state/mutable_snapshot.go
index 08e923d..c5a8b11 100644
--- a/services/store/memstore/state/mutable_snapshot.go
+++ b/services/store/memstore/state/mutable_snapshot.go
@@ -1,7 +1,6 @@
 package state
 
 import (
-	"errors"
 	"fmt"
 
 	"veyron/services/store/memstore/acl"
@@ -12,6 +11,7 @@
 	"veyron/runtimes/google/lib/functional"
 	"veyron2/security"
 	"veyron2/storage"
+	"veyron2/verror"
 )
 
 // MutableSnapshot is a mutable version of the snapshot.  It contains a Snapshot
@@ -103,17 +103,14 @@
 }
 
 var (
-	// TODO(tilaks): don't expose errors, use verror instead.
-	ErrBadPath              = errors.New("malformed path")
-	ErrTypeMismatch         = errors.New("type mismatch")
-	ErrNotFound             = errors.New("not found")
-	ErrBadRef               = errors.New("value has dangling references")
-	ErrCantUnlinkByID       = errors.New("can't unlink entries by ID")
-	ErrPreconditionFailed   = errors.New("precondition failed")
-	ErrIDsDoNotMatch        = errors.New("IDs do not match")
-	ErrPermissionDenied     = errors.New("permission denied") // TODO(tilaks): can permission denied leak store structure?
-	ErrNotTagList           = errors.New("not a TagList")
-	ErrDuplicatePutMutation = errors.New("duplicate calls to PutMutation for the same ID")
+	errBadPath              = verror.BadArgf("malformed path")
+	errBadRef               = verror.BadArgf("value has dangling references")
+	errCantUnlinkByID       = verror.BadArgf("can't unlink entries by ID")
+	errDuplicatePutMutation = verror.BadArgf("duplicate calls to PutMutation for the same ID")
+	errNotFound             = verror.NotFoundf("not found")
+	errNotTagList           = verror.BadArgf("not a TagList")
+	errPermissionDenied     = verror.NotAuthorizedf("")
+	errPreconditionFailed   = verror.Abortedf("precondition failed")
 
 	nullID storage.ID
 )
@@ -264,7 +261,7 @@
 		}
 		c.setRefs()
 		if !sn.refsExist(c.refs) {
-			return nil, ErrBadRef
+			return nil, errBadRef
 		}
 		sn.put(c)
 		sn.addRefs(id, c.refs)
@@ -280,13 +277,13 @@
 // replaceValue updates the cell.value.
 func (sn *MutableSnapshot) replaceValue(checker *acl.Checker, c *Cell, v interface{}) (*Cell, error) {
 	if !checker.IsAllowed(security.WriteLabel) {
-		return nil, ErrPermissionDenied
+		return nil, errPermissionDenied
 	}
 	cp := *c
 	cp.Value = v
 	cp.setRefs()
 	if !sn.refsExist(cp.refs) {
-		return nil, ErrBadRef
+		return nil, errBadRef
 	}
 	sn.put(&cp)
 	sn.updateRefs(c.ID, c.refs, cp.refs)
@@ -296,13 +293,13 @@
 // replaceDir updates the cell.dir.
 func (sn *MutableSnapshot) replaceDir(checker *acl.Checker, c *Cell, d functional.Set) (*Cell, error) {
 	if !checker.IsAllowed(security.WriteLabel) {
-		return nil, ErrPermissionDenied
+		return nil, errPermissionDenied
 	}
 	cp := *c
 	cp.Dir = d
 	cp.setRefs()
 	if !sn.refsExist(cp.refs) {
-		return nil, ErrBadRef
+		return nil, errBadRef
 	}
 	sn.put(&cp)
 	sn.updateRefs(c.ID, c.refs, cp.refs)
@@ -312,13 +309,13 @@
 // replaceTags replaces the cell.tags.
 func (sn *MutableSnapshot) replaceTags(checker *acl.Checker, c *Cell, tags storage.TagList) (*Cell, error) {
 	if !checker.IsAllowed(security.AdminLabel) {
-		return nil, ErrPermissionDenied
+		return nil, errPermissionDenied
 	}
 	cp := *c
 	cp.Tags = tags
 	cp.setRefs()
 	if !sn.refsExist(cp.refs) {
-		return nil, ErrBadRef
+		return nil, errBadRef
 	}
 	sn.put(&cp)
 	sn.updateRefs(c.ID, c.refs, cp.refs)
@@ -351,7 +348,7 @@
 	checker := sn.newPermChecker(pid)
 	cell, suffix, v := sn.resolveCell(checker, path, sn.mutations)
 	if cell == nil {
-		return nil, ErrNotFound
+		return nil, errNotFound
 	}
 	var e *storage.Entry
 	if len(suffix) == 0 {
@@ -394,7 +391,7 @@
 	// Find the parent object.
 	c, suffix, _ := sn.resolveCell(checker, path[:len(path)-1], sn.mutations)
 	if c == nil {
-		return nil, ErrNotFound
+		return nil, errNotFound
 	}
 	if len(suffix) > 0 && suffix[0] == refs.TagsDirName {
 		return sn.putTagsValue(checker, path, suffix[1:], c, v)
@@ -402,7 +399,7 @@
 	value := deepcopy(c.Value)
 	p, s := field.Get(makeInnerReference(value), suffix)
 	if len(s) != 0 {
-		return nil, ErrNotFound
+		return nil, errNotFound
 	}
 
 	// Add value to the parent.
@@ -411,7 +408,7 @@
 	switch result {
 	case field.SetFailed:
 		if len(suffix) != 0 {
-			return nil, ErrNotFound
+			return nil, errNotFound
 		}
 		if name == refs.TagsDirName {
 			return sn.putTags(checker, c, v)
@@ -438,7 +435,7 @@
 	tags := deepcopy(c.Tags).(storage.TagList)
 	p, s := field.Get(&tags, suffix)
 	if len(s) != 0 {
-		return nil, ErrNotFound
+		return nil, errNotFound
 	}
 
 	// Add value to the parent.
@@ -446,7 +443,7 @@
 	result, id := field.Set(p, name, v)
 	switch result {
 	case field.SetFailed:
-		return nil, ErrNotFound
+		return nil, errNotFound
 	case field.SetAsID:
 		nc, err := sn.add(checker, id, v)
 		if err != nil {
@@ -467,7 +464,7 @@
 func (sn *MutableSnapshot) putTags(checker *acl.Checker, c *Cell, v interface{}) (*Cell, error) {
 	tags, ok := v.(storage.TagList)
 	if !ok {
-		return nil, ErrNotTagList
+		return nil, errNotTagList
 	}
 	return sn.replaceTags(checker, c, tags)
 }
@@ -478,7 +475,7 @@
 	if id, ok := v.(storage.ID); ok {
 		ncell := sn.Find(id)
 		if ncell == nil {
-			return nil, ErrNotFound
+			return nil, errNotFound
 		}
 		r.ID = id
 		dir := c.Dir.Put(r)
@@ -513,7 +510,7 @@
 // putRoot replaces the root.
 func (sn *MutableSnapshot) putRoot(checker *acl.Checker, v interface{}) (*Cell, error) {
 	if !checker.IsAllowed(security.WriteLabel) {
-		return nil, ErrPermissionDenied
+		return nil, errPermissionDenied
 	}
 
 	id := sn.rootID
@@ -542,7 +539,7 @@
 func (sn *MutableSnapshot) putValueByID(checker *acl.Checker, id storage.ID, v interface{}) (*Cell, error) {
 	checker.Update(uidTagList)
 	if !checker.IsAllowed(security.WriteLabel) {
-		return nil, ErrPermissionDenied
+		return nil, errPermissionDenied
 	}
 
 	sn.gc()
@@ -554,7 +551,7 @@
 	checker := sn.newPermChecker(pid)
 	if path.IsRoot() {
 		if !checker.IsAllowed(security.WriteLabel) {
-			return ErrPermissionDenied
+			return errPermissionDenied
 		}
 		sn.unref(sn.rootID)
 		sn.rootID = nullID
@@ -563,13 +560,13 @@
 		return nil
 	}
 	if path.IsStrictID() {
-		return ErrCantUnlinkByID
+		return errCantUnlinkByID
 	}
 
 	// Split the names into directory and field parts.
 	cell, suffix, _ := sn.resolveCell(checker, path[:len(path)-1], sn.mutations)
 	if cell == nil {
-		return ErrNotFound
+		return errNotFound
 	}
 
 	// Remove the field.
@@ -586,7 +583,7 @@
 	value := deepcopy(cell.Value)
 	p, _ := field.Get(value, suffix)
 	if !field.Remove(p, name) {
-		return ErrNotFound
+		return errNotFound
 	}
 
 	_, err := sn.replaceValue(checker, cell, value)
@@ -600,7 +597,7 @@
 	id := extmu.ID
 	// Check that a mutation has not already been put for this id.
 	if _, ok := mus.Delta[id]; ok {
-		return ErrDuplicatePutMutation
+		return errDuplicatePutMutation
 	}
 	// If the object has no version, it was deleted.
 	if extmu.Version == storage.NoVersion {
diff --git a/services/store/memstore/state/mutable_snapshot_test.go b/services/store/memstore/state/mutable_snapshot_test.go
index 5651b70..1930ff1 100644
--- a/services/store/memstore/state/mutable_snapshot_test.go
+++ b/services/store/memstore/state/mutable_snapshot_test.go
@@ -8,6 +8,7 @@
 	"veyron/services/store/memstore/refs"
 
 	"veyron2/storage"
+	"veyron2/verror"
 	"veyron2/vom"
 )
 
@@ -198,8 +199,8 @@
 
 	// Not possible to create a Dir with a dangling reference.
 	d := &Dir{Entries: map[string]storage.ID{"ref": storage.NewID()}}
-	if _, err := sn.Put(rootPublicID, ePath, d); err != ErrBadRef {
-		t.Errorf("Error should be %q: got %q", ErrBadRef, err)
+	if _, err := sn.Put(rootPublicID, ePath, d); !verror.Is(err, verror.BadArg) {
+		t.Errorf("Error should be %v: got %v", verror.BadArg, err)
 	}
 
 	// Set the Ref to refer to the root.
diff --git a/services/store/memstore/state/snapshot.go b/services/store/memstore/state/snapshot.go
index 6c4b613..4213a55 100644
--- a/services/store/memstore/state/snapshot.go
+++ b/services/store/memstore/state/snapshot.go
@@ -12,11 +12,12 @@
 )
 
 type Snapshot interface {
-	// NewIterator returns an Iterator that starts with the value at <path>.  If
-	// filter is given it is used to limit traversal beneath certain paths.
-	// filter can be specified to limit the results of the iteration. If filter
-	// is nil, all decendents of the specified path are returned.
-	NewIterator(pid security.PublicID, path storage.PathName, filter IterFilter) Iterator
+	// NewIterator returns an Iterator that starts with the value at <path>.
+	// pathFilter is used to automatically limit traversal of certain paths.
+	// If filter is given, it is used to limit traversal beneath certain paths
+	// and limit the results of the iteration. If filter is nil, all decendents
+	// of the specified path are returned.
+	NewIterator(pid security.PublicID, path storage.PathName, pathFilter PathFilter, filter IterFilter) Iterator
 
 	// PathMatch returns true iff there is a name for the store value that
 	// matches the pathRegex.
@@ -94,7 +95,7 @@
 	// Pass nil for 'mutations' since the snapshot is immutable.
 	cell, suffix, v := sn.resolveCell(checker, path, nil)
 	if cell == nil {
-		return nil, ErrNotFound
+		return nil, errNotFound
 	}
 	var e *storage.Entry
 	if len(suffix) == 0 {
@@ -139,7 +140,7 @@
 		if len(path) > 0 && path[0] == refs.TagsDirName {
 			if !checker.IsAllowed(security.AdminLabel) {
 				// Access to .tags requires admin priviledges.
-				return nil, nil, ErrPermissionDenied
+				return nil, nil, errPermissionDenied
 			}
 			v, suffix = field.Get(cell.Tags, path[1:])
 		} else {
diff --git a/services/store/memstore/state/state.go b/services/store/memstore/state/state.go
index a1cd56c..04f914c 100644
--- a/services/store/memstore/state/state.go
+++ b/services/store/memstore/state/state.go
@@ -106,14 +106,14 @@
 		// is 0 and the cell already exists, or pre is not 0 and the cell does
 		// not already exist or have the expected version.
 		if pre == 0 && ok || pre != 0 && (!ok || c.(*Cell).Version != pre) {
-			return ErrPreconditionFailed
+			return errPreconditionFailed
 		}
 	}
 	for id, pre := range mu.Deletions {
 		c, ok := table.Get(&Cell{ID: id})
 		// The target is not required to exist.
 		if ok && c.(*Cell).Version != pre {
-			return ErrPreconditionFailed
+			return errPreconditionFailed
 		}
 	}
 
diff --git a/services/store/memstore/store.go b/services/store/memstore/store.go
index a4397b0..7a6202d 100644
--- a/services/store/memstore/store.go
+++ b/services/store/memstore/store.go
@@ -1,7 +1,6 @@
 package memstore
 
 import (
-	"errors"
 	"io"
 
 	"veyron/runtimes/google/lib/sync"
@@ -13,6 +12,7 @@
 	"veyron2/ipc"
 	"veyron2/security"
 	"veyron2/storage"
+	"veyron2/verror"
 )
 
 // Store is the in-memory state of the store.
@@ -31,7 +31,7 @@
 var _ service.Store = (*Store)(nil)
 
 var (
-	ErrRequestCancelled = errors.New("request cancelled")
+	ErrRequestCancelled = verror.Abortedf("request cancelled")
 )
 
 // New creates a new store.  admin is the public ID of the administrator, dbName
diff --git a/services/store/memstore/store_test.go b/services/store/memstore/store_test.go
index 6024504..a71aa48 100644
--- a/services/store/memstore/store_test.go
+++ b/services/store/memstore/store_test.go
@@ -5,10 +5,11 @@
 	"os"
 	"testing"
 
-	"veyron/services/store/memstore/state"
+	storetesting "veyron/services/store/memstore/testing"
 	"veyron/services/store/raw"
 
 	"veyron2/storage"
+	"veyron2/verror"
 )
 
 func TestLogWrite(t *testing.T) {
@@ -85,8 +86,8 @@
 	st.log.close()
 
 	// Commit the state. The call should fail.
-	if err := st.log.appendTransaction(nil); err != errLogIsClosed {
-		t.Errorf("Expected error %q, got %q", errLogIsClosed, err)
+	if err := st.log.appendTransaction(nil); !verror.Is(err, verror.Aborted) {
+		t.Errorf("Expected error %v, got %v", verror.Aborted, err)
 	}
 }
 
@@ -142,7 +143,7 @@
 	post1, post2, post3 := storage.NewVersion(), storage.NewVersion(), storage.NewVersion()
 	v1, v2, v3 := "v1", "v2", "v3"
 
-	putMutationsBatch(t, st, []raw.Mutation{
+	storetesting.PutMutationsBatch(t, rootPublicID, st.PutMutations, []raw.Mutation{
 		raw.Mutation{
 			ID:           id1,
 			PriorVersion: pre1,
@@ -177,14 +178,14 @@
 	pre1, pre2, pre3 = post1, post2, post3
 	post2 = storage.NewVersion()
 
-	putMutationsBatch(t, st, []raw.Mutation{raw.Mutation{
-		ID:           id2,
-		PriorVersion: pre2,
-		Version:      post2,
-		IsRoot:       false,
-		Value:        v2,
-		Dir:          empty,
-	}})
+	storetesting.PutMutationsBatch(t, rootPublicID, st.PutMutations, []raw.Mutation{
+		raw.Mutation{
+			ID: id2, PriorVersion: pre2,
+			Version: post2,
+			IsRoot:  false,
+			Value:   v2,
+			Dir:     empty,
+		}})
 
 	expectValue(t, st, nil, "/", v1)
 	expectValue(t, st, nil, "/a", v2)
@@ -193,12 +194,13 @@
 	// Garbage-collect /a/b
 	post3 = storage.NoVersion
 
-	putMutationsBatch(t, st, []raw.Mutation{raw.Mutation{
-		ID:           id3,
-		PriorVersion: pre3,
-		Version:      post3,
-		IsRoot:       false,
-	}})
+	storetesting.PutMutationsBatch(t, rootPublicID, st.PutMutations, []raw.Mutation{
+		raw.Mutation{
+			ID:           id3,
+			PriorVersion: pre3,
+			Version:      post3,
+			IsRoot:       false,
+		}})
 
 	expectValue(t, st, nil, "/", v1)
 	expectValue(t, st, nil, "/a", v2)
@@ -208,12 +210,13 @@
 	pre1, pre2, pre3 = post1, post2, post3
 	post1 = storage.NoVersion
 
-	putMutationsBatch(t, st, []raw.Mutation{raw.Mutation{
-		ID:           id1,
-		PriorVersion: pre1,
-		Version:      post1,
-		IsRoot:       true,
-	}})
+	storetesting.PutMutationsBatch(t, rootPublicID, st.PutMutations, []raw.Mutation{
+		raw.Mutation{
+			ID:           id1,
+			PriorVersion: pre1,
+			Version:      post1,
+			IsRoot:       true,
+		}})
 
 	expectNotExists(t, st, nil, "/")
 	expectNotExists(t, st, nil, "/a")
@@ -222,12 +225,13 @@
 	// Garbage-collect /a
 	post2 = storage.NoVersion
 
-	putMutationsBatch(t, st, []raw.Mutation{raw.Mutation{
-		ID:           id2,
-		PriorVersion: pre2,
-		Version:      post2,
-		IsRoot:       false,
-	}})
+	storetesting.PutMutationsBatch(t, rootPublicID, st.PutMutations, []raw.Mutation{
+		raw.Mutation{
+			ID:           id2,
+			PriorVersion: pre2,
+			Version:      post2,
+			IsRoot:       false,
+		}})
 
 	expectNotExists(t, st, nil, "/")
 	expectNotExists(t, st, nil, "/a")
@@ -253,7 +257,7 @@
 	post1, post2 := storage.NewVersion(), storage.NewVersion()
 	v1, v2 := "v1", "v2"
 
-	putMutationsBatch(t, st, []raw.Mutation{
+	storetesting.PutMutationsBatch(t, rootPublicID, st.PutMutations, []raw.Mutation{
 		raw.Mutation{
 			ID:           id1,
 			PriorVersion: pre1,
@@ -280,7 +284,7 @@
 	post2 = storage.NewVersion()
 	v2 = "v4"
 
-	s := putMutations(st)
+	s := storetesting.PutMutations(rootPublicID, st.PutMutations)
 	s.Send(raw.Mutation{
 		ID:           id2,
 		PriorVersion: pre2,
@@ -289,8 +293,8 @@
 		Value:        v2,
 		Dir:          empty,
 	})
-	if err := s.Finish(); err != state.ErrPreconditionFailed {
-		t.Fatalf("Expected precondition to fail")
+	if err := s.Finish(); !verror.Is(err, verror.Aborted) {
+		t.Errorf("Error should be %v: got %v", verror.Aborted, err)
 	}
 
 }
@@ -309,7 +313,7 @@
 	}
 
 	id := storage.NewID()
-	s := putMutations(st)
+	s := storetesting.PutMutations(rootPublicID, st.PutMutations)
 	s.Send(raw.Mutation{
 		ID:           id,
 		PriorVersion: storage.NoVersion,
@@ -326,8 +330,8 @@
 		Value:        "v2",
 		Dir:          empty,
 	})
-	if err := s.Finish(); err != state.ErrDuplicatePutMutation {
-		t.Fatalf("Expected precondition to fail")
+	if err := s.Finish(); !verror.Is(err, verror.BadArg) {
+		t.Errorf("Error should be %v: got %v", verror.BadArg, err)
 	}
 }
 
@@ -344,7 +348,7 @@
 		t.Fatalf("New() failed: %v", err)
 	}
 
-	s := putMutations(st)
+	s := storetesting.PutMutations(rootPublicID, st.PutMutations)
 	s.Send(raw.Mutation{
 		ID:           storage.NewID(),
 		PriorVersion: storage.NoVersion,
@@ -354,8 +358,8 @@
 		Dir:          empty,
 	})
 	s.Cancel()
-	if err := s.Finish(); err != ErrRequestCancelled {
-		t.Fatalf("Expected request to be cancelled")
+	if err := s.Finish(); !verror.Is(err, verror.Aborted) {
+		t.Errorf("Error should be %v: got %v", verror.Aborted, err)
 	}
 
 	expectNotExists(t, st, nil, "/")
diff --git a/services/store/memstore/watch/testing/util.go b/services/store/memstore/testing/util.go
similarity index 83%
rename from services/store/memstore/watch/testing/util.go
rename to services/store/memstore/testing/util.go
index 1e34a32..0553c75 100644
--- a/services/store/memstore/watch/testing/util.go
+++ b/services/store/memstore/testing/util.go
@@ -1,7 +1,8 @@
-package blackbox
+package testing
 
 import (
-	"errors"
+	"io"
+	"runtime"
 	"sync"
 	"testing"
 	"time"
@@ -16,10 +17,6 @@
 	"veyron2/storage"
 )
 
-var (
-	ErrStreamClosed = errors.New("stream closed")
-)
-
 // CancellableContext implements ipc.ServerContext.
 type CancellableContext struct {
 	id        security.PublicID
@@ -105,6 +102,80 @@
 	return ctx.cancelled
 }
 
+// Utilities for PutMutations.
+
+// storeServicePutMutationsStream implements raw.StoreServicePutMutationsStream
+type storeServicePutMutationsStream struct {
+	mus <-chan raw.Mutation
+}
+
+func (s *storeServicePutMutationsStream) Recv() (raw.Mutation, error) {
+	mu, ok := <-s.mus
+	if !ok {
+		return mu, io.EOF
+	}
+	return mu, nil
+}
+
+// storePutMutationsStream implements raw.StorePutMutationsStream
+type storePutMutationsStream struct {
+	ctx    ipc.ServerContext
+	closed bool
+	mus    chan<- raw.Mutation
+	err    <-chan error
+}
+
+func (s *storePutMutationsStream) Send(mu raw.Mutation) error {
+	s.mus <- mu
+	return nil
+}
+
+func (s *storePutMutationsStream) CloseSend() error {
+	if !s.closed {
+		s.closed = true
+		close(s.mus)
+	}
+	return nil
+}
+
+func (s *storePutMutationsStream) Finish() error {
+	s.CloseSend()
+	return <-s.err
+}
+
+func (s *storePutMutationsStream) Cancel() {
+	s.ctx.(*CancellableContext).Cancel()
+	s.CloseSend()
+}
+
+func PutMutations(id security.PublicID, putMutationsFn func(ipc.ServerContext, raw.StoreServicePutMutationsStream) error) raw.StorePutMutationsStream {
+	ctx := NewCancellableContext(id)
+	mus := make(chan raw.Mutation)
+	err := make(chan error)
+	go func() {
+		err <- putMutationsFn(ctx, &storeServicePutMutationsStream{mus})
+		close(err)
+	}()
+	return &storePutMutationsStream{
+		ctx: ctx,
+		mus: mus,
+		err: err,
+	}
+}
+
+func PutMutationsBatch(t *testing.T, id security.PublicID, putMutationsFn func(ipc.ServerContext, raw.StoreServicePutMutationsStream) error, mus []raw.Mutation) {
+	storePutMutationsStream := PutMutations(id, putMutationsFn)
+	for _, mu := range mus {
+		storePutMutationsStream.Send(mu)
+	}
+	if err := storePutMutationsStream.Finish(); err != nil {
+		_, file, line, _ := runtime.Caller(1)
+		t.Errorf("%s(%d): can't put mutations %s: %s", file, line, mus, err)
+	}
+}
+
+// Utilities for Watch.
+
 // watcherServiceWatchStream implements watch.WatcherServiceWatchStream.
 type watcherServiceWatchStream struct {
 	mu     *sync.Mutex
@@ -119,7 +190,7 @@
 	case s.output <- cb:
 		return nil
 	case <-s.ctx.Closed():
-		return ErrStreamClosed
+		return io.EOF
 	}
 }
 
@@ -133,7 +204,7 @@
 func (s *watcherWatchStream) Recv() (watch.ChangeBatch, error) {
 	cb, ok := <-s.input
 	if !ok {
-		return cb, ErrStreamClosed
+		return cb, io.EOF
 	}
 	return cb, nil
 }
diff --git a/services/store/memstore/transaction.go b/services/store/memstore/transaction.go
index 5328457..bb82a34 100644
--- a/services/store/memstore/transaction.go
+++ b/services/store/memstore/transaction.go
@@ -1,11 +1,11 @@
 package memstore
 
 import (
-	"errors"
 	"sync"
 
 	"veyron/services/store/memstore/state"
 	"veyron/services/store/service"
+	"veyron2/verror"
 )
 
 // Transaction is the type of transactions.  Each transaction has a snapshot of
@@ -22,7 +22,7 @@
 }
 
 var (
-	errBadTransaction = errors.New("bad transaction")
+	errBadTransaction = verror.BadArgf("bad transaction")
 )
 
 // newNilTransaction is used when nil is passed in as the transaction for an
diff --git a/services/store/memstore/util_test.go b/services/store/memstore/util_test.go
index 9a344a8..c95f94b 100644
--- a/services/store/memstore/util_test.go
+++ b/services/store/memstore/util_test.go
@@ -1,166 +1,14 @@
 package memstore
 
 import (
-	"io"
 	"runtime"
 	"testing"
-	"time"
 
-	"veyron/services/store/raw"
 	"veyron/services/store/service"
 
-	"veyron2/ipc"
-	"veyron2/naming"
-	"veyron2/security"
 	"veyron2/storage"
 )
 
-// cancellableContext implements ipc.ServerContext.
-type cancellableContext struct {
-	cancelled chan struct{}
-}
-
-func newCancellableContext() *cancellableContext {
-	return &cancellableContext{cancelled: make(chan struct{})}
-}
-
-func (*cancellableContext) Server() ipc.Server {
-	return nil
-}
-
-func (*cancellableContext) Method() string {
-	return ""
-}
-
-func (*cancellableContext) Name() string {
-	return ""
-}
-
-func (*cancellableContext) Suffix() string {
-	return ""
-}
-
-func (*cancellableContext) Label() (l security.Label) {
-	return
-}
-
-func (*cancellableContext) CaveatDischarges() security.CaveatDischargeMap {
-	return nil
-}
-
-func (*cancellableContext) LocalID() security.PublicID {
-	return rootPublicID
-}
-
-func (*cancellableContext) RemoteID() security.PublicID {
-	return rootPublicID
-}
-
-func (*cancellableContext) Blessing() security.PublicID {
-	return nil
-}
-
-func (*cancellableContext) LocalEndpoint() naming.Endpoint {
-	return nil
-}
-
-func (*cancellableContext) RemoteEndpoint() naming.Endpoint {
-	return nil
-}
-
-func (*cancellableContext) Deadline() (t time.Time) {
-	return
-}
-
-func (ctx *cancellableContext) IsClosed() bool {
-	select {
-	case <-ctx.cancelled:
-		return true
-	default:
-		return false
-	}
-}
-
-func (ctx *cancellableContext) Closed() <-chan struct{} {
-	return ctx.cancelled
-}
-
-// cancel synchronously closes the context. After cancel returns, calls to
-// IsClosed will return true and the stream returned by Closed will be closed.
-func (ctx *cancellableContext) cancel() {
-	close(ctx.cancelled)
-}
-
-// serverStream implements raw.StoreServicePutMutationsStream
-type serverStream struct {
-	mus <-chan raw.Mutation
-}
-
-func (s *serverStream) Recv() (raw.Mutation, error) {
-	mu, ok := <-s.mus
-	if !ok {
-		return mu, io.EOF
-	}
-	return mu, nil
-}
-
-// clientStream implements raw.StorePutMutationsStream
-type clientStream struct {
-	ctx    ipc.ServerContext
-	closed bool
-	mus    chan<- raw.Mutation
-	err    <-chan error
-}
-
-func (s *clientStream) Send(mu raw.Mutation) error {
-	s.mus <- mu
-	return nil
-}
-
-func (s *clientStream) CloseSend() error {
-	if !s.closed {
-		s.closed = true
-		close(s.mus)
-	}
-	return nil
-}
-
-func (s *clientStream) Finish() error {
-	s.CloseSend()
-	return <-s.err
-}
-
-func (s *clientStream) Cancel() {
-	s.ctx.(*cancellableContext).cancel()
-	s.CloseSend()
-}
-
-func putMutations(st *Store) raw.StorePutMutationsStream {
-	ctx := newCancellableContext()
-	mus := make(chan raw.Mutation)
-	err := make(chan error)
-	go func() {
-		err <- st.PutMutations(ctx, &serverStream{mus})
-		close(err)
-	}()
-	return &clientStream{
-		ctx: ctx,
-		mus: mus,
-		err: err,
-	}
-}
-
-func putMutationsBatch(t *testing.T, st *Store, mus []raw.Mutation) {
-	clientStream := putMutations(st)
-	for _, mu := range mus {
-		clientStream.Send(mu)
-	}
-	if err := clientStream.Finish(); err != nil {
-		_, file, line, _ := runtime.Caller(1)
-		t.Errorf("%s(%d): can't put mutations %s: %s", file, line, mus, err)
-	}
-}
-
 func mkdir(t *testing.T, st *Store, tr service.Transaction, path string) (storage.ID, interface{}) {
 	_, file, line, _ := runtime.Caller(1)
 	dir := &Dir{}
diff --git a/services/store/memstore/watch/glob_processor.go b/services/store/memstore/watch/glob_processor.go
index 38ea6c1..6254a17 100644
--- a/services/store/memstore/watch/glob_processor.go
+++ b/services/store/memstore/watch/glob_processor.go
@@ -1,8 +1,6 @@
 package watch
 
 import (
-	"errors"
-
 	iquery "veyron/services/store/memstore/query"
 	"veyron/services/store/memstore/state"
 
@@ -42,7 +40,7 @@
 func (p *globProcessor) processState(st *state.State) ([]watch.Change, error) {
 	// Check that the initial state has not already been processed.
 	if p.hasProcessedState {
-		return nil, errors.New("cannot process state after processing the initial state")
+		return nil, errInitialStateAlreadyProcessed
 	}
 	p.hasProcessedState = true
 
@@ -76,7 +74,7 @@
 func (p *globProcessor) processTransaction(mus *state.Mutations) ([]watch.Change, error) {
 	// Ensure that the initial state has been processed.
 	if !p.hasProcessedState {
-		return nil, errors.New("cannot process a transaction before processing the initial state")
+		return nil, errInitialStateNotProcessed
 	}
 
 	previousMatches := p.matches
diff --git a/services/store/memstore/watch/glob_processor_test.go b/services/store/memstore/watch/glob_processor_test.go
index fc2c310..02f73c7 100644
--- a/services/store/memstore/watch/glob_processor_test.go
+++ b/services/store/memstore/watch/glob_processor_test.go
@@ -4,7 +4,7 @@
 	"testing"
 
 	"veyron/services/store/memstore"
-	watchtesting "veyron/services/store/memstore/watch/testing"
+	watchtesting "veyron/services/store/memstore/testing"
 
 	"veyron2/storage"
 )
@@ -19,6 +19,9 @@
 	id1 := put(t, st, tr, "/", "val1")
 	id2 := put(t, st, tr, "/a", "val2")
 	put(t, st, tr, "/a/b", "val3")
+	id4 := put(t, st, tr, "/a/c", "val4")
+	// Test duplicate paths to the same object.
+	put(t, st, tr, "/a/d", id4)
 	commit(t, tr)
 
 	// Remove /a/b.
@@ -44,20 +47,26 @@
 	aRecursiveProcessor := createGlobProcessor(t, storage.ParsePath("/a"), "...")
 	aListProcessor := createGlobProcessor(t, storage.ParsePath("/a"), "*")
 
-	// Expect initial state that contains / and /a.
+	// Expect initial state that contains /, /a, /a/c and /a/d.
 	logst := readState(t, log)
 
-	changes := processState(t, rootRecursiveProcessor, logst, 2)
+	changes := processState(t, rootRecursiveProcessor, logst, 4)
 	watchtesting.ExpectEntryExists(t, changes, "", id1, "val1")
 	watchtesting.ExpectEntryExists(t, changes, "a", id2, "val2")
+	watchtesting.ExpectEntryExists(t, changes, "a/c", id4, "val4")
+	watchtesting.ExpectEntryExists(t, changes, "a/d", id4, "val4")
 
 	changes = processState(t, rootListProcessor, logst, 1)
 	watchtesting.ExpectEntryExists(t, changes, "a", id2, "val2")
 
-	changes = processState(t, aRecursiveProcessor, logst, 1)
+	changes = processState(t, aRecursiveProcessor, logst, 3)
 	watchtesting.ExpectEntryExists(t, changes, "a", id2, "val2")
+	watchtesting.ExpectEntryExists(t, changes, "a/c", id4, "val4")
+	watchtesting.ExpectEntryExists(t, changes, "a/d", id4, "val4")
 
-	processState(t, aListProcessor, logst, 0)
+	processState(t, aListProcessor, logst, 2)
+	watchtesting.ExpectEntryExists(t, changes, "a/c", id4, "val4")
+	watchtesting.ExpectEntryExists(t, changes, "a/d", id4, "val4")
 }
 
 func TestGlobProcessTransactionAdd(t *testing.T) {
@@ -85,25 +94,34 @@
 	id1 := put(t, st, tr, "/", "val1")
 	id2 := put(t, st, tr, "/a", "val2")
 	id3 := put(t, st, tr, "/a/b", "val3")
+	id4 := put(t, st, tr, "/a/c", "val4")
+	// Test duplicate paths to the same object.
+	put(t, st, tr, "/a/d", id4)
 	commit(t, tr)
 
 	// Expect transaction that adds /, /a and /a/b.
 	mus := readTransaction(t, log)
 
-	changes := processTransaction(t, rootRecursiveProcessor, mus, 3)
+	changes := processTransaction(t, rootRecursiveProcessor, mus, 5)
 	watchtesting.ExpectEntryExists(t, changes, "", id1, "val1")
 	watchtesting.ExpectEntryExists(t, changes, "a", id2, "val2")
 	watchtesting.ExpectEntryExists(t, changes, "a/b", id3, "val3")
+	watchtesting.ExpectEntryExists(t, changes, "a/c", id4, "val4")
+	watchtesting.ExpectEntryExists(t, changes, "a/d", id4, "val4")
 
 	changes = processTransaction(t, rootListProcessor, mus, 1)
 	watchtesting.ExpectEntryExists(t, changes, "a", id2, "val2")
 
-	changes = processTransaction(t, aRecursiveProcessor, mus, 2)
+	changes = processTransaction(t, aRecursiveProcessor, mus, 4)
 	watchtesting.ExpectEntryExists(t, changes, "a", id2, "val2")
 	watchtesting.ExpectEntryExists(t, changes, "a/b", id3, "val3")
+	watchtesting.ExpectEntryExists(t, changes, "a/c", id4, "val4")
+	watchtesting.ExpectEntryExists(t, changes, "a/d", id4, "val4")
 
-	changes = processTransaction(t, aListProcessor, mus, 1)
+	changes = processTransaction(t, aListProcessor, mus, 3)
 	watchtesting.ExpectEntryExists(t, changes, "a/b", id3, "val3")
+	watchtesting.ExpectEntryExists(t, changes, "a/c", id4, "val4")
+	watchtesting.ExpectEntryExists(t, changes, "a/d", id4, "val4")
 
 	changes = processTransaction(t, bRecursiveProcessor, mus, 1)
 	watchtesting.ExpectEntryExists(t, changes, "a/b", id3, "val3")
diff --git a/services/store/memstore/watch/processor.go b/services/store/memstore/watch/processor.go
index ab9bb69..ce3e07e 100644
--- a/services/store/memstore/watch/processor.go
+++ b/services/store/memstore/watch/processor.go
@@ -3,6 +3,12 @@
 import (
 	"veyron/services/store/memstore/state"
 	"veyron2/services/watch"
+	"veyron2/verror"
+)
+
+var (
+	errInitialStateAlreadyProcessed = verror.Internalf("cannot process state after processing the initial state")
+	errInitialStateNotProcessed     = verror.Internalf("cannot process a transaction before processing the initial state")
 )
 
 // reqProcessor processes log entries into watch changes. At first,
diff --git a/services/store/memstore/watch/raw_processor.go b/services/store/memstore/watch/raw_processor.go
index 7781c48..5c8d76e 100644
--- a/services/store/memstore/watch/raw_processor.go
+++ b/services/store/memstore/watch/raw_processor.go
@@ -1,7 +1,6 @@
 package watch
 
 import (
-	"errors"
 	"fmt"
 
 	"veyron/services/store/memstore/refs"
@@ -11,6 +10,7 @@
 	"veyron2/security"
 	"veyron2/services/watch"
 	"veyron2/storage"
+	"veyron2/verror"
 )
 
 var (
@@ -50,7 +50,7 @@
 func (p *rawProcessor) processState(st *state.State) ([]watch.Change, error) {
 	// Check that the initial state has not already been processed.
 	if p.hasProcessedState {
-		return nil, errors.New("cannot process state after processing the initial state")
+		return nil, errInitialStateAlreadyProcessed
 	}
 	p.hasProcessedState = true
 
@@ -67,7 +67,9 @@
 	// Create a change for each id in the state. In each change, the object
 	// exists, has no PriorVersion, has the Version of the new cell, and
 	// has the Value, Tags and Dir of the new cell.
-	for it := sn.NewIterator(p.pid, nil, state.RecursiveFilter); it.IsValid(); it.Next() {
+	for it := sn.NewIterator(p.pid, nil,
+		state.ListObjects, state.RecursiveFilter); it.IsValid(); it.Next() {
+
 		entry := it.Get()
 		id := entry.Stat.ID
 		// Retrieve Value, Tags and Dir from the corresponding cell.
@@ -100,7 +102,7 @@
 func (p *rawProcessor) processTransaction(mus *state.Mutations) ([]watch.Change, error) {
 	// Ensure that the initial state has been processed.
 	if !p.hasProcessedState {
-		return nil, errors.New("cannot process a transaction before processing the initial state")
+		return nil, errInitialStateNotProcessed
 	}
 
 	// If the root was deleted, add extra space for a prepared deletion.
@@ -207,7 +209,7 @@
 // does not have a root, nullID is returned.
 func rootID(pid security.PublicID, sn *state.MutableSnapshot) (storage.ID, error) {
 	entry, err := sn.Get(pid, rootPath)
-	if err == state.ErrNotFound {
+	if verror.Is(err, verror.NotFound) {
 		return nullID, nil
 	}
 	if err != nil {
diff --git a/services/store/memstore/watch/raw_processor_test.go b/services/store/memstore/watch/raw_processor_test.go
index 8599ef0..895baae 100644
--- a/services/store/memstore/watch/raw_processor_test.go
+++ b/services/store/memstore/watch/raw_processor_test.go
@@ -4,7 +4,7 @@
 	"testing"
 
 	"veyron/services/store/memstore"
-	watchtesting "veyron/services/store/memstore/watch/testing"
+	watchtesting "veyron/services/store/memstore/testing"
 
 	"veyron2/storage"
 )
diff --git a/services/store/memstore/watch/watcher.go b/services/store/memstore/watch/watcher.go
index 4cf8562..ad1ae00 100644
--- a/services/store/memstore/watch/watcher.go
+++ b/services/store/memstore/watch/watcher.go
@@ -3,7 +3,6 @@
 import (
 	"bytes"
 	"encoding/binary"
-	"errors"
 	"io"
 	"time"
 
@@ -20,8 +19,8 @@
 )
 
 var (
-	ErrWatchClosed            = io.EOF
-	ErrUnknownResumeMarker    = errors.New("Unknown ResumeMarker")
+	errWatchClosed            = io.EOF
+	errUnknownResumeMarker    = verror.BadArgf("Unknown ResumeMarker")
 	nowResumeMarker           = []byte("now") // UTF-8 conversion.
 	initialStateSkippedChange = watch.Change{
 		Name:  "",
@@ -104,7 +103,7 @@
 	done := make(chan error, 1)
 
 	if !w.pending.TryAdd() {
-		return ErrWatchClosed
+		return errWatchClosed
 	}
 	// This goroutine does not leak because processRequest is always terminated.
 	go func() {
@@ -122,7 +121,7 @@
 	case <-w.closed:
 	case <-ctx.Closed():
 	}
-	return ErrWatchClosed
+	return errWatchClosed
 }
 
 func (w *watcher) processRequest(cancel <-chan struct{}, processor reqProcessor,
@@ -251,7 +250,7 @@
 		return &onOrAfterFilter{baseFilter{uint64(time.Now().UnixNano()), false}}, nil
 	}
 	if len(resumeMarker) != 8 {
-		return nil, ErrUnknownResumeMarker
+		return nil, errUnknownResumeMarker
 	}
 	return &onAndAfterFilter{baseFilter{binary.BigEndian.Uint64(resumeMarker), false}}, nil
 }
@@ -276,7 +275,7 @@
 			return false, nil
 		}
 		if timestamp > f.initialTimestamp {
-			return false, ErrUnknownResumeMarker
+			return false, errUnknownResumeMarker
 		}
 		// TODO(tilaks): if the most recent timestamp in the log is less than
 		// initialTimestamp, return ErrUnknownResumeMarker.
diff --git a/services/store/memstore/watch/watcher_test.go b/services/store/memstore/watch/watcher_test.go
index 1ce5af6..8ef6878 100644
--- a/services/store/memstore/watch/watcher_test.go
+++ b/services/store/memstore/watch/watcher_test.go
@@ -8,11 +8,12 @@
 	"time"
 
 	"veyron/services/store/memstore"
-	watchtesting "veyron/services/store/memstore/watch/testing"
+	watchtesting "veyron/services/store/memstore/testing"
 	"veyron/services/store/raw"
 
 	"veyron2/services/watch"
 	"veyron2/storage"
+	"veyron2/verror"
 )
 
 func TestWatchRaw(t *testing.T) {
@@ -164,7 +165,7 @@
 	commit(t, tr)
 
 	// Check that watch did not processed the second transaction.
-	if _, err := ws.Recv(); err != watchtesting.ErrStreamClosed {
+	if _, err := ws.Recv(); err != io.EOF {
 		t.Errorf("Unexpected error: %v", err)
 	}
 
@@ -474,8 +475,8 @@
 	ws := watchtesting.WatchRaw(rootPublicID, w.WatchRaw, req)
 
 	// The resume marker should be unknown.
-	if err := ws.Finish(); err != ErrUnknownResumeMarker {
-		t.Errorf("Unexpected error: %v", err)
+	if err := ws.Finish(); !verror.Is(err, verror.BadArg) {
+		t.Errorf("Error should be %v: got %v", verror.BadArg, err)
 	}
 
 	// Start a watch request with a resume marker that's too late.
@@ -484,8 +485,8 @@
 	ws = watchtesting.WatchRaw(rootPublicID, w.WatchRaw, req)
 
 	// The resume marker should be unknown.
-	if err := ws.Finish(); err != ErrUnknownResumeMarker {
-		t.Errorf("Unexpected error: %v", err)
+	if err := ws.Finish(); !verror.Is(err, verror.BadArg) {
+		t.Errorf("Error should be %v: got %v", verror.BadArg, err)
 	}
 }
 
diff --git a/services/store/raw/service.vdl.go b/services/store/raw/service.vdl.go
index 9e532c0..ca92493 100644
--- a/services/store/raw/service.vdl.go
+++ b/services/store/raw/service.vdl.go
@@ -18,7 +18,7 @@
 	_gen_ipc "veyron2/ipc"
 	_gen_naming "veyron2/naming"
 	_gen_rt "veyron2/rt"
-	_gen_vdl "veyron2/vdl"
+	_gen_vdlutil "veyron2/vdl/vdlutil"
 	_gen_wiretype "veyron2/wiretype"
 )
 
@@ -38,7 +38,7 @@
 	// 2) The entry is the store root immediately after the update.
 	IsRoot bool
 	// Value is value stored at this entry.
-	Value _gen_vdl.Any
+	Value _gen_vdlutil.Any
 	// Tags specify permissions on this entry.
 	Tags storage.TagList
 	// Dir is the implicit directory of this entry, and may contain references
@@ -224,10 +224,10 @@
 		case _gen_ipc.Client:
 			client = o
 		default:
-			return nil, _gen_vdl.ErrUnrecognizedOption
+			return nil, _gen_vdlutil.ErrUnrecognizedOption
 		}
 	default:
-		return nil, _gen_vdl.ErrTooManyOptionsToBind
+		return nil, _gen_vdlutil.ErrTooManyOptionsToBind
 	}
 	stub := &clientStubStore{client: client, name: name}
 
@@ -342,7 +342,7 @@
 		OutStream: 72,
 	}
 
-	result.TypeDefs = []_gen_vdl.Any{
+	result.TypeDefs = []_gen_vdlutil.Any{
 		_gen_wiretype.NamedPrimitiveType{Type: 0x32, Name: "byte", Tags: []string(nil)}, _gen_wiretype.SliceType{Elem: 0x41, Name: "veyron2/services/watch.ResumeMarker", Tags: []string(nil)}, _gen_wiretype.StructType{
 			[]_gen_wiretype.FieldType{
 				_gen_wiretype.FieldType{Type: 0x42, Name: "ResumeMarker"},
diff --git a/services/store/server/object.go b/services/store/server/object.go
index f29112e..dd33bb6 100644
--- a/services/store/server/object.go
+++ b/services/store/server/object.go
@@ -1,8 +1,6 @@
 package server
 
 import (
-	"errors"
-
 	"veyron/services/store/service"
 
 	"veyron2/ipc"
@@ -11,7 +9,8 @@
 	"veyron2/services/store"
 	"veyron2/services/watch"
 	"veyron2/storage"
-	"veyron2/vdl"
+	"veyron2/vdl/vdlutil"
+	"veyron2/verror"
 )
 
 type object struct {
@@ -21,8 +20,8 @@
 }
 
 var (
-	errNotAValue      = errors.New("not a storage.Value")
-	errNotAnAttribute = errors.New("not a storage.Attr")
+	errNotAValue      = verror.BadArgf("not a storage.Value")
+	errNotAnAttribute = verror.BadArgf("not a storage.Attr")
 
 	_ store.ObjectService = (*object)(nil)
 
@@ -65,7 +64,7 @@
 	}
 }
 
-func attrsFromAnyData(attrs []vdl.Any) ([]storage.Attr, error) {
+func attrsFromAnyData(attrs []vdlutil.Any) ([]storage.Attr, error) {
 	typedAttrs := make([]storage.Attr, len(attrs))
 	for i, x := range attrs {
 		a, ok := x.(storage.Attr)
@@ -77,8 +76,8 @@
 	return typedAttrs, nil
 }
 
-func attrsToAnyData(attrs []storage.Attr) []vdl.Any {
-	uattrs := make([]vdl.Any, len(attrs))
+func attrsToAnyData(attrs []storage.Attr) []vdlutil.Any {
+	uattrs := make([]vdlutil.Any, len(attrs))
 	for i, x := range attrs {
 		uattrs[i] = x
 	}
@@ -110,7 +109,7 @@
 }
 
 // Put modifies the value of the Object.
-func (o *object) Put(ctx ipc.ServerContext, tid store.TransactionID, val vdl.Any) (store.Stat, error) {
+func (o *object) Put(ctx ipc.ServerContext, tid store.TransactionID, val vdlutil.Any) (store.Stat, error) {
 	t, err := o.server.findTransaction(ctx, tid)
 	if err != nil {
 		return nullStat, err
@@ -134,7 +133,7 @@
 // SetAttr changes the attributes of the entry, such as permissions and
 // replication groups.  Attributes are associated with the value, not the
 // path.
-func (o *object) SetAttr(ctx ipc.ServerContext, tid store.TransactionID, attrs []vdl.Any) error {
+func (o *object) SetAttr(ctx ipc.ServerContext, tid store.TransactionID, attrs []vdlutil.Any) error {
 	t, err := o.server.findTransaction(ctx, tid)
 	if err != nil {
 		return err
diff --git a/services/store/server/server.go b/services/store/server/server.go
index 3afa161..8eb4478 100644
--- a/services/store/server/server.go
+++ b/services/store/server/server.go
@@ -2,7 +2,6 @@
 package server
 
 import (
-	"errors"
 	"reflect"
 	"strings"
 	"sync"
@@ -16,7 +15,7 @@
 	"veyron2/ipc"
 	"veyron2/security"
 	"veyron2/services/store"
-	"veyron2/vdl"
+	"veyron2/vdl/vdlutil"
 	"veyron2/verror"
 )
 
@@ -34,10 +33,10 @@
 
 	nullTransactionID store.TransactionID
 
-	errTransactionAlreadyExists = errors.New("transaction already exists")
-	errTransactionDoesNotExist  = errors.New("transaction does not exist")
+	errTransactionAlreadyExists = verror.Existsf("transaction already exists")
+	errTransactionDoesNotExist  = verror.NotFoundf("transaction does not exist")
 	// Transaction exists, but may not be used by the caller.
-	errPermissionDenied = errors.New("permission denied")
+	errPermissionDenied = verror.NotAuthorizedf("permission denied")
 )
 
 // Server stores the dictionary of all media items.  It has a scanner.Scanner
@@ -195,7 +194,7 @@
 }
 
 // CreateTransaction creates a transaction.
-func (s *Server) CreateTransaction(ctx ipc.ServerContext, id store.TransactionID, opts []vdl.Any) error {
+func (s *Server) CreateTransaction(ctx ipc.ServerContext, id store.TransactionID, opts []vdlutil.Any) error {
 	s.mutex.Lock()
 	defer s.mutex.Unlock()
 
diff --git a/services/store/server/server_test.go b/services/store/server/server_test.go
index 8a0ca7f..15fb5e0 100644
--- a/services/store/server/server_test.go
+++ b/services/store/server/server_test.go
@@ -9,7 +9,7 @@
 	"testing"
 	"time"
 
-	watchtesting "veyron/services/store/memstore/watch/testing"
+	watchtesting "veyron/services/store/memstore/testing"
 	"veyron/services/store/raw"
 
 	"veyron2/ipc"
diff --git a/services/store/testutil/store.go b/services/store/testutil/store.go
index 50feb22..9190f09 100644
--- a/services/store/testutil/store.go
+++ b/services/store/testutil/store.go
@@ -7,6 +7,7 @@
 	"testing"
 
 	istore "veyron/services/store/server"
+	_ "veyron/services/store/typeregistryhack"
 
 	"veyron2/ipc"
 	"veyron2/naming"
diff --git a/services/store/typeregistryhack/init.go b/services/store/typeregistryhack/init.go
index 84a8f00..72b5216 100644
--- a/services/store/typeregistryhack/init.go
+++ b/services/store/typeregistryhack/init.go
@@ -5,10 +5,7 @@
 package typeregistryhack
 
 import (
-	"veyron/services/mgmt/profile"
-	"veyron2/services/mgmt/application"
-
-	// Register boxes types
+	// Register boxes types.
 	"veyron/examples/boxes"
 	// Register mdb types.
 	_ "veyron/examples/storage/mdb/schema"
@@ -18,6 +15,12 @@
 	_ "veyron/examples/bank/schema"
 	// Register stfortune types.
 	_ "veyron/examples/stfortune/schema"
+	// Register profile types.
+	"veyron/services/mgmt/profile"
+	// Register application types.
+	"veyron2/services/mgmt/application"
+	// Register build types.
+	_ "veyron2/services/mgmt/build"
 
 	"veyron2/vom"
 )
diff --git a/services/wspr/wsprd/lib/stream.go b/services/wspr/wsprd/lib/stream.go
deleted file mode 100644
index 062115b..0000000
--- a/services/wspr/wsprd/lib/stream.go
+++ /dev/null
@@ -1,81 +0,0 @@
-// The set of streaming helper objects for wspr.
-
-package lib
-
-import (
-	"veyron2/ipc"
-)
-
-// An interface for an asynchronous sender.
-type sender interface {
-	// Similar to ipc.Stream.Send, expect that instead of
-	// returning an error, w.sendError will be called.
-	Send(item interface{}, w clientWriter)
-}
-
-// A message that will be passed to the writeLoop function that will
-// eventually write the message out to the stream.
-type streamMessage struct {
-	// The data to put on the stream.
-	data interface{}
-	// The client writer that will be used to send errors.
-	w clientWriter
-}
-
-// A stream that will eventually write messages to the underlying stream.
-// It isn't initialized with a stream, but rather a chan that will eventually
-// provide a stream, so that it can accept sends before the underlying stream
-// has been set up.
-type queueingStream chan *streamMessage
-
-// Creates and returns a queueing stream that will starting writing to the
-// stream provided by the ready channel.  It is expected that ready will only
-// provide a single stream.
-// TODO(bjornick): allow for ready to pass an error if the stream had any issues
-// setting up.
-func startQueueingStream(ready chan ipc.Stream) queueingStream {
-	s := make(queueingStream, 100)
-	go s.writeLoop(ready)
-	return s
-}
-
-func (q queueingStream) Send(item interface{}, w clientWriter) {
-	// TODO(bjornick): Reject the message if the queue is too long.
-	message := streamMessage{data: item, w: w}
-	q <- &message
-}
-
-func (q queueingStream) Close() error {
-	close(q)
-	return nil
-}
-
-func (q queueingStream) writeLoop(ready chan ipc.Stream) {
-	stream := <-ready
-	for value, ok := <-q; ok; value, ok = <-q {
-		if !ok {
-			break
-		}
-		if err := stream.Send(value.data); err != nil {
-			value.w.sendError(err)
-		}
-	}
-
-	// If the stream is on the client side, then also close the stream.
-	if call, ok := stream.(ipc.Call); ok {
-		call.CloseSend()
-	}
-}
-
-// A simple struct that wraps a stream with the sender api.  It
-// will write to the stream synchronously.  Any error will still
-// be written to clientWriter.
-type senderWrapper struct {
-	stream ipc.Stream
-}
-
-func (s senderWrapper) Send(item interface{}, w clientWriter) {
-	if err := s.stream.Send(item); err != nil {
-		w.sendError(err)
-	}
-}
diff --git a/services/wsprd/ipc/client/stream.go b/services/wsprd/ipc/client/stream.go
new file mode 100644
index 0000000..4237f8f
--- /dev/null
+++ b/services/wsprd/ipc/client/stream.go
@@ -0,0 +1,62 @@
+// A client stream helper.
+
+package client
+
+import (
+	"veyron/services/wsprd/lib"
+	"veyron2/ipc"
+)
+
+// A message that will be passed to the writeLoop function that will
+// eventually write the message out to the stream.
+type streamMessage struct {
+	// The data to put on the stream.
+	data interface{}
+	// The client writer that will be used to send errors.
+	w lib.ClientWriter
+}
+
+// A stream that will eventually write messages to the underlying stream.
+// It isn't initialized with a stream, but rather a chan that will eventually
+// provide a stream, so that it can accept sends before the underlying stream
+// has been set up.
+type QueueingStream chan *streamMessage
+
+// Creates and returns a queueing stream that will starting writing to the
+// stream provided by the ready channel.  It is expected that ready will only
+// provide a single stream.
+// TODO(bjornick): allow for ready to pass an error if the stream had any issues
+// setting up.
+func StartQueueingStream(ready chan ipc.Stream) QueueingStream {
+	s := make(QueueingStream, 100)
+	go s.writeLoop(ready)
+	return s
+}
+
+func (q QueueingStream) Send(item interface{}, w lib.ClientWriter) {
+	// TODO(bjornick): Reject the message if the queue is too long.
+	message := streamMessage{data: item, w: w}
+	q <- &message
+}
+
+func (q QueueingStream) Close() error {
+	close(q)
+	return nil
+}
+
+func (q QueueingStream) writeLoop(ready chan ipc.Stream) {
+	stream := <-ready
+	for value, ok := <-q; ok; value, ok = <-q {
+		if !ok {
+			break
+		}
+		if err := stream.Send(value.data); err != nil {
+			value.w.Error(err)
+		}
+	}
+
+	// If the stream is on the client side, then also close the stream.
+	if call, ok := stream.(ipc.Call); ok {
+		call.CloseSend()
+	}
+}
diff --git a/services/wspr/wsprd/lib/dispatcher.go b/services/wsprd/ipc/server/dispatcher.go
similarity index 97%
rename from services/wspr/wsprd/lib/dispatcher.go
rename to services/wsprd/ipc/server/dispatcher.go
index 97b4aab..7c73701 100644
--- a/services/wspr/wsprd/lib/dispatcher.go
+++ b/services/wsprd/ipc/server/dispatcher.go
@@ -1,4 +1,4 @@
-package lib
+package server
 
 import (
 	"veyron2/ipc"
diff --git a/services/wspr/wsprd/lib/invoker.go b/services/wsprd/ipc/server/invoker.go
similarity index 96%
rename from services/wspr/wsprd/lib/invoker.go
rename to services/wsprd/ipc/server/invoker.go
index a385d4d..aabafe8 100644
--- a/services/wspr/wsprd/lib/invoker.go
+++ b/services/wsprd/ipc/server/invoker.go
@@ -1,4 +1,4 @@
-package lib
+package server
 
 import (
 	"veyron2/ipc"
@@ -24,7 +24,7 @@
 	predefinedInvokers := make(map[string]ipc.Invoker)
 
 	// Special handling for predefined "signature" method
-	predefinedInvokers[signatureMethodName] = newSignatureInvoker(sig)
+	predefinedInvokers["Signature"] = newSignatureInvoker(sig)
 
 	i := &invoker{sig, invokeFunc, predefinedInvokers}
 	return i, nil
diff --git a/services/wspr/wsprd/lib/server.go b/services/wsprd/ipc/server/server.go
similarity index 65%
rename from services/wspr/wsprd/lib/server.go
rename to services/wsprd/ipc/server/server.go
index 8b95ea2..8b79b15 100644
--- a/services/wspr/wsprd/lib/server.go
+++ b/services/wsprd/ipc/server/server.go
@@ -1,6 +1,6 @@
 // An implementation of a server for WSPR
 
-package lib
+package server
 
 import (
 	"bytes"
@@ -8,17 +8,19 @@
 	"fmt"
 	"sync"
 
+	"veyron/services/wsprd/ipc/stream"
+	"veyron/services/wsprd/lib"
+	"veyron/services/wsprd/signature"
 	"veyron2"
 	"veyron2/ipc"
 	"veyron2/security"
 	"veyron2/verror"
 	"veyron2/vlog"
-	"veyron2/vom"
 )
 
-type flow struct {
-	id     int64
-	writer clientWriter
+type Flow struct {
+	ID     int64
+	Writer lib.ClientWriter
 }
 
 // A request from the proxy to javascript to handle an RPC
@@ -35,17 +37,23 @@
 	Name   string
 }
 
-type serverHelper interface {
-	createNewFlow(server *server, sender sender) *flow
-
-	cleanupFlow(id int64)
-
-	getLogger() vlog.Logger
-
-	rt() veyron2.Runtime
+// The response from the javascript server to the proxy.
+type serverRPCReply struct {
+	Results []interface{}
+	Err     *verror.Standard
 }
 
-type server struct {
+type ServerHelper interface {
+	CreateNewFlow(server *Server, sender stream.Sender) *Flow
+
+	CleanupFlow(id int64)
+
+	GetLogger() vlog.Logger
+
+	RT() veyron2.Runtime
+}
+
+type Server struct {
 	sync.Mutex
 
 	// The server that handles the ipc layer.  Listen on this server is
@@ -61,7 +69,7 @@
 
 	// The server id.
 	id     uint64
-	helper serverHelper
+	helper ServerHelper
 
 	// The proxy to listen through.
 	veyronProxy string
@@ -70,15 +78,15 @@
 	outstandingServerRequests map[int64]chan *serverRPCReply
 }
 
-func newServer(id uint64, veyronProxy string, helper serverHelper) (*server, error) {
-	server := &server{
+func NewServer(id uint64, veyronProxy string, helper ServerHelper) (*Server, error) {
+	server := &Server{
 		id:                        id,
 		helper:                    helper,
 		veyronProxy:               veyronProxy,
 		outstandingServerRequests: make(map[int64]chan *serverRPCReply),
 	}
 	var err error
-	if server.server, err = helper.rt().NewServer(); err != nil {
+	if server.server, err = helper.RT().NewServer(); err != nil {
 		return nil, err
 	}
 	return server, nil
@@ -88,12 +96,12 @@
 // communicate the result back via a channel to the caller
 type remoteInvokeFunc func(methodName string, args []interface{}, call ipc.ServerCall) <-chan *serverRPCReply
 
-func (s *server) createRemoteInvokerFunc() remoteInvokeFunc {
+func (s *Server) createRemoteInvokerFunc() remoteInvokeFunc {
 	return func(methodName string, args []interface{}, call ipc.ServerCall) <-chan *serverRPCReply {
-		flow := s.helper.createNewFlow(s, senderWrapper{stream: call})
+		flow := s.helper.CreateNewFlow(s, senderWrapper{stream: call})
 		replyChan := make(chan *serverRPCReply, 1)
 		s.Lock()
-		s.outstandingServerRequests[flow.id] = replyChan
+		s.outstandingServerRequests[flow.ID] = replyChan
 		s.Unlock()
 		context := serverRPCRequestContext{
 			Suffix: call.Suffix(),
@@ -102,13 +110,12 @@
 		// Send a invocation request to JavaScript
 		message := serverRPCRequest{
 			ServerId: s.id,
-			Method:   lowercaseFirstCharacter(methodName),
+			Method:   lib.LowercaseFirstCharacter(methodName),
 			Args:     args,
 			Context:  context,
 		}
 
-		data := response{Type: responseServerRequest, Message: message}
-		if err := vom.ObjToJSON(flow.writer, vom.ValueOf(data)); err != nil {
+		if err := flow.Writer.Send(lib.ResponseServerRequest, message); err != nil {
 			// Error in marshaling, pass the error through the channel immediately
 			replyChan <- &serverRPCReply{nil,
 				&verror.Standard{
@@ -117,49 +124,32 @@
 			}
 			return replyChan
 		}
-		if err := flow.writer.FinishMessage(); err != nil {
-			replyChan <- &serverRPCReply{nil,
-				&verror.Standard{
-					ID:  verror.Internal,
-					Msg: fmt.Sprintf("WSPR: error finishing message: %v", err)},
-			}
-			return replyChan
-		}
 
-		s.helper.getLogger().VI(3).Infof("request received to call method %q on "+
+		s.helper.GetLogger().VI(3).Infof("request received to call method %q on "+
 			"JavaScript server with args %v, MessageId %d was assigned.",
-			methodName, args, flow.id)
+			methodName, args, flow.ID)
 
-		go proxyStream(call, flow.writer, s.helper.getLogger())
+		go proxyStream(call, flow.Writer, s.helper.GetLogger())
 		return replyChan
 	}
 }
 
-func proxyStream(stream ipc.Stream, w clientWriter, logger vlog.Logger) {
+func proxyStream(stream ipc.Stream, w lib.ClientWriter, logger vlog.Logger) {
 	var item interface{}
 	for err := stream.Recv(&item); err == nil; err = stream.Recv(&item) {
-		data := response{Type: responseStream, Message: item}
-		if err := vom.ObjToJSON(w, vom.ValueOf(data)); err != nil {
-			w.sendError(verror.Internalf("error marshalling stream: %v:", err))
-			return
-		}
-		if err := w.FinishMessage(); err != nil {
-			logger.Error("WSPR: error finishing message", err)
+		if err := w.Send(lib.ResponseStream, item); err != nil {
+			w.Error(verror.Internalf("error marshalling stream: %v:", err))
 			return
 		}
 	}
 
-	if err := vom.ObjToJSON(w, vom.ValueOf(response{Type: responseStreamClose})); err != nil {
-		w.sendError(verror.Internalf("error closing stream: %v:", err))
-		return
-	}
-	if err := w.FinishMessage(); err != nil {
-		logger.Error("WSPR: error finishing message", err)
+	if err := w.Send(lib.ResponseStreamClose, nil); err != nil {
+		w.Error(verror.Internalf("error closing stream: %v:", err))
 		return
 	}
 }
 
-func (s *server) serve(name string, sig JSONServiceSignature) (string, error) {
+func (s *Server) Serve(name string, sig signature.JSONServiceSignature) (string, error) {
 	s.Lock()
 	defer s.Unlock()
 
@@ -192,17 +182,17 @@
 	if err := s.server.Serve(name, s.dispatcher); err != nil {
 		return "", err
 	}
-	s.helper.getLogger().VI(1).Infof("endpoint is %s", s.endpoint)
+	s.helper.GetLogger().VI(1).Infof("endpoint is %s", s.endpoint)
 	return s.endpoint, nil
 }
 
-func (s *server) handleServerResponse(id int64, data string) {
+func (s *Server) HandleServerResponse(id int64, data string) {
 	s.Lock()
 	ch := s.outstandingServerRequests[id]
 	delete(s.outstandingServerRequests, id)
 	s.Unlock()
 	if ch == nil {
-		s.helper.getLogger().Errorf("unexpected result from JavaScript. No channel "+
+		s.helper.GetLogger().Errorf("unexpected result from JavaScript. No channel "+
 			"for MessageId: %d exists. Ignoring the results.", id)
 		//Ignore unknown responses that don't belong to any channel
 		return
@@ -218,13 +208,13 @@
 		serverReply = serverRPCReply{nil, &err}
 	}
 
-	s.helper.getLogger().VI(3).Infof("response received from JavaScript server for "+
+	s.helper.GetLogger().VI(3).Infof("response received from JavaScript server for "+
 		"MessageId %d with result %v", id, serverReply)
-	s.helper.cleanupFlow(id)
+	s.helper.CleanupFlow(id)
 	ch <- &serverReply
 }
 
-func (s *server) Stop() {
+func (s *Server) Stop() {
 	result := serverRPCReply{
 		Results: []interface{}{nil},
 		Err: &verror.Standard{
diff --git a/services/wspr/wsprd/lib/signature_invoker.go b/services/wsprd/ipc/server/signature_invoker.go
similarity index 97%
rename from services/wspr/wsprd/lib/signature_invoker.go
rename to services/wsprd/ipc/server/signature_invoker.go
index 56026e2..6384510 100644
--- a/services/wspr/wsprd/lib/signature_invoker.go
+++ b/services/wsprd/ipc/server/signature_invoker.go
@@ -1,4 +1,4 @@
-package lib
+package server
 
 import (
 	"veyron2/ipc"
diff --git a/services/wsprd/ipc/server/stream.go b/services/wsprd/ipc/server/stream.go
new file mode 100644
index 0000000..03b39e2
--- /dev/null
+++ b/services/wsprd/ipc/server/stream.go
@@ -0,0 +1,19 @@
+package server
+
+import (
+	"veyron/services/wsprd/lib"
+	"veyron2/ipc"
+)
+
+// A simple struct that wraps a stream with the sender api.  It
+// will write to the stream synchronously.  Any error will still
+// be written to clientWriter.
+type senderWrapper struct {
+	stream ipc.Stream
+}
+
+func (s senderWrapper) Send(item interface{}, w lib.ClientWriter) {
+	if err := s.stream.Send(item); err != nil {
+		w.Error(err)
+	}
+}
diff --git a/services/wsprd/ipc/stream/stream.go b/services/wsprd/ipc/stream/stream.go
new file mode 100644
index 0000000..57ef1b3
--- /dev/null
+++ b/services/wsprd/ipc/stream/stream.go
@@ -0,0 +1,14 @@
+// The set of streaming helper objects for wspr.
+
+package stream
+
+import (
+	"veyron/services/wsprd/lib"
+)
+
+// An interface for an asynchronous sender.
+type Sender interface {
+	// Similar to ipc.Stream.Send, expect that instead of
+	// returning an error, w.sendError will be called.
+	Send(item interface{}, w lib.ClientWriter)
+}
diff --git a/services/wspr/wsprd/lib/cache.go b/services/wsprd/lib/cache.go
similarity index 100%
rename from services/wspr/wsprd/lib/cache.go
rename to services/wsprd/lib/cache.go
diff --git a/services/wspr/wsprd/lib/case.go b/services/wsprd/lib/case.go
similarity index 67%
rename from services/wspr/wsprd/lib/case.go
rename to services/wsprd/lib/case.go
index b440561..e6ec0d0 100644
--- a/services/wspr/wsprd/lib/case.go
+++ b/services/wsprd/lib/case.go
@@ -2,14 +2,14 @@
 
 import "unicode"
 
-func lowercaseFirstCharacter(s string) string {
+func LowercaseFirstCharacter(s string) string {
 	for _, r := range s {
 		return string(unicode.ToLower(r)) + s[1:]
 	}
 	return ""
 }
 
-func uppercaseFirstCharacter(s string) string {
+func UppercaseFirstCharacter(s string) string {
 	for _, r := range s {
 		return string(unicode.ToUpper(r)) + s[1:]
 	}
diff --git a/services/wspr/wsprd/lib/remove_this.go b/services/wsprd/lib/remove_this.go
similarity index 100%
rename from services/wspr/wsprd/lib/remove_this.go
rename to services/wsprd/lib/remove_this.go
diff --git a/services/wspr/wsprd/lib/signature_manager.go b/services/wsprd/lib/signature_manager.go
similarity index 84%
rename from services/wspr/wsprd/lib/signature_manager.go
rename to services/wsprd/lib/signature_manager.go
index 642dfe8..18a76a8 100644
--- a/services/wspr/wsprd/lib/signature_manager.go
+++ b/services/wsprd/lib/signature_manager.go
@@ -8,9 +8,8 @@
 	"veyron2/ipc"
 )
 
-// NewSignatureManager creates and initialized a new Signature Manager
-func newSignatureManager() *signatureManager {
-	return &signatureManager{cache: make(map[string]*cacheEntry)}
+type SignatureManager interface {
+	Signature(ctx context.T, name string, client ipc.Client) (*ipc.ServiceSignature, error)
 }
 
 // signatureManager can be used to discover the signature of a remote service
@@ -24,6 +23,11 @@
 	cache map[string]*cacheEntry
 }
 
+// NewSignatureManager creates and initialized a new Signature Manager
+func NewSignatureManager() SignatureManager {
+	return &signatureManager{cache: make(map[string]*cacheEntry)}
+}
+
 const (
 	// ttl from the last-accessed time.
 	ttl = time.Duration(time.Hour)
@@ -41,7 +45,7 @@
 
 // signature uses the given client to fetch the signature for the given service name.
 // It locks until it fetches the service signature from the remote server, if not a cache hit.
-func (sm *signatureManager) signature(ctx context.T, name string, client ipc.Client) (*ipc.ServiceSignature, error) {
+func (sm *signatureManager) Signature(ctx context.T, name string, client ipc.Client) (*ipc.ServiceSignature, error) {
 	sm.Lock()
 	defer sm.Unlock()
 
@@ -51,7 +55,7 @@
 	}
 
 	// cache expired or not found, fetch it from the remote server
-	signatureCall, err := client.StartCall(ctx, name, signatureMethodName, []interface{}{})
+	signatureCall, err := client.StartCall(ctx, name, "Signature", []interface{}{})
 	if err != nil {
 		return nil, err
 	}
diff --git a/services/wspr/wsprd/lib/signature_manager_test.go b/services/wsprd/lib/signature_manager_test.go
similarity index 79%
rename from services/wspr/wsprd/lib/signature_manager_test.go
rename to services/wsprd/lib/signature_manager_test.go
index 0271fbd..f0caf01 100644
--- a/services/wspr/wsprd/lib/signature_manager_test.go
+++ b/services/wsprd/lib/signature_manager_test.go
@@ -7,7 +7,7 @@
 	mocks_ipc "veyron/runtimes/google/testing/mocks/ipc"
 	"veyron2/ipc"
 	"veyron2/rt"
-	"veyron2/vdl"
+	"veyron2/vdl/vdlutil"
 	"veyron2/wiretype"
 )
 
@@ -15,12 +15,16 @@
 	name = "/veyron/name"
 )
 
+func init() {
+	rt.Init()
+}
+
 func expectedSignature() ipc.ServiceSignature {
 	return ipc.ServiceSignature{
 		Methods: make(map[string]ipc.MethodSignature),
-		TypeDefs: []vdl.Any{
+		TypeDefs: []vdlutil.Any{
 			wiretype.NamedPrimitiveType{
-				Name: "veyron2/vdl.AnyData",
+				Name: "veyron2/vdlutil.AnyData",
 				Type: wiretype.TypeIDInterface,
 			},
 		},
@@ -30,7 +34,7 @@
 func client() *mocks_ipc.SimpleMockClient {
 	return mocks_ipc.NewSimpleClient(
 		map[string][]interface{}{
-			signatureMethodName: []interface{}{expectedSignature(), nil},
+			"Signature": []interface{}{expectedSignature(), nil},
 		},
 	)
 }
@@ -75,8 +79,8 @@
 }
 
 func TestFetching(t *testing.T) {
-	sm := newSignatureManager()
-	got, err := sm.signature(rt.R().NewContext(), name, client())
+	sm := NewSignatureManager()
+	got, err := sm.Signature(rt.R().NewContext(), name, client())
 	if err != nil {
 		t.Errorf(`Did not expect an error but got %v`, err)
 		return
@@ -86,8 +90,8 @@
 }
 
 func TestThatCachedAfterFetching(t *testing.T) {
-	sm := newSignatureManager()
-	sig, _ := sm.signature(rt.R().NewContext(), name, client())
+	sm := NewSignatureManager().(*signatureManager)
+	sig, _ := sm.Signature(rt.R().NewContext(), name, client())
 	cache, ok := sm.cache[name]
 	if !ok {
 		t.Errorf(`Signature manager did not cache the results`)
@@ -98,30 +102,30 @@
 
 func TestThatCacheIsUsed(t *testing.T) {
 	client := client()
-	sm := newSignatureManager()
+	sm := NewSignatureManager()
 
 	// call twice
-	sm.signature(rt.R().NewContext(), name, client)
-	sm.signature(rt.R().NewContext(), name, client)
+	sm.Signature(rt.R().NewContext(), name, client)
+	sm.Signature(rt.R().NewContext(), name, client)
 
 	// expect number of calls to Signature method of client to still be 1 since cache
 	// should have been used despite the second call
-	if client.TimesCalled(signatureMethodName) != 1 {
+	if client.TimesCalled("Signature") != 1 {
 		t.Errorf("Signature cache was not used for the second call")
 	}
 }
 
 func TestThatLastAccessedGetUpdated(t *testing.T) {
 	client := client()
-	sm := newSignatureManager()
-	sm.signature(rt.R().NewContext(), name, client)
+	sm := NewSignatureManager().(*signatureManager)
+	sm.Signature(rt.R().NewContext(), name, client)
 	// make last accessed be in the past to account for the fact that
 	// two consecutive calls to time.Now() can return identical values.
 	sm.cache[name].lastAccessed = sm.cache[name].lastAccessed.Add(-ttl / 2)
 	prevAccess := sm.cache[name].lastAccessed
 
 	// access again
-	sm.signature(rt.R().NewContext(), name, client)
+	sm.Signature(rt.R().NewContext(), name, client)
 	newAccess := sm.cache[name].lastAccessed
 
 	if !newAccess.After(prevAccess) {
@@ -131,17 +135,17 @@
 
 func TestThatTTLExpires(t *testing.T) {
 	client := client()
-	sm := newSignatureManager()
-	sm.signature(rt.R().NewContext(), name, client)
+	sm := NewSignatureManager().(*signatureManager)
+	sm.Signature(rt.R().NewContext(), name, client)
 
 	// make last accessed go over the ttl
 	sm.cache[name].lastAccessed = sm.cache[name].lastAccessed.Add(-2 * ttl)
 
 	// make a second call
-	sm.signature(rt.R().NewContext(), name, client)
+	sm.Signature(rt.R().NewContext(), name, client)
 
 	// expect number of calls to Signature method of client to be 2 since cache should have expired
-	if client.TimesCalled(signatureMethodName) != 2 {
+	if client.TimesCalled("Signature") != 2 {
 		t.Errorf("Cache was still used but TTL had passed. It should have been fetched again")
 	}
 }
diff --git a/services/wsprd/lib/writer.go b/services/wsprd/lib/writer.go
new file mode 100644
index 0000000..ae18996
--- /dev/null
+++ b/services/wsprd/lib/writer.go
@@ -0,0 +1,19 @@
+package lib
+
+type ResponseType int
+
+const (
+	ResponseFinal         ResponseType = 0
+	ResponseStream                     = 1
+	ResponseError                      = 2
+	ResponseServerRequest              = 3
+	ResponseStreamClose                = 4
+)
+
+// This is basically an io.Writer interface, that allows passing error message
+// strings.  This is how the proxy will talk to the javascript/java clients.
+type ClientWriter interface {
+	Send(messageType ResponseType, data interface{}) error
+
+	Error(err error)
+}
diff --git a/services/wspr/wsprd/lib/identity.go b/services/wsprd/security/identity.go
similarity index 99%
rename from services/wspr/wsprd/lib/identity.go
rename to services/wsprd/security/identity.go
index 823d4d8..f72ad24 100644
--- a/services/wspr/wsprd/lib/identity.go
+++ b/services/wsprd/security/identity.go
@@ -10,8 +10,7 @@
 // information, but not the private keys for each app.
 // TODO(bjornick,ataly,ashankar): Have all the accounts share the same private key which will be stored
 // in a TPM, so no private key gets serialized to disk.
-
-package lib
+package security
 
 import (
 	"crypto/ecdsa"
diff --git a/services/wspr/wsprd/lib/identity_test.go b/services/wsprd/security/identity_test.go
similarity index 99%
rename from services/wspr/wsprd/lib/identity_test.go
rename to services/wsprd/security/identity_test.go
index b7ccbad..9b89999 100644
--- a/services/wspr/wsprd/lib/identity_test.go
+++ b/services/wsprd/security/identity_test.go
@@ -1,4 +1,4 @@
-package lib
+package security
 
 import (
 	"bytes"
diff --git a/services/wspr/wsprd/lib/signature.go b/services/wsprd/signature/signature.go
similarity index 86%
rename from services/wspr/wsprd/lib/signature.go
rename to services/wsprd/signature/signature.go
index a0a60e0..0185658 100644
--- a/services/wspr/wsprd/lib/signature.go
+++ b/services/wsprd/signature/signature.go
@@ -1,19 +1,15 @@
-package lib
+package signature
 
 import (
+	"veyron/services/wsprd/lib"
 	"veyron2/ipc"
-	"veyron2/vdl"
+	"veyron2/vdl/vdlutil"
 	"veyron2/wiretype"
 )
 
-const (
-	// agreed-upon name of the signature method that's available on all services
-	signatureMethodName = "Signature"
-)
-
 var (
 	anydataType = wiretype.NamedPrimitiveType{
-		Name: "veyron2/vdl.AnyData",
+		Name: "veyron2/vdlutil.AnyData",
 		Type: wiretype.TypeIDInterface,
 	}
 	errType = wiretype.NamedPrimitiveType{
@@ -49,7 +45,7 @@
 			jmethSig.InArgs[i] = inarg.Name
 		}
 
-		jsig[lowercaseFirstCharacter(name)] = jmethSig
+		jsig[lib.LowercaseFirstCharacter(name)] = jmethSig
 	}
 
 	return jsig
@@ -88,10 +84,10 @@
 			ms.OutStream = anydataTypeID
 		}
 
-		ss.Methods[uppercaseFirstCharacter(name)] = ms
+		ss.Methods[lib.UppercaseFirstCharacter(name)] = ms
 	}
 
-	ss.TypeDefs = []vdl.Any{anydataType, errType}
+	ss.TypeDefs = []vdlutil.Any{anydataType, errType}
 
 	return ss, nil
 }
diff --git a/services/wspr/wsprd/lib/signature_test.go b/services/wsprd/signature/signature_test.go
similarity index 95%
rename from services/wspr/wsprd/lib/signature_test.go
rename to services/wsprd/signature/signature_test.go
index 70f5803..250acf5 100644
--- a/services/wspr/wsprd/lib/signature_test.go
+++ b/services/wsprd/signature/signature_test.go
@@ -1,11 +1,11 @@
-package lib
+package signature
 
 import (
 	"reflect"
 	"testing"
 
 	"veyron2/ipc"
-	"veyron2/vdl"
+	"veyron2/vdl/vdlutil"
 	"veyron2/wiretype"
 )
 
@@ -44,7 +44,7 @@
 				OutStream: wiretype.TypeIDString,
 			},
 		},
-		TypeDefs: []vdl.Any{
+		TypeDefs: []vdlutil.Any{
 			anydataType,
 			errType,
 		},
@@ -105,7 +105,7 @@
 				OutStream: anydataTypeID,
 			},
 		},
-		TypeDefs: []vdl.Any{
+		TypeDefs: []vdlutil.Any{
 			anydataType,
 			errType,
 		},
diff --git a/services/wspr/wsprd/wspr.go b/services/wsprd/wspr.go
similarity index 81%
rename from services/wspr/wsprd/wspr.go
rename to services/wsprd/wspr.go
index ef4977d..4a01ea0 100644
--- a/services/wspr/wsprd/wspr.go
+++ b/services/wsprd/wspr.go
@@ -4,7 +4,7 @@
 	"flag"
 
 	"veyron/lib/signals"
-	"veyron/services/wspr/wsprd/lib"
+	"veyron/services/wsprd/wspr"
 )
 
 func main() {
@@ -12,7 +12,7 @@
 	veyronProxy := flag.String("vproxy", "", "The endpoint for the veyron proxy to publish on. This must be set")
 	flag.Parse()
 
-	proxy := lib.NewWSPR(*port, *veyronProxy)
+	proxy := wspr.NewWSPR(*port, *veyronProxy)
 	defer proxy.Shutdown()
 	go func() {
 		proxy.Run()
diff --git a/services/wspr/wsprd/lib/writer.go b/services/wsprd/wspr/writer.go
similarity index 60%
rename from services/wspr/wsprd/lib/writer.go
rename to services/wsprd/wspr/writer.go
index 11fd44c..4c85ea0 100644
--- a/services/wspr/wsprd/lib/writer.go
+++ b/services/wsprd/wspr/writer.go
@@ -1,10 +1,13 @@
-package lib
+package wspr
 
 import (
 	"bytes"
 	"fmt"
 	"path/filepath"
 	"runtime"
+
+	"veyron/services/wsprd/lib"
+
 	"veyron2/verror"
 	"veyron2/vlog"
 	"veyron2/vom"
@@ -12,30 +15,41 @@
 	"github.com/gorilla/websocket"
 )
 
-// This is basically an io.Writer interface, that allows passing error message
-// strings.  This is how the proxy will talk to the javascript/java clients.
-type clientWriter interface {
-	Write(p []byte) (int, error)
-
-	sendError(err error)
-
-	FinishMessage() error
+// Wraps a response to the proxy client and adds a message type.
+type response struct {
+	Type    lib.ResponseType
+	Message interface{}
 }
 
 // Implements clientWriter interface for sending messages over websockets.
 type websocketWriter struct {
 	ws     *websocket.Conn
-	buf    bytes.Buffer
 	logger vlog.Logger
 	id     int64
 }
 
-func (w *websocketWriter) Write(p []byte) (int, error) {
-	w.buf.Write(p)
-	return len(p), nil
+func (w *websocketWriter) Send(messageType lib.ResponseType, data interface{}) error {
+	var buf bytes.Buffer
+	if err := vom.ObjToJSON(&buf, vom.ValueOf(response{Type: messageType, Message: data})); err != nil {
+		w.logger.Error("Failed to marshal with", err)
+		return err
+	}
+
+	wc, err := w.ws.NextWriter(websocket.TextMessage)
+	if err != nil {
+		w.logger.Error("Failed to get a writer from the websocket", err)
+		return err
+	}
+	if err := vom.ObjToJSON(wc, vom.ValueOf(websocketMessage{Id: w.id, Data: buf.String()})); err != nil {
+		w.logger.Error("Failed to write the message", err)
+		return err
+	}
+	wc.Close()
+
+	return nil
 }
 
-func (w *websocketWriter) sendError(err error) {
+func (w *websocketWriter) Error(err error) {
 	verr := verror.ToStandard(err)
 
 	// Also log the error but write internal errors at a more severe log level
@@ -56,26 +70,5 @@
 		Msg: verr.Error(),
 	}
 
-	w.buf.Reset()
-	if err := vom.ObjToJSON(&w.buf, vom.ValueOf(response{Type: responseError, Message: errMsg})); err != nil {
-		w.logger.Error("Failed to marshal with", err)
-		return
-	}
-	if err := w.FinishMessage(); err != nil {
-		w.logger.Error("WSPR: error finishing message: ", err)
-		return
-	}
-}
-
-func (w *websocketWriter) FinishMessage() error {
-	wc, err := w.ws.NextWriter(websocket.TextMessage)
-	if err != nil {
-		return err
-	}
-	if err := vom.ObjToJSON(wc, vom.ValueOf(websocketMessage{Id: w.id, Data: w.buf.String()})); err != nil {
-		return err
-	}
-	wc.Close()
-	w.buf.Reset()
-	return nil
+	w.Send(lib.ResponseError, errMsg)
 }
diff --git a/services/wspr/wsprd/lib/wspr.go b/services/wsprd/wspr/wspr.go
similarity index 80%
rename from services/wspr/wsprd/lib/wspr.go
rename to services/wsprd/wspr/wspr.go
index b48a310..81e31e9 100644
--- a/services/wspr/wsprd/lib/wspr.go
+++ b/services/wsprd/wspr/wspr.go
@@ -13,7 +13,7 @@
 //   "IsStreaming" : true/false
 // }
 //
-package lib
+package wspr
 
 import (
 	"bytes"
@@ -31,6 +31,11 @@
 	"sync"
 	"time"
 
+	"veyron/services/wsprd/ipc/client"
+	"veyron/services/wsprd/ipc/server"
+	"veyron/services/wsprd/ipc/stream"
+	"veyron/services/wsprd/lib"
+	"veyron/services/wsprd/signature"
 	"veyron2"
 	"veyron2/ipc"
 	"veyron2/rt"
@@ -55,29 +60,13 @@
 
 type WSPR struct {
 	tlsCert       *tls.Certificate
-	clientCache   *ClientCache
+	clientCache   *lib.ClientCache
 	rt            veyron2.Runtime
 	logger        vlog.Logger
 	port          int
 	veyronProxyEP string
 }
 
-type responseType int
-
-const (
-	responseFinal         responseType = 0
-	responseStream                     = 1
-	responseError                      = 2
-	responseServerRequest              = 3
-	responseStreamClose                = 4
-)
-
-// Wraps a response to the proxy client and adds a message type.
-type response struct {
-	Type    responseType
-	Message interface{}
-}
-
 var logger vlog.Logger
 
 // The type of message sent by the JS client to the wspr.
@@ -139,17 +128,11 @@
 type serveRequest struct {
 	Name     string
 	ServerId uint64
-	Service  JSONServiceSignature
-}
-
-// The response from the javascript server to the proxy.
-type serverRPCReply struct {
-	Results []interface{}
-	Err     *verror.Standard
+	Service  signature.JSONServiceSignature
 }
 
 // finishCall waits for the call to finish and write out the response to w.
-func (wsp *websocketPipe) finishCall(w clientWriter, clientCall ipc.Call, msg *veyronRPC) {
+func (wsp *websocketPipe) finishCall(w lib.ClientWriter, clientCall ipc.Call, msg *veyronRPC) {
 	if msg.IsStreaming {
 		for {
 			var item interface{}
@@ -157,24 +140,16 @@
 				if err == io.EOF {
 					break
 				}
-				w.sendError(err) // Send streaming error as is
+				w.Error(err) // Send streaming error as is
 				return
 			}
-			data := &response{Type: responseStream, Message: item}
-			if err := vom.ObjToJSON(w, vom.ValueOf(data)); err != nil {
-				w.sendError(verror.Internalf("unable to marshal: %v", item))
-				continue
-			}
-			if err := w.FinishMessage(); err != nil {
-				wsp.ctx.logger.Error("WSPR: error finishing message: ", err)
+			if err := w.Send(lib.ResponseStream, item); err != nil {
+				w.Error(verror.Internalf("unable to marshal: %v", item))
 			}
 		}
 
-		if err := vom.ObjToJSON(w, vom.ValueOf(response{Type: responseStreamClose})); err != nil {
-			w.sendError(verror.Internalf("unable to marshal close stream message"))
-		}
-		if err := w.FinishMessage(); err != nil {
-			wsp.ctx.logger.Error("WSPR: error finishing message: ", err)
+		if err := w.Send(lib.ResponseStreamClose, nil); err != nil {
+			w.Error(verror.Internalf("unable to marshal close stream message"))
 		}
 	}
 
@@ -186,30 +161,23 @@
 	}
 	if err := clientCall.Finish(resultptrs...); err != nil {
 		// return the call system error as is
-		w.sendError(err)
+		w.Error(err)
 		return
 	}
 	// for now we assume last out argument is always error
 	if len(results) < 1 {
-		w.sendError(verror.Internalf("client call did not return any results"))
+		w.Error(verror.Internalf("client call did not return any results"))
 		return
 	}
 
 	if err, ok := results[len(results)-1].(error); ok {
 		// return the call application error as is
-		w.sendError(err)
+		w.Error(err)
 		return
 	}
 
-	data := response{Type: responseFinal, Message: results[0 : len(results)-1]}
-	if err := vom.ObjToJSON(w, vom.ValueOf(data)); err != nil {
-		w.sendError(verror.Internalf("error marshalling results: %v", err))
-		return
-	}
-
-	if err := w.FinishMessage(); err != nil {
-		wsp.ctx.logger.Error("WSPR: error finishing message: ", err)
-		return
+	if err := w.Send(lib.ResponseFinal, results[0:len(results)-1]); err != nil {
+		w.Error(verror.Internalf("error marshalling results: %v", err))
 	}
 }
 
@@ -219,7 +187,7 @@
 	var err error
 	if client == nil {
 		// TODO(bjornick): Use the identity to create the client.
-		client, err = ctx.rt.NewClient()
+		client, err = ctx.rt.NewClient(veyron2.CallTimeout(ipc.NoTimeout))
 		if err != nil {
 			return nil, fmt.Errorf("error creating client: %v", err)
 		}
@@ -229,16 +197,17 @@
 	return client, nil
 }
 
-func (ctx WSPR) startVeyronRequest(w clientWriter, msg *veyronRPC) (ipc.Call, error) {
+func (ctx WSPR) startVeyronRequest(w lib.ClientWriter, msg *veyronRPC) (ipc.Call, error) {
 	// Issue request to the endpoint.
 	client, err := ctx.newClient(msg.PrivateId)
 	if err != nil {
 		return nil, err
 	}
-	clientCall, err := client.StartCall(ctx.rt.TODOContext(), msg.Name, uppercaseFirstCharacter(msg.Method), msg.InArgs)
+	methodName := lib.UppercaseFirstCharacter(msg.Method)
+	clientCall, err := client.StartCall(ctx.rt.TODOContext(), msg.Name, methodName, msg.InArgs)
 
 	if err != nil {
-		return nil, fmt.Errorf("error starting call (name: %v, method: %v, args: %v): %v", msg.Name, uppercaseFirstCharacter(msg.Method), msg.InArgs, err)
+		return nil, fmt.Errorf("error starting call (name: %v, method: %v, args: %v): %v", msg.Name, methodName, msg.InArgs, err)
 	}
 
 	return clientCall, nil
@@ -311,7 +280,7 @@
 }
 
 type outstandingStream struct {
-	stream sender
+	stream stream.Sender
 	inType vom.Type
 }
 
@@ -329,43 +298,43 @@
 	outstandingStreams map[int64]outstandingStream
 
 	// Maps flowids to the server that owns them.
-	flowMap map[int64]*server
+	flowMap map[int64]*server.Server
 
 	// A manager that handles fetching and caching signature of remote services
-	signatureManager *signatureManager
+	signatureManager lib.SignatureManager
 
 	// We maintain multiple Veyron server per websocket pipe for serving JavaScript
 	// services.
-	servers map[uint64]*server
+	servers map[uint64]*server.Server
 
 	// Creates a client writer for a given flow.  This is a member so that tests can override
 	// the default implementation.
-	writerCreator func(id int64) clientWriter
+	writerCreator func(id int64) lib.ClientWriter
 }
 
 // Implements the serverHelper interface
-func (wsp *websocketPipe) createNewFlow(server *server, stream sender) *flow {
+func (wsp *websocketPipe) CreateNewFlow(s *server.Server, stream stream.Sender) *server.Flow {
 	wsp.Lock()
 	defer wsp.Unlock()
 	id := wsp.lastGeneratedId
 	wsp.lastGeneratedId += 2
-	wsp.flowMap[id] = server
+	wsp.flowMap[id] = s
 	wsp.outstandingStreams[id] = outstandingStream{stream, vom_wiretype.Type{ID: 1}}
-	return &flow{id: id, writer: wsp.writerCreator(id)}
+	return &server.Flow{ID: id, Writer: wsp.writerCreator(id)}
 }
 
-func (wsp *websocketPipe) cleanupFlow(id int64) {
+func (wsp *websocketPipe) CleanupFlow(id int64) {
 	wsp.Lock()
 	defer wsp.Unlock()
 	delete(wsp.outstandingStreams, id)
 	delete(wsp.flowMap, id)
 }
 
-func (wsp *websocketPipe) getLogger() vlog.Logger {
+func (wsp *websocketPipe) GetLogger() vlog.Logger {
 	return wsp.ctx.logger
 }
 
-func (wsp *websocketPipe) rt() veyron2.Runtime {
+func (wsp *websocketPipe) RT() veyron2.Runtime {
 	return wsp.ctx.rt
 }
 
@@ -385,13 +354,13 @@
 }
 
 func (wsp *websocketPipe) setup() {
-	wsp.signatureManager = newSignatureManager()
+	wsp.signatureManager = lib.NewSignatureManager()
 	wsp.outstandingStreams = make(map[int64]outstandingStream)
-	wsp.flowMap = make(map[int64]*server)
-	wsp.servers = make(map[uint64]*server)
+	wsp.flowMap = make(map[int64]*server.Server)
+	wsp.servers = make(map[uint64]*server.Server)
 
 	if wsp.writerCreator == nil {
-		wsp.writerCreator = func(id int64) clientWriter {
+		wsp.writerCreator = func(id int64) lib.ClientWriter {
 			return &websocketWriter{ws: wsp.ws, id: id, logger: wsp.ctx.logger}
 		}
 	}
@@ -455,12 +424,13 @@
 	return nil
 }
 
-func (wsp *websocketPipe) sendParsedMessageOnStream(id int64, msg interface{}, w clientWriter) {
+func (wsp *websocketPipe) sendParsedMessageOnStream(id int64, msg interface{}, w lib.ClientWriter) {
 	wsp.Lock()
 	defer wsp.Unlock()
 	stream := wsp.outstandingStreams[id].stream
 	if stream == nil {
-		w.sendError(fmt.Errorf("unknown stream"))
+		w.Error(fmt.Errorf("unknown stream"))
+		return
 	}
 
 	stream.Send(msg, w)
@@ -468,7 +438,7 @@
 }
 
 // sendOnStream writes data on id's stream.  Returns an error if the send failed.
-func (wsp *websocketPipe) sendOnStream(id int64, data string, w clientWriter) {
+func (wsp *websocketPipe) sendOnStream(id int64, data string, w lib.ClientWriter) {
 	wsp.Lock()
 	typ := wsp.outstandingStreams[id].inType
 	wsp.Unlock()
@@ -484,12 +454,12 @@
 	wsp.sendParsedMessageOnStream(id, payload, w)
 }
 
-func (wsp *websocketPipe) sendVeyronRequest(id int64, veyronMsg *veyronRPC, w clientWriter, signal chan ipc.Stream) {
+func (wsp *websocketPipe) sendVeyronRequest(id int64, veyronMsg *veyronRPC, w lib.ClientWriter, signal chan ipc.Stream) {
 	// We have to make the start call synchronous so we can make sure that we populate
 	// the call map before we can handle a recieve call.
 	call, err := wsp.ctx.startVeyronRequest(w, veyronMsg)
 	if err != nil {
-		w.sendError(verror.Internalf("can't start Veyron Request: %v", err))
+		w.Error(verror.Internalf("can't start Veyron Request: %v", err))
 		return
 	}
 
@@ -509,7 +479,7 @@
 func (wsp *websocketPipe) handleVeyronRequest(id int64, data string, w *websocketWriter) {
 	veyronMsg, inStreamType, err := wsp.parseVeyronRequest(bytes.NewBufferString(data))
 	if err != nil {
-		w.sendError(verror.Internalf("can't parse Veyron Request: %v", err))
+		w.Error(verror.Internalf("can't parse Veyron Request: %v", err))
 		return
 	}
 
@@ -524,7 +494,7 @@
 	if veyronMsg.IsStreaming {
 		signal = make(chan ipc.Stream)
 		wsp.outstandingStreams[id] = outstandingStream{
-			stream: startQueueingStream(signal),
+			stream: client.StartQueueingStream(signal),
 			inType: inStreamType,
 		}
 	}
@@ -540,9 +510,9 @@
 		return
 	}
 
-	var call queueingStream
+	var call client.QueueingStream
 	var ok bool
-	if call, ok = stream.(queueingStream); !ok {
+	if call, ok = stream.(client.QueueingStream); !ok {
 		wsp.ctx.logger.Errorf("can't close server stream: %v", id)
 		return
 	}
@@ -601,19 +571,19 @@
 		case websocketSignatureRequest:
 			go wsp.handleSignatureRequest(msg.Data, ww)
 		default:
-			ww.sendError(verror.Unknownf("unknown message type: %v", msg.Type))
+			ww.Error(verror.Unknownf("unknown message type: %v", msg.Type))
 		}
 	}
 	wsp.cleanup()
 }
 
-func (wsp *websocketPipe) maybeCreateServer(serverId uint64) (*server, error) {
+func (wsp *websocketPipe) maybeCreateServer(serverId uint64) (*server.Server, error) {
 	wsp.Lock()
 	defer wsp.Unlock()
 	if server, ok := wsp.servers[serverId]; ok {
 		return server, nil
 	}
-	server, err := newServer(serverId, wsp.ctx.veyronProxyEP, wsp)
+	server, err := server.NewServer(serverId, wsp.ctx.veyronProxyEP, wsp)
 	if err != nil {
 		return nil, err
 	}
@@ -634,29 +604,23 @@
 	server.Stop()
 }
 
-func (wsp *websocketPipe) serve(serveRequest serveRequest, w clientWriter) {
+func (wsp *websocketPipe) serve(serveRequest serveRequest, w lib.ClientWriter) {
 	// Create a server for the websocket pipe, if it does not exist already
 	server, err := wsp.maybeCreateServer(serveRequest.ServerId)
 	if err != nil {
-		w.sendError(verror.Internalf("error creating server: %v", err))
+		w.Error(verror.Internalf("error creating server: %v", err))
 	}
 
 	wsp.ctx.logger.VI(2).Infof("serving under name: %q", serveRequest.Name)
 
-	endpoint, err := server.serve(serveRequest.Name, serveRequest.Service)
+	endpoint, err := server.Serve(serveRequest.Name, serveRequest.Service)
 	if err != nil {
-		w.sendError(verror.Internalf("error serving service: %v", err))
+		w.Error(verror.Internalf("error serving service: %v", err))
 		return
 	}
 	// Send the endpoint back
-	endpointData := response{Type: responseFinal, Message: endpoint}
-	if err := vom.ObjToJSON(w, vom.ValueOf(endpointData)); err != nil {
-		w.sendError(verror.Internalf("error marshalling results: %v", err))
-		return
-	}
-
-	if err := w.FinishMessage(); err != nil {
-		wsp.ctx.logger.Error("WSPR: error finishing message: ", err)
+	if err := w.Send(lib.ResponseFinal, endpoint); err != nil {
+		w.Error(verror.Internalf("error marshalling results: %v", err))
 		return
 	}
 }
@@ -668,7 +632,7 @@
 	var serveRequest serveRequest
 	decoder := json.NewDecoder(bytes.NewBufferString(data))
 	if err := decoder.Decode(&serveRequest); err != nil {
-		w.sendError(verror.Internalf("can't unmarshal JSONMessage: %v", err))
+		w.Error(verror.Internalf("can't unmarshal JSONMessage: %v", err))
 		return
 	}
 	wsp.serve(serveRequest, w)
@@ -680,19 +644,17 @@
 	var serverId uint64
 	decoder := json.NewDecoder(bytes.NewBufferString(data))
 	if err := decoder.Decode(&serverId); err != nil {
-		w.sendError(verror.Internalf("can't unmarshal JSONMessage: %v", err))
+		w.Error(verror.Internalf("can't unmarshal JSONMessage: %v", err))
 		return
 	}
 
 	wsp.removeServer(serverId)
 
 	// Send true to indicate stop has finished
-	result := response{Type: responseFinal, Message: true}
-	if err := vom.ObjToJSON(w, vom.ValueOf(result)); err != nil {
-		w.sendError(verror.Internalf("error marshalling results: %v", err))
+	if err := w.Send(lib.ResponseFinal, true); err != nil {
+		w.Error(verror.Internalf("error marshalling results: %v", err))
 		return
 	}
-	w.FinishMessage()
 }
 
 // handleServerResponse handles the completion of outstanding calls to JavaScript services
@@ -707,7 +669,7 @@
 		//Ignore unknown responses that don't belong to any channel
 		return
 	}
-	server.handleServerResponse(id, data)
+	server.HandleServerResponse(id, data)
 }
 
 // parseVeyronRequest parses a json rpc request into a veyronRPC object.
@@ -725,12 +687,12 @@
 
 	// Fetch and adapt signature from the SignatureManager
 	ctx := wsp.ctx.rt.TODOContext()
-	sig, err := wsp.signatureManager.signature(ctx, tempMsg.Name, client)
+	sig, err := wsp.signatureManager.Signature(ctx, tempMsg.Name, client)
 	if err != nil {
 		return nil, nil, verror.Internalf("error getting service signature for %s: %v", tempMsg.Name, err)
 	}
 
-	methName := uppercaseFirstCharacter(tempMsg.Method)
+	methName := lib.UppercaseFirstCharacter(tempMsg.Method)
 	methSig, ok := sig.Methods[methName]
 	if !ok {
 		return nil, nil, fmt.Errorf("Method not found in signature: %v (full sig: %v)", methName, sig)
@@ -777,7 +739,7 @@
 	PrivateId string
 }
 
-func (wsp *websocketPipe) getSignature(name string, privateId string) (JSONServiceSignature, error) {
+func (wsp *websocketPipe) getSignature(name string, privateId string) (signature.JSONServiceSignature, error) {
 	client, err := wsp.ctx.newClient(privateId)
 	if err != nil {
 		return nil, verror.Internalf("error creating client: %v", err)
@@ -785,12 +747,12 @@
 
 	// Fetch and adapt signature from the SignatureManager
 	ctx := wsp.ctx.rt.TODOContext()
-	sig, err := wsp.signatureManager.signature(ctx, name, client)
+	sig, err := wsp.signatureManager.Signature(ctx, name, client)
 	if err != nil {
 		return nil, verror.Internalf("error getting service signature for %s: %v", name, err)
 	}
 
-	return NewJSONServiceSignature(*sig), nil
+	return signature.NewJSONServiceSignature(*sig), nil
 }
 
 // handleSignatureRequest uses signature manager to get and cache signature of a remote server
@@ -799,7 +761,7 @@
 	var request signatureRequest
 	decoder := json.NewDecoder(bytes.NewBufferString(data))
 	if err := decoder.Decode(&request); err != nil {
-		w.sendError(verror.Internalf("can't unmarshal JSONMessage: %v", err))
+		w.Error(verror.Internalf("can't unmarshal JSONMessage: %v", err))
 		return
 	}
 
@@ -807,25 +769,20 @@
 	wsp.ctx.logger.VI(2).Info("private id is", request.PrivateId)
 	jsSig, err := wsp.getSignature(request.Name, request.PrivateId)
 	if err != nil {
-		w.sendError(err)
+		w.Error(err)
 		return
 	}
 
 	// Send the signature back
-	signatureData := response{Type: responseFinal, Message: jsSig}
-	if err := vom.ObjToJSON(w, vom.ValueOf(signatureData)); err != nil {
-		w.sendError(verror.Internalf("error marshalling results: %v", err))
-		return
-	}
-	if err := w.FinishMessage(); err != nil {
-		w.logger.Error("WSPR: error finishing message: ", err)
+	if err := w.Send(lib.ResponseFinal, jsSig); err != nil {
+		w.Error(verror.Internalf("error marshalling results: %v", err))
 		return
 	}
 }
 
 func (ctx *WSPR) setup() {
 	// Cache up to 20 identity.PrivateID->ipc.Client mappings
-	ctx.clientCache = NewClientCache(20)
+	ctx.clientCache = lib.NewClientCache(20)
 }
 
 // Starts the proxy and listens for requests. This method is blocking.
diff --git a/services/wspr/wsprd/lib/wspr_test.go b/services/wsprd/wspr/wspr_test.go
similarity index 88%
rename from services/wspr/wsprd/lib/wspr_test.go
rename to services/wsprd/wspr/wspr_test.go
index f8d6b9f..d03d7fa 100644
--- a/services/wspr/wsprd/lib/wspr_test.go
+++ b/services/wsprd/wspr/wspr_test.go
@@ -1,4 +1,4 @@
-package lib
+package wspr
 
 import (
 	"bytes"
@@ -8,11 +8,14 @@
 	"sync"
 	"testing"
 	"time"
+	"veyron/services/wsprd/ipc/client"
+	"veyron/services/wsprd/lib"
+	"veyron/services/wsprd/signature"
 	"veyron2"
 	"veyron2/ipc"
 	"veyron2/naming"
 	"veyron2/rt"
-	"veyron2/vdl"
+	"veyron2/vdl/vdlutil"
 	"veyron2/verror"
 	"veyron2/vlog"
 	"veyron2/vom"
@@ -85,7 +88,7 @@
 		InStream:  36,
 		OutStream: 36,
 	}
-	result.TypeDefs = []vdl.Any{
+	result.TypeDefs = []vdlutil.Any{
 		wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}}
 
 	return result, nil
@@ -132,7 +135,6 @@
 type testWriter struct {
 	sync.Mutex
 	stream []response
-	buf    bytes.Buffer
 	err    error
 	logger vlog.Logger
 	// If this channel is set then a message will be sent
@@ -140,29 +142,32 @@
 	notifier chan bool
 }
 
-func (w *testWriter) Write(p []byte) (int, error) {
-	return w.buf.Write(p)
-
-}
-
-func (w *testWriter) sendError(err error) {
-	w.err = err
-}
-
-func (w *testWriter) FinishMessage() error {
-	var resp response
-	p := w.buf.Bytes()
-	w.buf.Reset()
-	if err := json.Unmarshal(p, &resp); err != nil {
+func (w *testWriter) Send(responseType lib.ResponseType, msg interface{}) error {
+	w.Lock()
+	defer w.Unlock()
+	// We serialize and deserialize the reponse so that we can do deep equal with
+	// messages that contain non-exported structs.
+	var buf bytes.Buffer
+	if err := json.NewEncoder(&buf).Encode(response{Type: responseType, Message: msg}); err != nil {
 		return err
 	}
-	w.Lock()
-	w.stream = append(w.stream, resp)
+
+	var r response
+
+	if err := json.NewDecoder(&buf).Decode(&r); err != nil {
+		return err
+	}
+
+	w.stream = append(w.stream, r)
 	if w.notifier != nil {
 		w.notifier <- true
 	}
-	w.Unlock()
 	return nil
+
+}
+
+func (w *testWriter) Error(err error) {
+	w.err = err
 }
 
 func (w *testWriter) streamLength() int {
@@ -204,18 +209,18 @@
 	}
 }
 
-var adderServiceSignature JSONServiceSignature = JSONServiceSignature{
-	"add": JSONMethodSignature{
+var adderServiceSignature signature.JSONServiceSignature = signature.JSONServiceSignature{
+	"add": signature.JSONMethodSignature{
 		InArgs:      []string{"A", "B"},
 		NumOutArgs:  2,
 		IsStreaming: false,
 	},
-	"divide": JSONMethodSignature{
+	"divide": signature.JSONMethodSignature{
 		InArgs:      []string{"A", "B"},
 		NumOutArgs:  2,
 		IsStreaming: false,
 	},
-	"streamingAdd": JSONMethodSignature{
+	"streamingAdd": signature.JSONMethodSignature{
 		InArgs:      []string{},
 		NumOutArgs:  2,
 		IsStreaming: true,
@@ -275,7 +280,7 @@
 	if len(test.streamingInputs) > 0 {
 		signal = make(chan ipc.Stream, 1)
 		wsp.outstandingStreams[0] = outstandingStream{
-			stream: startQueueingStream(signal),
+			stream: client.StartQueueingStream(signal),
 			inType: test.streamingInputType,
 		}
 		go func() {
@@ -294,6 +299,7 @@
 		IsStreaming: signal != nil,
 	}
 	wsp.sendVeyronRequest(0, &request, &writer, signal)
+
 	checkResponses(&writer, test.expectedStream, test.expectedError, t)
 }
 
@@ -304,8 +310,8 @@
 		numOutArgs: 2,
 		expectedStream: []response{
 			response{
-				Message: []interface{}{float64(5)},
-				Type:    responseFinal,
+				Message: []interface{}{5.0},
+				Type:    lib.ResponseFinal,
 			},
 		},
 	})
@@ -330,27 +336,27 @@
 		expectedStream: []response{
 			response{
 				Message: 1.0,
-				Type:    responseStream,
+				Type:    lib.ResponseStream,
 			},
 			response{
 				Message: 3.0,
-				Type:    responseStream,
+				Type:    lib.ResponseStream,
 			},
 			response{
 				Message: 6.0,
-				Type:    responseStream,
+				Type:    lib.ResponseStream,
 			},
 			response{
 				Message: 10.0,
-				Type:    responseStream,
+				Type:    lib.ResponseStream,
 			},
 			response{
 				Message: nil,
-				Type:    responseStreamClose,
+				Type:    lib.ResponseStreamClose,
 			},
 			response{
 				Message: []interface{}{10.0},
-				Type:    responseFinal,
+				Type:    lib.ResponseFinal,
 			},
 		},
 	})
@@ -385,7 +391,7 @@
 	writer := testWriter{
 		logger: wspr.logger,
 	}
-	wsp.writerCreator = func(int64) clientWriter {
+	wsp.writerCreator = func(int64) lib.ClientWriter {
 		return &writer
 	}
 	wsp.setup()
@@ -416,7 +422,7 @@
 
 	resp := rt.writer.stream[0]
 
-	if resp.Type != responseFinal {
+	if resp.Type != lib.ResponseFinal {
 		t.Errorf("unknown stream message Got: %v, expected: serve response", resp)
 		return
 	}
@@ -469,14 +475,14 @@
 	err           *verror.Standard
 }
 
-func sendServerStream(t *testing.T, wsp *websocketPipe, test *jsServerTestCase, w clientWriter) {
+func sendServerStream(t *testing.T, wsp *websocketPipe, test *jsServerTestCase, w lib.ClientWriter) {
 	for _, msg := range test.serverStream {
 		wsp.sendParsedMessageOnStream(0, msg, w)
 	}
 
-	serverReply := serverRPCReply{
-		Results: []interface{}{test.finalResponse},
-		Err:     test.err,
+	serverReply := map[string]interface{}{
+		"Results": []interface{}{test.finalResponse},
+		"Err":     test.err,
 	}
 
 	bytes, err := json.Marshal(serverReply)
@@ -503,7 +509,7 @@
 
 	resp := rt.writer.stream[0]
 
-	if resp.Type != responseFinal {
+	if resp.Type != lib.ResponseFinal {
 		t.Errorf("unknown stream message Got: %v, expected: serve response", resp)
 		return
 	}
@@ -533,14 +539,14 @@
 
 	expectedWebsocketMessage := []response{
 		response{
-			Type: responseServerRequest,
+			Type: lib.ResponseServerRequest,
 			Message: map[string]interface{}{
-				"serverId": 0.0,
-				"method":   lowercaseFirstCharacter(test.method),
-				"args":     test.inArgs,
-				"context": map[string]interface{}{
-					"name":   "adder",
-					"suffix": "adder",
+				"ServerId": 0.0,
+				"Method":   lib.LowercaseFirstCharacter(test.method),
+				"Args":     test.inArgs,
+				"Context": map[string]interface{}{
+					"Name":   "adder",
+					"Suffix": "adder",
 				},
 			},
 		},
@@ -551,7 +557,7 @@
 		t.Errorf("didn't recieve expected message: %v", err)
 	}
 	for _, msg := range test.clientStream {
-		expectedWebsocketMessage = append(expectedWebsocketMessage, response{Type: responseStream, Message: msg})
+		expectedWebsocketMessage = append(expectedWebsocketMessage, response{Type: lib.ResponseStream, Message: msg})
 		if err := call.Send(msg); err != nil {
 			t.Errorf("unexpected error while sending %v: %v", msg, err)
 		}
@@ -562,7 +568,7 @@
 		t.Errorf("didn't recieve expected message: %v", err)
 	}
 
-	expectedWebsocketMessage = append(expectedWebsocketMessage, response{Type: responseStreamClose})
+	expectedWebsocketMessage = append(expectedWebsocketMessage, response{Type: lib.ResponseStreamClose})
 
 	expectedStream := test.serverStream
 	go sendServerStream(t, rt.wsp, &test, rt.writer)
diff --git a/tools/playground/builder/vbuild.go b/tools/playground/builder/vbuild.go
index 9a3b9b9..0b8f174 100644
--- a/tools/playground/builder/vbuild.go
+++ b/tools/playground/builder/vbuild.go
@@ -6,6 +6,7 @@
 import (
 	"bufio"
 	"encoding/json"
+	"flag"
 	"fmt"
 	"go/parser"
 	"go/token"
@@ -22,7 +23,7 @@
 )
 
 const RUN_TIMEOUT = time.Second
-const debug = false
+var debug = flag.Bool("v", false, "Verbose mode")
 
 type CodeFile struct {
 	Name       string
@@ -55,7 +56,7 @@
 }
 
 func Log(args ...interface{}) {
-	if debug {
+	if *debug {
 		log.Println(args...)
 	}
 }
@@ -108,6 +109,7 @@
 }
 
 func main() {
+	flag.Parse()
 	r, err := ParseRequest(os.Stdin)
 	if err != nil {
 		log.Fatal(err)
@@ -275,7 +277,7 @@
 			if groups := pat.FindStringSubmatch(line); groups != nil {
 				ch <- groups[1]
 			} else {
-				Log(line)
+				Log("mounttabld: %s", line)
 			}
 		}
 		close(ch)
diff --git a/tools/profile/impl/impl.go b/tools/profile/impl/impl.go
index cef78c8..b90e8a6 100644
--- a/tools/profile/impl/impl.go
+++ b/tools/profile/impl/impl.go
@@ -8,6 +8,7 @@
 	"veyron/services/mgmt/repository"
 
 	"veyron2/rt"
+	"veyron2/services/mgmt/build"
 )
 
 var cmdLabel = &cmdline.Command{
@@ -105,10 +106,12 @@
 
 	// TODO(rthellend): Read an actual specification from a file.
 	spec := profile.Specification{
-		Format:      profile.Format{Name: "elf", Attributes: map[string]string{"os": "linux", "arch": "amd64"}},
+		Arch:        build.AMD64,
+		Description: "Example profile to test the profile manager implementation.",
+		Format:      build.ELF,
 		Libraries:   map[profile.Library]struct{}{profile.Library{Name: "foo", MajorVersion: "1", MinorVersion: "0"}: struct{}{}},
 		Label:       "example",
-		Description: "Example profile to test the profile manager implementation.",
+		OS:          build.Linux,
 	}
 	if err := p.Put(rt.R().NewContext(), spec); err != nil {
 		return err
diff --git a/tools/profile/impl/impl_test.go b/tools/profile/impl/impl_test.go
index 8500787..45ccf14 100644
--- a/tools/profile/impl/impl_test.go
+++ b/tools/profile/impl/impl_test.go
@@ -15,16 +15,19 @@
 	"veyron2/naming"
 	"veyron2/rt"
 	"veyron2/security"
+	"veyron2/services/mgmt/build"
 	"veyron2/vlog"
 )
 
 var (
 	// spec is an example profile specification used throughout the test.
 	spec = profile.Specification{
-		Format:      profile.Format{Name: "elf", Attributes: map[string]string{"os": "linux"}},
+		Arch:        build.AMD64,
+		Description: "Example profile to test the profile repository implementation.",
+		Format:      build.ELF,
 		Libraries:   map[profile.Library]struct{}{profile.Library{Name: "foo", MajorVersion: "1", MinorVersion: "0"}: struct{}{}},
 		Label:       "example",
-		Description: "Example profile to test the profile repository implementation.",
+		OS:          build.Linux,
 	}
 )
 
diff --git a/tools/vrpc/impl/impl.go b/tools/vrpc/impl/impl.go
index aca51a3..fa06375 100644
--- a/tools/vrpc/impl/impl.go
+++ b/tools/vrpc/impl/impl.go
@@ -12,7 +12,7 @@
 	"veyron2/context"
 	"veyron2/ipc"
 	"veyron2/rt"
-	"veyron2/vdl"
+	"veyron2/vdl/vdlutil"
 	"veyron2/vom"
 	"veyron2/wiretype"
 
@@ -224,8 +224,8 @@
 }
 
 // formatWiretype generates a string representation of the specified type.
-func formatWiretype(td []vdl.Any, tid wiretype.TypeID) string {
-	var wt vdl.Any
+func formatWiretype(td []vdlutil.Any, tid wiretype.TypeID) string {
+	var wt vdlutil.Any
 	if tid >= wiretype.TypeIDFirst {
 		wt = td[tid-wiretype.TypeIDFirst]
 	} else {
@@ -269,7 +269,7 @@
 	}
 }
 
-func formatSignature(name string, ms ipc.MethodSignature, defs []vdl.Any) string {
+func formatSignature(name string, ms ipc.MethodSignature, defs []vdlutil.Any) string {
 	var buf bytes.Buffer
 	fmt.Fprintf(&buf, "func %s(", name)
 	for index, arg := range ms.InArgs {
diff --git a/tools/vrpc/test_base/test_base.vdl.go b/tools/vrpc/test_base/test_base.vdl.go
index 958f64e..9332b43 100644
--- a/tools/vrpc/test_base/test_base.vdl.go
+++ b/tools/vrpc/test_base/test_base.vdl.go
@@ -10,7 +10,7 @@
 	_gen_ipc "veyron2/ipc"
 	_gen_naming "veyron2/naming"
 	_gen_rt "veyron2/rt"
-	_gen_vdl "veyron2/vdl"
+	_gen_vdlutil "veyron2/vdl/vdlutil"
 	_gen_wiretype "veyron2/wiretype"
 )
 
@@ -153,10 +153,10 @@
 		case _gen_ipc.Client:
 			client = o
 		default:
-			return nil, _gen_vdl.ErrUnrecognizedOption
+			return nil, _gen_vdlutil.ErrUnrecognizedOption
 		}
 	default:
-		return nil, _gen_vdl.ErrTooManyOptionsToBind
+		return nil, _gen_vdlutil.ErrTooManyOptionsToBind
 	}
 	stub := &clientStubTypeTester{client: client, name: name}
 
@@ -659,7 +659,7 @@
 		OutStream: 2,
 	}
 
-	result.TypeDefs = []_gen_vdl.Any{
+	result.TypeDefs = []_gen_vdlutil.Any{
 		_gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}, _gen_wiretype.NamedPrimitiveType{Type: 0x32, Name: "byte", Tags: []string(nil)}, _gen_wiretype.ArrayType{Elem: 0x42, Len: 0x2, Name: "", Tags: []string(nil)}, _gen_wiretype.MapType{Key: 0x42, Elem: 0x42, Name: "", Tags: []string(nil)}, _gen_wiretype.SliceType{Elem: 0x42, Name: "", Tags: []string(nil)}, _gen_wiretype.StructType{
 			[]_gen_wiretype.FieldType{
 				_gen_wiretype.FieldType{Type: 0x24, Name: "X"},