diff --git a/go/src/v.io/x/js.core/stress/stress.vdl.go b/go/src/v.io/x/js.core/stress/stress.vdl.go
index 0fd9dcb..0daebc1 100644
--- a/go/src/v.io/x/js.core/stress/stress.vdl.go
+++ b/go/src/v.io/x/js.core/stress/stress.vdl.go
@@ -3,7 +3,7 @@
 // license that can be found in the LICENSE file.
 
 // This file was auto-generated by the vanadium vdl tool.
-// Source: stress.vdl
+// Package: stress
 
 package stress
 
@@ -30,7 +30,7 @@
 }
 
 func (m *StressResults) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-	if __VDLType_stress_v_io_x_js_core_stress_StressResults == nil || __VDLTypestress0 == nil {
+	if __VDLType_v_io_x_js_core_stress_StressResults == nil || __VDLType0 == nil {
 		panic("Initialization order error: types generated for FillVDLTarget not initialized. Consider moving caller to an init() block.")
 	}
 	fieldsTarget1, err := t.StartFields(tt)
@@ -91,8 +91,8 @@
 }
 
 func (t *StressResultsTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {
-	if !vdl.Compatible(tt, __VDLType_stress_v_io_x_js_core_stress_StressResults) {
-		return nil, fmt.Errorf("type %v incompatible with %v", tt, __VDLType_stress_v_io_x_js_core_stress_StressResults)
+	if !vdl.Compatible(tt, __VDLType_v_io_x_js_core_stress_StressResults) {
+		return nil, fmt.Errorf("type %v incompatible with %v", tt, __VDLType_v_io_x_js_core_stress_StressResults)
 	}
 	return t, nil
 }
@@ -108,7 +108,7 @@
 		val, err := &vdl.Float64Target{Value: &t.Value.MsecsPerRpc}, error(nil)
 		return nil, val, err
 	default:
-		return nil, nil, fmt.Errorf("field %s not in struct %v", name, __VDLType_stress_v_io_x_js_core_stress_StressResults)
+		return nil, nil, fmt.Errorf("field %s not in struct %v", name, __VDLType_v_io_x_js_core_stress_StressResults)
 	}
 }
 func (t *StressResultsTarget) FinishField(_, _ vdl.Target) error {
@@ -123,10 +123,10 @@
 	vdl.Register((*StressResults)(nil))
 }
 
-var __VDLTypestress0 *vdl.Type = vdl.TypeOf((*StressResults)(nil))
-var __VDLType_stress_v_io_x_js_core_stress_StressResults *vdl.Type = vdl.TypeOf(StressResults{})
+var __VDLType0 *vdl.Type = vdl.TypeOf((*StressResults)(nil))
+var __VDLType_v_io_x_js_core_stress_StressResults *vdl.Type = vdl.TypeOf(StressResults{})
 
-func __VDLEnsureNativeBuilt_stress() {
+func __VDLEnsureNativeBuilt() {
 }
 
 // StressClientMethods is the client interface
diff --git a/go/src/v.io/x/js.core/test_service/cache.vdl.go b/go/src/v.io/x/js.core/test_service/cache.vdl.go
deleted file mode 100644
index 369e56e..0000000
--- a/go/src/v.io/x/js.core/test_service/cache.vdl.go
+++ /dev/null
@@ -1,901 +0,0 @@
-// Copyright 2015 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file was auto-generated by the vanadium vdl tool.
-// Source: cache.vdl
-
-package test_service
-
-import (
-	"fmt"
-	"io"
-	"reflect"
-	"v.io/v23"
-	"v.io/v23/context"
-	"v.io/v23/rpc"
-	"v.io/v23/vdl"
-	"v.io/v23/vom"
-)
-
-// KeyPageResult is a page of 10 keys.
-type KeyPageResult [10]string
-
-func (KeyPageResult) __VDLReflect(struct {
-	Name string `vdl:"v.io/x/js.core/test_service.KeyPageResult"`
-}) {
-}
-
-func (m *KeyPageResult) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-	listTarget1, err := t.StartList(__VDLType_cache_v_io_x_js_core_test_service_KeyPageResult, 10)
-	if err != nil {
-		return err
-	}
-	for i, elem3 := range *m {
-		elemTarget2, err := listTarget1.StartElem(i)
-		if err != nil {
-			return err
-		}
-		if err := elemTarget2.FromString(string(elem3), vdl.StringType); err != nil {
-			return err
-		}
-		if err := listTarget1.FinishElem(elemTarget2); err != nil {
-			return err
-		}
-	}
-	if err := t.FinishList(listTarget1); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (m *KeyPageResult) MakeVDLTarget() vdl.Target {
-	return &KeyPageResultTarget{Value: m}
-}
-
-type KeyPageResultTarget struct {
-	Value *KeyPageResult
-	vdl.TargetBase
-	vdl.ListTargetBase
-}
-
-func (t *KeyPageResultTarget) StartList(tt *vdl.Type, len int) (vdl.ListTarget, error) {
-	if !vdl.Compatible(tt, __VDLType_cache_v_io_x_js_core_test_service_KeyPageResult) {
-		return nil, fmt.Errorf("type %v incompatible with %v", tt, __VDLType_cache_v_io_x_js_core_test_service_KeyPageResult)
-	}
-	return t, nil
-}
-func (t *KeyPageResultTarget) StartElem(index int) (elem vdl.Target, _ error) {
-	return &vdl.StringTarget{Value: &(*t.Value)[index]}, error(nil)
-}
-func (t *KeyPageResultTarget) FinishElem(elem vdl.Target) error {
-	return nil
-}
-func (t *KeyPageResultTarget) FinishList(elem vdl.ListTarget) error {
-
-	return nil
-}
-
-// KeyValuePair is a representation of a cached key and value pair.
-type KeyValuePair struct {
-	Key   string
-	Value *vom.RawBytes
-}
-
-func (KeyValuePair) __VDLReflect(struct {
-	Name string `vdl:"v.io/x/js.core/test_service.KeyValuePair"`
-}) {
-}
-
-func (m *KeyValuePair) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-	if __VDLType_cache_v_io_x_js_core_test_service_KeyValuePair == nil || __VDLTypecache0 == nil {
-		panic("Initialization order error: types generated for FillVDLTarget not initialized. Consider moving caller to an init() block.")
-	}
-	fieldsTarget1, err := t.StartFields(tt)
-	if err != nil {
-		return err
-	}
-
-	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Key")
-	if err != vdl.ErrFieldNoExist && err != nil {
-		return err
-	}
-	if err != vdl.ErrFieldNoExist {
-		if err := fieldTarget3.FromString(string(m.Key), vdl.StringType); err != nil {
-			return err
-		}
-		if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
-			return err
-		}
-	}
-	keyTarget4, fieldTarget5, err := fieldsTarget1.StartField("Value")
-	if err != vdl.ErrFieldNoExist && err != nil {
-		return err
-	}
-	if err != vdl.ErrFieldNoExist {
-
-		if m.Value == nil {
-			if err := fieldTarget5.FromNil(vdl.AnyType); err != nil {
-				return err
-			}
-		} else {
-			if err := m.Value.FillVDLTarget(fieldTarget5, vdl.AnyType); err != nil {
-				return err
-			}
-		}
-		if err := fieldsTarget1.FinishField(keyTarget4, fieldTarget5); err != nil {
-			return err
-		}
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (m *KeyValuePair) MakeVDLTarget() vdl.Target {
-	return &KeyValuePairTarget{Value: m}
-}
-
-type KeyValuePairTarget struct {
-	Value *KeyValuePair
-	vdl.TargetBase
-	vdl.FieldsTargetBase
-}
-
-func (t *KeyValuePairTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {
-	if !vdl.Compatible(tt, __VDLType_cache_v_io_x_js_core_test_service_KeyValuePair) {
-		return nil, fmt.Errorf("type %v incompatible with %v", tt, __VDLType_cache_v_io_x_js_core_test_service_KeyValuePair)
-	}
-	return t, nil
-}
-func (t *KeyValuePairTarget) StartField(name string) (key, field vdl.Target, _ error) {
-	switch name {
-	case "Key":
-		val, err := &vdl.StringTarget{Value: &t.Value.Key}, error(nil)
-		return nil, val, err
-	case "Value":
-		val, err := vdl.ReflectTarget(reflect.ValueOf(&t.Value.Value))
-		return nil, val, err
-	default:
-		return nil, nil, fmt.Errorf("field %s not in struct %v", name, __VDLType_cache_v_io_x_js_core_test_service_KeyValuePair)
-	}
-}
-func (t *KeyValuePairTarget) FinishField(_, _ vdl.Target) error {
-	return nil
-}
-func (t *KeyValuePairTarget) FinishFields(_ vdl.FieldsTarget) error {
-
-	return nil
-}
-
-func init() {
-	vdl.Register((*KeyPageResult)(nil))
-	vdl.Register((*KeyValuePair)(nil))
-}
-
-var __VDLTypecache0 *vdl.Type = vdl.TypeOf((*KeyValuePair)(nil))
-var __VDLType_cache_v_io_x_js_core_test_service_KeyPageResult *vdl.Type = vdl.TypeOf(KeyPageResult{})
-var __VDLType_cache_v_io_x_js_core_test_service_KeyValuePair *vdl.Type = vdl.TypeOf(KeyValuePair{})
-
-func __VDLEnsureNativeBuilt_cache() {
-}
-
-// CacheClientMethods is the client interface
-// containing Cache methods.
-//
-// A Cache service mimics the memcache interface.
-type CacheClientMethods interface {
-	// Set sets a value for a key.
-	Set(_ *context.T, key string, value *vom.RawBytes, _ ...rpc.CallOpt) error
-	// Get returns the value for a key.  If the value is not found, returns
-	// a not found error.
-	Get(_ *context.T, key string, _ ...rpc.CallOpt) (*vom.RawBytes, error)
-	// Same as Get, but casts the return argument to an byte.
-	GetAsByte(_ *context.T, key string, _ ...rpc.CallOpt) (byte, error)
-	// Same as Get, but casts the return argument to an int32.
-	GetAsInt32(_ *context.T, key string, _ ...rpc.CallOpt) (int32, error)
-	// Same as Get, but casts the return argument to an int64.
-	GetAsInt64(_ *context.T, key string, _ ...rpc.CallOpt) (int64, error)
-	// Same as Get, but casts the return argument to an uint32.
-	GetAsUint32(_ *context.T, key string, _ ...rpc.CallOpt) (uint32, error)
-	// Same as Get, but casts the return argument to an uint64.
-	GetAsUint64(_ *context.T, key string, _ ...rpc.CallOpt) (uint64, error)
-	// Same as Get, but casts the return argument to an float32.
-	GetAsFloat32(_ *context.T, key string, _ ...rpc.CallOpt) (float32, error)
-	// Same as Get, but casts the return argument to an float64.
-	GetAsFloat64(_ *context.T, key string, _ ...rpc.CallOpt) (float64, error)
-	// Same as Get, but casts the return argument to a string.
-	GetAsString(_ *context.T, key string, _ ...rpc.CallOpt) (string, error)
-	// Same as Get, but casts the return argument to a bool.
-	GetAsBool(_ *context.T, key string, _ ...rpc.CallOpt) (bool, error)
-	// Same as Get, but casts the return argument to an error.
-	GetAsError(_ *context.T, key string, _ ...rpc.CallOpt) (error, error)
-	// AsMap returns the full contents of the cache as a map.
-	AsMap(*context.T, ...rpc.CallOpt) (map[string]*vom.RawBytes, error)
-	// KeyValuePairs returns the full contents of the cache as a slice of pairs.
-	KeyValuePairs(*context.T, ...rpc.CallOpt) ([]KeyValuePair, error)
-	// MostRecentSet returns the key and value and the timestamp for the most
-	// recent set operation
-	// TODO(bprosnitz) support type types and change time to native time type
-	MostRecentSet(*context.T, ...rpc.CallOpt) (value KeyValuePair, time int64, _ error)
-	// KeyPage indexes into the keys (in alphanumerically sorted order) and
-	// returns the indexth page of 10 keys.
-	KeyPage(_ *context.T, index int64, _ ...rpc.CallOpt) (KeyPageResult, error)
-	// Size returns the total number of entries in the cache.
-	Size(*context.T, ...rpc.CallOpt) (int64, error)
-	// MultiGet sets up a stream that allows fetching multiple keys.
-	MultiGet(*context.T, ...rpc.CallOpt) (CacheMultiGetClientCall, error)
-}
-
-// CacheClientStub adds universal methods to CacheClientMethods.
-type CacheClientStub interface {
-	CacheClientMethods
-	rpc.UniversalServiceMethods
-}
-
-// CacheClient returns a client stub for Cache.
-func CacheClient(name string) CacheClientStub {
-	return implCacheClientStub{name}
-}
-
-type implCacheClientStub struct {
-	name string
-}
-
-func (c implCacheClientStub) Set(ctx *context.T, i0 string, i1 *vom.RawBytes, opts ...rpc.CallOpt) (err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "Set", []interface{}{i0, i1}, nil, opts...)
-	return
-}
-
-func (c implCacheClientStub) Get(ctx *context.T, i0 string, opts ...rpc.CallOpt) (o0 *vom.RawBytes, err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "Get", []interface{}{i0}, []interface{}{&o0}, opts...)
-	return
-}
-
-func (c implCacheClientStub) GetAsByte(ctx *context.T, i0 string, opts ...rpc.CallOpt) (o0 byte, err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "GetAsByte", []interface{}{i0}, []interface{}{&o0}, opts...)
-	return
-}
-
-func (c implCacheClientStub) GetAsInt32(ctx *context.T, i0 string, opts ...rpc.CallOpt) (o0 int32, err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "GetAsInt32", []interface{}{i0}, []interface{}{&o0}, opts...)
-	return
-}
-
-func (c implCacheClientStub) GetAsInt64(ctx *context.T, i0 string, opts ...rpc.CallOpt) (o0 int64, err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "GetAsInt64", []interface{}{i0}, []interface{}{&o0}, opts...)
-	return
-}
-
-func (c implCacheClientStub) GetAsUint32(ctx *context.T, i0 string, opts ...rpc.CallOpt) (o0 uint32, err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "GetAsUint32", []interface{}{i0}, []interface{}{&o0}, opts...)
-	return
-}
-
-func (c implCacheClientStub) GetAsUint64(ctx *context.T, i0 string, opts ...rpc.CallOpt) (o0 uint64, err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "GetAsUint64", []interface{}{i0}, []interface{}{&o0}, opts...)
-	return
-}
-
-func (c implCacheClientStub) GetAsFloat32(ctx *context.T, i0 string, opts ...rpc.CallOpt) (o0 float32, err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "GetAsFloat32", []interface{}{i0}, []interface{}{&o0}, opts...)
-	return
-}
-
-func (c implCacheClientStub) GetAsFloat64(ctx *context.T, i0 string, opts ...rpc.CallOpt) (o0 float64, err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "GetAsFloat64", []interface{}{i0}, []interface{}{&o0}, opts...)
-	return
-}
-
-func (c implCacheClientStub) GetAsString(ctx *context.T, i0 string, opts ...rpc.CallOpt) (o0 string, err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "GetAsString", []interface{}{i0}, []interface{}{&o0}, opts...)
-	return
-}
-
-func (c implCacheClientStub) GetAsBool(ctx *context.T, i0 string, opts ...rpc.CallOpt) (o0 bool, err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "GetAsBool", []interface{}{i0}, []interface{}{&o0}, opts...)
-	return
-}
-
-func (c implCacheClientStub) GetAsError(ctx *context.T, i0 string, opts ...rpc.CallOpt) (o0 error, err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "GetAsError", []interface{}{i0}, []interface{}{&o0}, opts...)
-	return
-}
-
-func (c implCacheClientStub) AsMap(ctx *context.T, opts ...rpc.CallOpt) (o0 map[string]*vom.RawBytes, err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "AsMap", nil, []interface{}{&o0}, opts...)
-	return
-}
-
-func (c implCacheClientStub) KeyValuePairs(ctx *context.T, opts ...rpc.CallOpt) (o0 []KeyValuePair, err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "KeyValuePairs", nil, []interface{}{&o0}, opts...)
-	return
-}
-
-func (c implCacheClientStub) MostRecentSet(ctx *context.T, opts ...rpc.CallOpt) (o0 KeyValuePair, o1 int64, err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "MostRecentSet", nil, []interface{}{&o0, &o1}, opts...)
-	return
-}
-
-func (c implCacheClientStub) KeyPage(ctx *context.T, i0 int64, opts ...rpc.CallOpt) (o0 KeyPageResult, err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "KeyPage", []interface{}{i0}, []interface{}{&o0}, opts...)
-	return
-}
-
-func (c implCacheClientStub) Size(ctx *context.T, opts ...rpc.CallOpt) (o0 int64, err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "Size", nil, []interface{}{&o0}, opts...)
-	return
-}
-
-func (c implCacheClientStub) MultiGet(ctx *context.T, opts ...rpc.CallOpt) (ocall CacheMultiGetClientCall, err error) {
-	var call rpc.ClientCall
-	if call, err = v23.GetClient(ctx).StartCall(ctx, c.name, "MultiGet", nil, opts...); err != nil {
-		return
-	}
-	ocall = &implCacheMultiGetClientCall{ClientCall: call}
-	return
-}
-
-// CacheMultiGetClientStream is the client stream for Cache.MultiGet.
-type CacheMultiGetClientStream interface {
-	// RecvStream returns the receiver side of the Cache.MultiGet client stream.
-	RecvStream() interface {
-		// Advance stages an item so that it may be retrieved via Value.  Returns
-		// true iff there is an item to retrieve.  Advance must be called before
-		// Value is called.  May block if an item is not available.
-		Advance() bool
-		// Value returns the item that was staged by Advance.  May panic if Advance
-		// returned false or was not called.  Never blocks.
-		Value() *vom.RawBytes
-		// Err returns any error encountered by Advance.  Never blocks.
-		Err() error
-	}
-	// SendStream returns the send side of the Cache.MultiGet client stream.
-	SendStream() interface {
-		// Send places the item onto the output stream.  Returns errors
-		// encountered while sending, or if Send is called after Close or
-		// the stream has been canceled.  Blocks if there is no buffer
-		// space; will unblock when buffer space is available or after
-		// the stream has been canceled.
-		Send(item string) error
-		// Close indicates to the server that no more items will be sent;
-		// server Recv calls will receive io.EOF after all sent items.
-		// This is an optional call - e.g. a client might call Close if it
-		// needs to continue receiving items from the server after it's
-		// done sending.  Returns errors encountered while closing, or if
-		// Close is called after the stream has been canceled.  Like Send,
-		// blocks if there is no buffer space available.
-		Close() error
-	}
-}
-
-// CacheMultiGetClientCall represents the call returned from Cache.MultiGet.
-type CacheMultiGetClientCall interface {
-	CacheMultiGetClientStream
-	// Finish performs the equivalent of SendStream().Close, then blocks until
-	// the server is done, and returns the positional return values for the call.
-	//
-	// Finish returns immediately if the call has been canceled; depending on the
-	// timing the output could either be an error signaling cancelation, or the
-	// valid positional return values from the server.
-	//
-	// Calling Finish is mandatory for releasing stream resources, unless the call
-	// has been canceled or any of the other methods return an error.  Finish should
-	// be called at most once.
-	Finish() error
-}
-
-type implCacheMultiGetClientCall struct {
-	rpc.ClientCall
-	valRecv *vom.RawBytes
-	errRecv error
-}
-
-func (c *implCacheMultiGetClientCall) RecvStream() interface {
-	Advance() bool
-	Value() *vom.RawBytes
-	Err() error
-} {
-	return implCacheMultiGetClientCallRecv{c}
-}
-
-type implCacheMultiGetClientCallRecv struct {
-	c *implCacheMultiGetClientCall
-}
-
-func (c implCacheMultiGetClientCallRecv) Advance() bool {
-	c.c.valRecv = nil
-	c.c.errRecv = c.c.Recv(&c.c.valRecv)
-	return c.c.errRecv == nil
-}
-func (c implCacheMultiGetClientCallRecv) Value() *vom.RawBytes {
-	return c.c.valRecv
-}
-func (c implCacheMultiGetClientCallRecv) Err() error {
-	if c.c.errRecv == io.EOF {
-		return nil
-	}
-	return c.c.errRecv
-}
-func (c *implCacheMultiGetClientCall) SendStream() interface {
-	Send(item string) error
-	Close() error
-} {
-	return implCacheMultiGetClientCallSend{c}
-}
-
-type implCacheMultiGetClientCallSend struct {
-	c *implCacheMultiGetClientCall
-}
-
-func (c implCacheMultiGetClientCallSend) Send(item string) error {
-	return c.c.Send(item)
-}
-func (c implCacheMultiGetClientCallSend) Close() error {
-	return c.c.CloseSend()
-}
-func (c *implCacheMultiGetClientCall) Finish() (err error) {
-	err = c.ClientCall.Finish()
-	return
-}
-
-// CacheServerMethods is the interface a server writer
-// implements for Cache.
-//
-// A Cache service mimics the memcache interface.
-type CacheServerMethods interface {
-	// Set sets a value for a key.
-	Set(_ *context.T, _ rpc.ServerCall, key string, value *vom.RawBytes) error
-	// Get returns the value for a key.  If the value is not found, returns
-	// a not found error.
-	Get(_ *context.T, _ rpc.ServerCall, key string) (*vom.RawBytes, error)
-	// Same as Get, but casts the return argument to an byte.
-	GetAsByte(_ *context.T, _ rpc.ServerCall, key string) (byte, error)
-	// Same as Get, but casts the return argument to an int32.
-	GetAsInt32(_ *context.T, _ rpc.ServerCall, key string) (int32, error)
-	// Same as Get, but casts the return argument to an int64.
-	GetAsInt64(_ *context.T, _ rpc.ServerCall, key string) (int64, error)
-	// Same as Get, but casts the return argument to an uint32.
-	GetAsUint32(_ *context.T, _ rpc.ServerCall, key string) (uint32, error)
-	// Same as Get, but casts the return argument to an uint64.
-	GetAsUint64(_ *context.T, _ rpc.ServerCall, key string) (uint64, error)
-	// Same as Get, but casts the return argument to an float32.
-	GetAsFloat32(_ *context.T, _ rpc.ServerCall, key string) (float32, error)
-	// Same as Get, but casts the return argument to an float64.
-	GetAsFloat64(_ *context.T, _ rpc.ServerCall, key string) (float64, error)
-	// Same as Get, but casts the return argument to a string.
-	GetAsString(_ *context.T, _ rpc.ServerCall, key string) (string, error)
-	// Same as Get, but casts the return argument to a bool.
-	GetAsBool(_ *context.T, _ rpc.ServerCall, key string) (bool, error)
-	// Same as Get, but casts the return argument to an error.
-	GetAsError(_ *context.T, _ rpc.ServerCall, key string) (error, error)
-	// AsMap returns the full contents of the cache as a map.
-	AsMap(*context.T, rpc.ServerCall) (map[string]*vom.RawBytes, error)
-	// KeyValuePairs returns the full contents of the cache as a slice of pairs.
-	KeyValuePairs(*context.T, rpc.ServerCall) ([]KeyValuePair, error)
-	// MostRecentSet returns the key and value and the timestamp for the most
-	// recent set operation
-	// TODO(bprosnitz) support type types and change time to native time type
-	MostRecentSet(*context.T, rpc.ServerCall) (value KeyValuePair, time int64, _ error)
-	// KeyPage indexes into the keys (in alphanumerically sorted order) and
-	// returns the indexth page of 10 keys.
-	KeyPage(_ *context.T, _ rpc.ServerCall, index int64) (KeyPageResult, error)
-	// Size returns the total number of entries in the cache.
-	Size(*context.T, rpc.ServerCall) (int64, error)
-	// MultiGet sets up a stream that allows fetching multiple keys.
-	MultiGet(*context.T, CacheMultiGetServerCall) error
-}
-
-// CacheServerStubMethods is the server interface containing
-// Cache methods, as expected by rpc.Server.
-// The only difference between this interface and CacheServerMethods
-// is the streaming methods.
-type CacheServerStubMethods interface {
-	// Set sets a value for a key.
-	Set(_ *context.T, _ rpc.ServerCall, key string, value *vom.RawBytes) error
-	// Get returns the value for a key.  If the value is not found, returns
-	// a not found error.
-	Get(_ *context.T, _ rpc.ServerCall, key string) (*vom.RawBytes, error)
-	// Same as Get, but casts the return argument to an byte.
-	GetAsByte(_ *context.T, _ rpc.ServerCall, key string) (byte, error)
-	// Same as Get, but casts the return argument to an int32.
-	GetAsInt32(_ *context.T, _ rpc.ServerCall, key string) (int32, error)
-	// Same as Get, but casts the return argument to an int64.
-	GetAsInt64(_ *context.T, _ rpc.ServerCall, key string) (int64, error)
-	// Same as Get, but casts the return argument to an uint32.
-	GetAsUint32(_ *context.T, _ rpc.ServerCall, key string) (uint32, error)
-	// Same as Get, but casts the return argument to an uint64.
-	GetAsUint64(_ *context.T, _ rpc.ServerCall, key string) (uint64, error)
-	// Same as Get, but casts the return argument to an float32.
-	GetAsFloat32(_ *context.T, _ rpc.ServerCall, key string) (float32, error)
-	// Same as Get, but casts the return argument to an float64.
-	GetAsFloat64(_ *context.T, _ rpc.ServerCall, key string) (float64, error)
-	// Same as Get, but casts the return argument to a string.
-	GetAsString(_ *context.T, _ rpc.ServerCall, key string) (string, error)
-	// Same as Get, but casts the return argument to a bool.
-	GetAsBool(_ *context.T, _ rpc.ServerCall, key string) (bool, error)
-	// Same as Get, but casts the return argument to an error.
-	GetAsError(_ *context.T, _ rpc.ServerCall, key string) (error, error)
-	// AsMap returns the full contents of the cache as a map.
-	AsMap(*context.T, rpc.ServerCall) (map[string]*vom.RawBytes, error)
-	// KeyValuePairs returns the full contents of the cache as a slice of pairs.
-	KeyValuePairs(*context.T, rpc.ServerCall) ([]KeyValuePair, error)
-	// MostRecentSet returns the key and value and the timestamp for the most
-	// recent set operation
-	// TODO(bprosnitz) support type types and change time to native time type
-	MostRecentSet(*context.T, rpc.ServerCall) (value KeyValuePair, time int64, _ error)
-	// KeyPage indexes into the keys (in alphanumerically sorted order) and
-	// returns the indexth page of 10 keys.
-	KeyPage(_ *context.T, _ rpc.ServerCall, index int64) (KeyPageResult, error)
-	// Size returns the total number of entries in the cache.
-	Size(*context.T, rpc.ServerCall) (int64, error)
-	// MultiGet sets up a stream that allows fetching multiple keys.
-	MultiGet(*context.T, *CacheMultiGetServerCallStub) error
-}
-
-// CacheServerStub adds universal methods to CacheServerStubMethods.
-type CacheServerStub interface {
-	CacheServerStubMethods
-	// Describe the Cache interfaces.
-	Describe__() []rpc.InterfaceDesc
-}
-
-// CacheServer returns a server stub for Cache.
-// It converts an implementation of CacheServerMethods into
-// an object that may be used by rpc.Server.
-func CacheServer(impl CacheServerMethods) CacheServerStub {
-	stub := implCacheServerStub{
-		impl: impl,
-	}
-	// Initialize GlobState; always check the stub itself first, to handle the
-	// case where the user has the Glob method defined in their VDL source.
-	if gs := rpc.NewGlobState(stub); gs != nil {
-		stub.gs = gs
-	} else if gs := rpc.NewGlobState(impl); gs != nil {
-		stub.gs = gs
-	}
-	return stub
-}
-
-type implCacheServerStub struct {
-	impl CacheServerMethods
-	gs   *rpc.GlobState
-}
-
-func (s implCacheServerStub) Set(ctx *context.T, call rpc.ServerCall, i0 string, i1 *vom.RawBytes) error {
-	return s.impl.Set(ctx, call, i0, i1)
-}
-
-func (s implCacheServerStub) Get(ctx *context.T, call rpc.ServerCall, i0 string) (*vom.RawBytes, error) {
-	return s.impl.Get(ctx, call, i0)
-}
-
-func (s implCacheServerStub) GetAsByte(ctx *context.T, call rpc.ServerCall, i0 string) (byte, error) {
-	return s.impl.GetAsByte(ctx, call, i0)
-}
-
-func (s implCacheServerStub) GetAsInt32(ctx *context.T, call rpc.ServerCall, i0 string) (int32, error) {
-	return s.impl.GetAsInt32(ctx, call, i0)
-}
-
-func (s implCacheServerStub) GetAsInt64(ctx *context.T, call rpc.ServerCall, i0 string) (int64, error) {
-	return s.impl.GetAsInt64(ctx, call, i0)
-}
-
-func (s implCacheServerStub) GetAsUint32(ctx *context.T, call rpc.ServerCall, i0 string) (uint32, error) {
-	return s.impl.GetAsUint32(ctx, call, i0)
-}
-
-func (s implCacheServerStub) GetAsUint64(ctx *context.T, call rpc.ServerCall, i0 string) (uint64, error) {
-	return s.impl.GetAsUint64(ctx, call, i0)
-}
-
-func (s implCacheServerStub) GetAsFloat32(ctx *context.T, call rpc.ServerCall, i0 string) (float32, error) {
-	return s.impl.GetAsFloat32(ctx, call, i0)
-}
-
-func (s implCacheServerStub) GetAsFloat64(ctx *context.T, call rpc.ServerCall, i0 string) (float64, error) {
-	return s.impl.GetAsFloat64(ctx, call, i0)
-}
-
-func (s implCacheServerStub) GetAsString(ctx *context.T, call rpc.ServerCall, i0 string) (string, error) {
-	return s.impl.GetAsString(ctx, call, i0)
-}
-
-func (s implCacheServerStub) GetAsBool(ctx *context.T, call rpc.ServerCall, i0 string) (bool, error) {
-	return s.impl.GetAsBool(ctx, call, i0)
-}
-
-func (s implCacheServerStub) GetAsError(ctx *context.T, call rpc.ServerCall, i0 string) (error, error) {
-	return s.impl.GetAsError(ctx, call, i0)
-}
-
-func (s implCacheServerStub) AsMap(ctx *context.T, call rpc.ServerCall) (map[string]*vom.RawBytes, error) {
-	return s.impl.AsMap(ctx, call)
-}
-
-func (s implCacheServerStub) KeyValuePairs(ctx *context.T, call rpc.ServerCall) ([]KeyValuePair, error) {
-	return s.impl.KeyValuePairs(ctx, call)
-}
-
-func (s implCacheServerStub) MostRecentSet(ctx *context.T, call rpc.ServerCall) (KeyValuePair, int64, error) {
-	return s.impl.MostRecentSet(ctx, call)
-}
-
-func (s implCacheServerStub) KeyPage(ctx *context.T, call rpc.ServerCall, i0 int64) (KeyPageResult, error) {
-	return s.impl.KeyPage(ctx, call, i0)
-}
-
-func (s implCacheServerStub) Size(ctx *context.T, call rpc.ServerCall) (int64, error) {
-	return s.impl.Size(ctx, call)
-}
-
-func (s implCacheServerStub) MultiGet(ctx *context.T, call *CacheMultiGetServerCallStub) error {
-	return s.impl.MultiGet(ctx, call)
-}
-
-func (s implCacheServerStub) Globber() *rpc.GlobState {
-	return s.gs
-}
-
-func (s implCacheServerStub) Describe__() []rpc.InterfaceDesc {
-	return []rpc.InterfaceDesc{CacheDesc}
-}
-
-// CacheDesc describes the Cache interface.
-var CacheDesc rpc.InterfaceDesc = descCache
-
-// descCache hides the desc to keep godoc clean.
-var descCache = rpc.InterfaceDesc{
-	Name:    "Cache",
-	PkgPath: "v.io/x/js.core/test_service",
-	Doc:     "// A Cache service mimics the memcache interface.",
-	Methods: []rpc.MethodDesc{
-		{
-			Name: "Set",
-			Doc:  "// Set sets a value for a key.",
-			InArgs: []rpc.ArgDesc{
-				{"key", ``},   // string
-				{"value", ``}, // *vom.RawBytes
-			},
-		},
-		{
-			Name: "Get",
-			Doc:  "// Get returns the value for a key.  If the value is not found, returns\n// a not found error.",
-			InArgs: []rpc.ArgDesc{
-				{"key", ``}, // string
-			},
-			OutArgs: []rpc.ArgDesc{
-				{"", ``}, // *vom.RawBytes
-			},
-		},
-		{
-			Name: "GetAsByte",
-			Doc:  "// Same as Get, but casts the return argument to an byte.",
-			InArgs: []rpc.ArgDesc{
-				{"key", ``}, // string
-			},
-			OutArgs: []rpc.ArgDesc{
-				{"", ``}, // byte
-			},
-		},
-		{
-			Name: "GetAsInt32",
-			Doc:  "// Same as Get, but casts the return argument to an int32.",
-			InArgs: []rpc.ArgDesc{
-				{"key", ``}, // string
-			},
-			OutArgs: []rpc.ArgDesc{
-				{"", ``}, // int32
-			},
-		},
-		{
-			Name: "GetAsInt64",
-			Doc:  "// Same as Get, but casts the return argument to an int64.",
-			InArgs: []rpc.ArgDesc{
-				{"key", ``}, // string
-			},
-			OutArgs: []rpc.ArgDesc{
-				{"", ``}, // int64
-			},
-		},
-		{
-			Name: "GetAsUint32",
-			Doc:  "// Same as Get, but casts the return argument to an uint32.",
-			InArgs: []rpc.ArgDesc{
-				{"key", ``}, // string
-			},
-			OutArgs: []rpc.ArgDesc{
-				{"", ``}, // uint32
-			},
-		},
-		{
-			Name: "GetAsUint64",
-			Doc:  "// Same as Get, but casts the return argument to an uint64.",
-			InArgs: []rpc.ArgDesc{
-				{"key", ``}, // string
-			},
-			OutArgs: []rpc.ArgDesc{
-				{"", ``}, // uint64
-			},
-		},
-		{
-			Name: "GetAsFloat32",
-			Doc:  "// Same as Get, but casts the return argument to an float32.",
-			InArgs: []rpc.ArgDesc{
-				{"key", ``}, // string
-			},
-			OutArgs: []rpc.ArgDesc{
-				{"", ``}, // float32
-			},
-		},
-		{
-			Name: "GetAsFloat64",
-			Doc:  "// Same as Get, but casts the return argument to an float64.",
-			InArgs: []rpc.ArgDesc{
-				{"key", ``}, // string
-			},
-			OutArgs: []rpc.ArgDesc{
-				{"", ``}, // float64
-			},
-		},
-		{
-			Name: "GetAsString",
-			Doc:  "// Same as Get, but casts the return argument to a string.",
-			InArgs: []rpc.ArgDesc{
-				{"key", ``}, // string
-			},
-			OutArgs: []rpc.ArgDesc{
-				{"", ``}, // string
-			},
-		},
-		{
-			Name: "GetAsBool",
-			Doc:  "// Same as Get, but casts the return argument to a bool.",
-			InArgs: []rpc.ArgDesc{
-				{"key", ``}, // string
-			},
-			OutArgs: []rpc.ArgDesc{
-				{"", ``}, // bool
-			},
-		},
-		{
-			Name: "GetAsError",
-			Doc:  "// Same as Get, but casts the return argument to an error.",
-			InArgs: []rpc.ArgDesc{
-				{"key", ``}, // string
-			},
-			OutArgs: []rpc.ArgDesc{
-				{"", ``}, // error
-			},
-		},
-		{
-			Name: "AsMap",
-			Doc:  "// AsMap returns the full contents of the cache as a map.",
-			OutArgs: []rpc.ArgDesc{
-				{"", ``}, // map[string]*vom.RawBytes
-			},
-		},
-		{
-			Name: "KeyValuePairs",
-			Doc:  "// KeyValuePairs returns the full contents of the cache as a slice of pairs.",
-			OutArgs: []rpc.ArgDesc{
-				{"", ``}, // []KeyValuePair
-			},
-		},
-		{
-			Name: "MostRecentSet",
-			Doc:  "// MostRecentSet returns the key and value and the timestamp for the most\n// recent set operation\n// TODO(bprosnitz) support type types and change time to native time type",
-			OutArgs: []rpc.ArgDesc{
-				{"value", ``}, // KeyValuePair
-				{"time", ``},  // int64
-			},
-		},
-		{
-			Name: "KeyPage",
-			Doc:  "// KeyPage indexes into the keys (in alphanumerically sorted order) and\n// returns the indexth page of 10 keys.",
-			InArgs: []rpc.ArgDesc{
-				{"index", ``}, // int64
-			},
-			OutArgs: []rpc.ArgDesc{
-				{"", ``}, // KeyPageResult
-			},
-		},
-		{
-			Name: "Size",
-			Doc:  "// Size returns the total number of entries in the cache.",
-			OutArgs: []rpc.ArgDesc{
-				{"", ``}, // int64
-			},
-		},
-		{
-			Name: "MultiGet",
-			Doc:  "// MultiGet sets up a stream that allows fetching multiple keys.",
-		},
-	},
-}
-
-// CacheMultiGetServerStream is the server stream for Cache.MultiGet.
-type CacheMultiGetServerStream interface {
-	// RecvStream returns the receiver side of the Cache.MultiGet server stream.
-	RecvStream() interface {
-		// Advance stages an item so that it may be retrieved via Value.  Returns
-		// true iff there is an item to retrieve.  Advance must be called before
-		// Value is called.  May block if an item is not available.
-		Advance() bool
-		// Value returns the item that was staged by Advance.  May panic if Advance
-		// returned false or was not called.  Never blocks.
-		Value() string
-		// Err returns any error encountered by Advance.  Never blocks.
-		Err() error
-	}
-	// SendStream returns the send side of the Cache.MultiGet server stream.
-	SendStream() interface {
-		// Send places the item onto the output stream.  Returns errors encountered
-		// while sending.  Blocks if there is no buffer space; will unblock when
-		// buffer space is available.
-		Send(item *vom.RawBytes) error
-	}
-}
-
-// CacheMultiGetServerCall represents the context passed to Cache.MultiGet.
-type CacheMultiGetServerCall interface {
-	rpc.ServerCall
-	CacheMultiGetServerStream
-}
-
-// CacheMultiGetServerCallStub is a wrapper that converts rpc.StreamServerCall into
-// a typesafe stub that implements CacheMultiGetServerCall.
-type CacheMultiGetServerCallStub struct {
-	rpc.StreamServerCall
-	valRecv string
-	errRecv error
-}
-
-// Init initializes CacheMultiGetServerCallStub from rpc.StreamServerCall.
-func (s *CacheMultiGetServerCallStub) Init(call rpc.StreamServerCall) {
-	s.StreamServerCall = call
-}
-
-// RecvStream returns the receiver side of the Cache.MultiGet server stream.
-func (s *CacheMultiGetServerCallStub) RecvStream() interface {
-	Advance() bool
-	Value() string
-	Err() error
-} {
-	return implCacheMultiGetServerCallRecv{s}
-}
-
-type implCacheMultiGetServerCallRecv struct {
-	s *CacheMultiGetServerCallStub
-}
-
-func (s implCacheMultiGetServerCallRecv) Advance() bool {
-	s.s.errRecv = s.s.Recv(&s.s.valRecv)
-	return s.s.errRecv == nil
-}
-func (s implCacheMultiGetServerCallRecv) Value() string {
-	return s.s.valRecv
-}
-func (s implCacheMultiGetServerCallRecv) Err() error {
-	if s.s.errRecv == io.EOF {
-		return nil
-	}
-	return s.s.errRecv
-}
-
-// SendStream returns the send side of the Cache.MultiGet server stream.
-func (s *CacheMultiGetServerCallStub) SendStream() interface {
-	Send(item *vom.RawBytes) error
-} {
-	return implCacheMultiGetServerCallSend{s}
-}
-
-type implCacheMultiGetServerCallSend struct {
-	s *CacheMultiGetServerCallStub
-}
-
-func (s implCacheMultiGetServerCallSend) Send(item *vom.RawBytes) error {
-	return s.s.Send(item)
-}
diff --git a/go/src/v.io/x/js.core/test_service/cancel_collector.vdl.go b/go/src/v.io/x/js.core/test_service/cancel_collector.vdl.go
deleted file mode 100644
index 756e309..0000000
--- a/go/src/v.io/x/js.core/test_service/cancel_collector.vdl.go
+++ /dev/null
@@ -1,149 +0,0 @@
-// Copyright 2015 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file was auto-generated by the vanadium vdl tool.
-// Source: cancel_collector.vdl
-
-package test_service
-
-import (
-	"v.io/v23"
-	"v.io/v23/context"
-	"v.io/v23/rpc"
-)
-
-func __VDLEnsureNativeBuilt_cancel_collector() {
-}
-
-// CancelCollectorClientMethods is the client interface
-// containing CancelCollector methods.
-//
-// CancelCollector is a test interface for use in testing cancellation and deadlines.
-type CancelCollectorClientMethods interface {
-	// A function that never returns, but records the status of the given key.
-	NeverReturn(_ *context.T, key int64, _ ...rpc.CallOpt) error
-	// Wait for the call with the given key to have the given status.  Possible statuses are:
-	// "running", and, "cancelled".  Returns the number of nanoseconds left on
-	// the deadline of the specified call when the call first began.
-	WaitForStatus(_ *context.T, key int64, status string, _ ...rpc.CallOpt) (timeout int64, _ error)
-}
-
-// CancelCollectorClientStub adds universal methods to CancelCollectorClientMethods.
-type CancelCollectorClientStub interface {
-	CancelCollectorClientMethods
-	rpc.UniversalServiceMethods
-}
-
-// CancelCollectorClient returns a client stub for CancelCollector.
-func CancelCollectorClient(name string) CancelCollectorClientStub {
-	return implCancelCollectorClientStub{name}
-}
-
-type implCancelCollectorClientStub struct {
-	name string
-}
-
-func (c implCancelCollectorClientStub) NeverReturn(ctx *context.T, i0 int64, opts ...rpc.CallOpt) (err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "NeverReturn", []interface{}{i0}, nil, opts...)
-	return
-}
-
-func (c implCancelCollectorClientStub) WaitForStatus(ctx *context.T, i0 int64, i1 string, opts ...rpc.CallOpt) (o0 int64, err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "WaitForStatus", []interface{}{i0, i1}, []interface{}{&o0}, opts...)
-	return
-}
-
-// CancelCollectorServerMethods is the interface a server writer
-// implements for CancelCollector.
-//
-// CancelCollector is a test interface for use in testing cancellation and deadlines.
-type CancelCollectorServerMethods interface {
-	// A function that never returns, but records the status of the given key.
-	NeverReturn(_ *context.T, _ rpc.ServerCall, key int64) error
-	// Wait for the call with the given key to have the given status.  Possible statuses are:
-	// "running", and, "cancelled".  Returns the number of nanoseconds left on
-	// the deadline of the specified call when the call first began.
-	WaitForStatus(_ *context.T, _ rpc.ServerCall, key int64, status string) (timeout int64, _ error)
-}
-
-// CancelCollectorServerStubMethods is the server interface containing
-// CancelCollector methods, as expected by rpc.Server.
-// There is no difference between this interface and CancelCollectorServerMethods
-// since there are no streaming methods.
-type CancelCollectorServerStubMethods CancelCollectorServerMethods
-
-// CancelCollectorServerStub adds universal methods to CancelCollectorServerStubMethods.
-type CancelCollectorServerStub interface {
-	CancelCollectorServerStubMethods
-	// Describe the CancelCollector interfaces.
-	Describe__() []rpc.InterfaceDesc
-}
-
-// CancelCollectorServer returns a server stub for CancelCollector.
-// It converts an implementation of CancelCollectorServerMethods into
-// an object that may be used by rpc.Server.
-func CancelCollectorServer(impl CancelCollectorServerMethods) CancelCollectorServerStub {
-	stub := implCancelCollectorServerStub{
-		impl: impl,
-	}
-	// Initialize GlobState; always check the stub itself first, to handle the
-	// case where the user has the Glob method defined in their VDL source.
-	if gs := rpc.NewGlobState(stub); gs != nil {
-		stub.gs = gs
-	} else if gs := rpc.NewGlobState(impl); gs != nil {
-		stub.gs = gs
-	}
-	return stub
-}
-
-type implCancelCollectorServerStub struct {
-	impl CancelCollectorServerMethods
-	gs   *rpc.GlobState
-}
-
-func (s implCancelCollectorServerStub) NeverReturn(ctx *context.T, call rpc.ServerCall, i0 int64) error {
-	return s.impl.NeverReturn(ctx, call, i0)
-}
-
-func (s implCancelCollectorServerStub) WaitForStatus(ctx *context.T, call rpc.ServerCall, i0 int64, i1 string) (int64, error) {
-	return s.impl.WaitForStatus(ctx, call, i0, i1)
-}
-
-func (s implCancelCollectorServerStub) Globber() *rpc.GlobState {
-	return s.gs
-}
-
-func (s implCancelCollectorServerStub) Describe__() []rpc.InterfaceDesc {
-	return []rpc.InterfaceDesc{CancelCollectorDesc}
-}
-
-// CancelCollectorDesc describes the CancelCollector interface.
-var CancelCollectorDesc rpc.InterfaceDesc = descCancelCollector
-
-// descCancelCollector hides the desc to keep godoc clean.
-var descCancelCollector = rpc.InterfaceDesc{
-	Name:    "CancelCollector",
-	PkgPath: "v.io/x/js.core/test_service",
-	Doc:     "// CancelCollector is a test interface for use in testing cancellation and deadlines.",
-	Methods: []rpc.MethodDesc{
-		{
-			Name: "NeverReturn",
-			Doc:  "// A function that never returns, but records the status of the given key.",
-			InArgs: []rpc.ArgDesc{
-				{"key", ``}, // int64
-			},
-		},
-		{
-			Name: "WaitForStatus",
-			Doc:  "// Wait for the call with the given key to have the given status.  Possible statuses are:\n// \"running\", and, \"cancelled\".  Returns the number of nanoseconds left on\n// the deadline of the specified call when the call first began.",
-			InArgs: []rpc.ArgDesc{
-				{"key", ``},    // int64
-				{"status", ``}, // string
-			},
-			OutArgs: []rpc.ArgDesc{
-				{"timeout", ``}, // int64
-			},
-		},
-	},
-}
diff --git a/go/src/v.io/x/js.core/test_service/error_thrower.vdl.go b/go/src/v.io/x/js.core/test_service/error_thrower.vdl.go
deleted file mode 100644
index dd79a5b..0000000
--- a/go/src/v.io/x/js.core/test_service/error_thrower.vdl.go
+++ /dev/null
@@ -1,271 +0,0 @@
-// Copyright 2015 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file was auto-generated by the vanadium vdl tool.
-// Source: error_thrower.vdl
-
-package test_service
-
-import (
-	"v.io/v23"
-	"v.io/v23/context"
-	"v.io/v23/rpc"
-)
-
-func __VDLEnsureNativeBuilt_error_thrower() {
-}
-
-// ErrorThrowerClientMethods is the client interface
-// containing ErrorThrower methods.
-//
-// A testing interface with methods that throw various types of errors
-type ErrorThrowerClientMethods interface {
-	// Throws v23/vError.Aborted error
-	ThrowAborted(*context.T, ...rpc.CallOpt) error
-	// Throws v23/vError.BadArg error
-	ThrowBadArg(*context.T, ...rpc.CallOpt) error
-	// Throws v23/vError.BadProtocol error
-	ThrowBadProtocol(*context.T, ...rpc.CallOpt) error
-	// Throws v23/vError.Internal error
-	ThrowInternal(*context.T, ...rpc.CallOpt) error
-	// Throws v23/vError.NoAccess error
-	ThrowNoAccess(*context.T, ...rpc.CallOpt) error
-	// Throws v23/vError.NoExist error
-	ThrowNoExist(*context.T, ...rpc.CallOpt) error
-	// Throws v23/vError.NoExistOrNoAccess error
-	ThrowNoExistOrNoAccess(*context.T, ...rpc.CallOpt) error
-	// Throws v23/vError.Unknown error
-	ThrowUnknown(*context.T, ...rpc.CallOpt) error
-	// Throws normal Go error
-	ThrowGoError(*context.T, ...rpc.CallOpt) error
-	// Throws custom error created by using Standard
-	ThrowCustomStandardError(*context.T, ...rpc.CallOpt) error
-}
-
-// ErrorThrowerClientStub adds universal methods to ErrorThrowerClientMethods.
-type ErrorThrowerClientStub interface {
-	ErrorThrowerClientMethods
-	rpc.UniversalServiceMethods
-}
-
-// ErrorThrowerClient returns a client stub for ErrorThrower.
-func ErrorThrowerClient(name string) ErrorThrowerClientStub {
-	return implErrorThrowerClientStub{name}
-}
-
-type implErrorThrowerClientStub struct {
-	name string
-}
-
-func (c implErrorThrowerClientStub) ThrowAborted(ctx *context.T, opts ...rpc.CallOpt) (err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "ThrowAborted", nil, nil, opts...)
-	return
-}
-
-func (c implErrorThrowerClientStub) ThrowBadArg(ctx *context.T, opts ...rpc.CallOpt) (err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "ThrowBadArg", nil, nil, opts...)
-	return
-}
-
-func (c implErrorThrowerClientStub) ThrowBadProtocol(ctx *context.T, opts ...rpc.CallOpt) (err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "ThrowBadProtocol", nil, nil, opts...)
-	return
-}
-
-func (c implErrorThrowerClientStub) ThrowInternal(ctx *context.T, opts ...rpc.CallOpt) (err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "ThrowInternal", nil, nil, opts...)
-	return
-}
-
-func (c implErrorThrowerClientStub) ThrowNoAccess(ctx *context.T, opts ...rpc.CallOpt) (err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "ThrowNoAccess", nil, nil, opts...)
-	return
-}
-
-func (c implErrorThrowerClientStub) ThrowNoExist(ctx *context.T, opts ...rpc.CallOpt) (err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "ThrowNoExist", nil, nil, opts...)
-	return
-}
-
-func (c implErrorThrowerClientStub) ThrowNoExistOrNoAccess(ctx *context.T, opts ...rpc.CallOpt) (err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "ThrowNoExistOrNoAccess", nil, nil, opts...)
-	return
-}
-
-func (c implErrorThrowerClientStub) ThrowUnknown(ctx *context.T, opts ...rpc.CallOpt) (err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "ThrowUnknown", nil, nil, opts...)
-	return
-}
-
-func (c implErrorThrowerClientStub) ThrowGoError(ctx *context.T, opts ...rpc.CallOpt) (err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "ThrowGoError", nil, nil, opts...)
-	return
-}
-
-func (c implErrorThrowerClientStub) ThrowCustomStandardError(ctx *context.T, opts ...rpc.CallOpt) (err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "ThrowCustomStandardError", nil, nil, opts...)
-	return
-}
-
-// ErrorThrowerServerMethods is the interface a server writer
-// implements for ErrorThrower.
-//
-// A testing interface with methods that throw various types of errors
-type ErrorThrowerServerMethods interface {
-	// Throws v23/vError.Aborted error
-	ThrowAborted(*context.T, rpc.ServerCall) error
-	// Throws v23/vError.BadArg error
-	ThrowBadArg(*context.T, rpc.ServerCall) error
-	// Throws v23/vError.BadProtocol error
-	ThrowBadProtocol(*context.T, rpc.ServerCall) error
-	// Throws v23/vError.Internal error
-	ThrowInternal(*context.T, rpc.ServerCall) error
-	// Throws v23/vError.NoAccess error
-	ThrowNoAccess(*context.T, rpc.ServerCall) error
-	// Throws v23/vError.NoExist error
-	ThrowNoExist(*context.T, rpc.ServerCall) error
-	// Throws v23/vError.NoExistOrNoAccess error
-	ThrowNoExistOrNoAccess(*context.T, rpc.ServerCall) error
-	// Throws v23/vError.Unknown error
-	ThrowUnknown(*context.T, rpc.ServerCall) error
-	// Throws normal Go error
-	ThrowGoError(*context.T, rpc.ServerCall) error
-	// Throws custom error created by using Standard
-	ThrowCustomStandardError(*context.T, rpc.ServerCall) error
-}
-
-// ErrorThrowerServerStubMethods is the server interface containing
-// ErrorThrower methods, as expected by rpc.Server.
-// There is no difference between this interface and ErrorThrowerServerMethods
-// since there are no streaming methods.
-type ErrorThrowerServerStubMethods ErrorThrowerServerMethods
-
-// ErrorThrowerServerStub adds universal methods to ErrorThrowerServerStubMethods.
-type ErrorThrowerServerStub interface {
-	ErrorThrowerServerStubMethods
-	// Describe the ErrorThrower interfaces.
-	Describe__() []rpc.InterfaceDesc
-}
-
-// ErrorThrowerServer returns a server stub for ErrorThrower.
-// It converts an implementation of ErrorThrowerServerMethods into
-// an object that may be used by rpc.Server.
-func ErrorThrowerServer(impl ErrorThrowerServerMethods) ErrorThrowerServerStub {
-	stub := implErrorThrowerServerStub{
-		impl: impl,
-	}
-	// Initialize GlobState; always check the stub itself first, to handle the
-	// case where the user has the Glob method defined in their VDL source.
-	if gs := rpc.NewGlobState(stub); gs != nil {
-		stub.gs = gs
-	} else if gs := rpc.NewGlobState(impl); gs != nil {
-		stub.gs = gs
-	}
-	return stub
-}
-
-type implErrorThrowerServerStub struct {
-	impl ErrorThrowerServerMethods
-	gs   *rpc.GlobState
-}
-
-func (s implErrorThrowerServerStub) ThrowAborted(ctx *context.T, call rpc.ServerCall) error {
-	return s.impl.ThrowAborted(ctx, call)
-}
-
-func (s implErrorThrowerServerStub) ThrowBadArg(ctx *context.T, call rpc.ServerCall) error {
-	return s.impl.ThrowBadArg(ctx, call)
-}
-
-func (s implErrorThrowerServerStub) ThrowBadProtocol(ctx *context.T, call rpc.ServerCall) error {
-	return s.impl.ThrowBadProtocol(ctx, call)
-}
-
-func (s implErrorThrowerServerStub) ThrowInternal(ctx *context.T, call rpc.ServerCall) error {
-	return s.impl.ThrowInternal(ctx, call)
-}
-
-func (s implErrorThrowerServerStub) ThrowNoAccess(ctx *context.T, call rpc.ServerCall) error {
-	return s.impl.ThrowNoAccess(ctx, call)
-}
-
-func (s implErrorThrowerServerStub) ThrowNoExist(ctx *context.T, call rpc.ServerCall) error {
-	return s.impl.ThrowNoExist(ctx, call)
-}
-
-func (s implErrorThrowerServerStub) ThrowNoExistOrNoAccess(ctx *context.T, call rpc.ServerCall) error {
-	return s.impl.ThrowNoExistOrNoAccess(ctx, call)
-}
-
-func (s implErrorThrowerServerStub) ThrowUnknown(ctx *context.T, call rpc.ServerCall) error {
-	return s.impl.ThrowUnknown(ctx, call)
-}
-
-func (s implErrorThrowerServerStub) ThrowGoError(ctx *context.T, call rpc.ServerCall) error {
-	return s.impl.ThrowGoError(ctx, call)
-}
-
-func (s implErrorThrowerServerStub) ThrowCustomStandardError(ctx *context.T, call rpc.ServerCall) error {
-	return s.impl.ThrowCustomStandardError(ctx, call)
-}
-
-func (s implErrorThrowerServerStub) Globber() *rpc.GlobState {
-	return s.gs
-}
-
-func (s implErrorThrowerServerStub) Describe__() []rpc.InterfaceDesc {
-	return []rpc.InterfaceDesc{ErrorThrowerDesc}
-}
-
-// ErrorThrowerDesc describes the ErrorThrower interface.
-var ErrorThrowerDesc rpc.InterfaceDesc = descErrorThrower
-
-// descErrorThrower hides the desc to keep godoc clean.
-var descErrorThrower = rpc.InterfaceDesc{
-	Name:    "ErrorThrower",
-	PkgPath: "v.io/x/js.core/test_service",
-	Doc:     "// A testing interface with methods that throw various types of errors",
-	Methods: []rpc.MethodDesc{
-		{
-			Name: "ThrowAborted",
-			Doc:  "// Throws v23/vError.Aborted error",
-		},
-		{
-			Name: "ThrowBadArg",
-			Doc:  "// Throws v23/vError.BadArg error",
-		},
-		{
-			Name: "ThrowBadProtocol",
-			Doc:  "// Throws v23/vError.BadProtocol error",
-		},
-		{
-			Name: "ThrowInternal",
-			Doc:  "// Throws v23/vError.Internal error",
-		},
-		{
-			Name: "ThrowNoAccess",
-			Doc:  "// Throws v23/vError.NoAccess error",
-		},
-		{
-			Name: "ThrowNoExist",
-			Doc:  "// Throws v23/vError.NoExist error",
-		},
-		{
-			Name: "ThrowNoExistOrNoAccess",
-			Doc:  "// Throws v23/vError.NoExistOrNoAccess error",
-		},
-		{
-			Name: "ThrowUnknown",
-			Doc:  "// Throws v23/vError.Unknown error",
-		},
-		{
-			Name: "ThrowGoError",
-			Doc:  "// Throws normal Go error",
-		},
-		{
-			Name: "ThrowCustomStandardError",
-			Doc:  "// Throws custom error created by using Standard",
-		},
-	},
-}
diff --git a/go/src/v.io/x/js.core/test_service/invoke_method_caveat_id.vdl.go b/go/src/v.io/x/js.core/test_service/invoke_method_caveat_id.vdl.go
deleted file mode 100644
index 0728642..0000000
--- a/go/src/v.io/x/js.core/test_service/invoke_method_caveat_id.vdl.go
+++ /dev/null
@@ -1,338 +0,0 @@
-// Copyright 2015 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file was auto-generated by the vanadium vdl tool.
-// Source: invoke_method_caveat_id.vdl
-
-package test_service
-
-import (
-	"fmt"
-	"reflect"
-	"v.io/v23"
-	"v.io/v23/context"
-	"v.io/v23/rpc"
-	"v.io/v23/security"
-	"v.io/v23/uniqueid"
-	"v.io/v23/vdl"
-	"v.io/v23/vom"
-)
-
-type TestCaveatData struct {
-	A string
-	B *vom.RawBytes // Use any for value so that we can confirm VDL is being used properly.
-}
-
-func (TestCaveatData) __VDLReflect(struct {
-	Name string `vdl:"v.io/x/js.core/test_service.TestCaveatData"`
-}) {
-}
-
-func (m *TestCaveatData) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-	if __VDLType_invoke_method_caveat_id_v_io_x_js_core_test_service_TestCaveatData == nil || __VDLTypeinvoke_method_caveat_id0 == nil {
-		panic("Initialization order error: types generated for FillVDLTarget not initialized. Consider moving caller to an init() block.")
-	}
-	fieldsTarget1, err := t.StartFields(tt)
-	if err != nil {
-		return err
-	}
-
-	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("A")
-	if err != vdl.ErrFieldNoExist && err != nil {
-		return err
-	}
-	if err != vdl.ErrFieldNoExist {
-		if err := fieldTarget3.FromString(string(m.A), vdl.StringType); err != nil {
-			return err
-		}
-		if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
-			return err
-		}
-	}
-	keyTarget4, fieldTarget5, err := fieldsTarget1.StartField("B")
-	if err != vdl.ErrFieldNoExist && err != nil {
-		return err
-	}
-	if err != vdl.ErrFieldNoExist {
-
-		if m.B == nil {
-			if err := fieldTarget5.FromNil(vdl.AnyType); err != nil {
-				return err
-			}
-		} else {
-			if err := m.B.FillVDLTarget(fieldTarget5, vdl.AnyType); err != nil {
-				return err
-			}
-		}
-		if err := fieldsTarget1.FinishField(keyTarget4, fieldTarget5); err != nil {
-			return err
-		}
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (m *TestCaveatData) MakeVDLTarget() vdl.Target {
-	return &TestCaveatDataTarget{Value: m}
-}
-
-type TestCaveatDataTarget struct {
-	Value *TestCaveatData
-	vdl.TargetBase
-	vdl.FieldsTargetBase
-}
-
-func (t *TestCaveatDataTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {
-	if !vdl.Compatible(tt, __VDLType_invoke_method_caveat_id_v_io_x_js_core_test_service_TestCaveatData) {
-		return nil, fmt.Errorf("type %v incompatible with %v", tt, __VDLType_invoke_method_caveat_id_v_io_x_js_core_test_service_TestCaveatData)
-	}
-	return t, nil
-}
-func (t *TestCaveatDataTarget) StartField(name string) (key, field vdl.Target, _ error) {
-	switch name {
-	case "A":
-		val, err := &vdl.StringTarget{Value: &t.Value.A}, error(nil)
-		return nil, val, err
-	case "B":
-		val, err := vdl.ReflectTarget(reflect.ValueOf(&t.Value.B))
-		return nil, val, err
-	default:
-		return nil, nil, fmt.Errorf("field %s not in struct %v", name, __VDLType_invoke_method_caveat_id_v_io_x_js_core_test_service_TestCaveatData)
-	}
-}
-func (t *TestCaveatDataTarget) FinishField(_, _ vdl.Target) error {
-	return nil
-}
-func (t *TestCaveatDataTarget) FinishFields(_ vdl.FieldsTarget) error {
-
-	return nil
-}
-
-func init() {
-	vdl.Register((*TestCaveatData)(nil))
-}
-
-var __VDLTypeinvoke_method_caveat_id0 *vdl.Type = vdl.TypeOf((*TestCaveatData)(nil))
-var __VDLType_invoke_method_caveat_id_v_io_x_js_core_test_service_TestCaveatData *vdl.Type = vdl.TypeOf(TestCaveatData{})
-
-func __VDLEnsureNativeBuilt_invoke_method_caveat_id() {
-}
-
-var ConditionallyValidatingTestCaveat = security.CaveatDescriptor{
-	Id: uniqueid.Id{
-		0,
-		17,
-		34,
-		51,
-		68,
-		85,
-		102,
-		119,
-		136,
-		153,
-		170,
-		187,
-		204,
-		221,
-		238,
-		255,
-	},
-	ParamType: vdl.TypeOf(TestCaveatData{}),
-}
-
-// InvokableTestMethodClientMethods is the client interface
-// containing InvokableTestMethod methods.
-type InvokableTestMethodClientMethods interface {
-	AMethod(*context.T, ...rpc.CallOpt) (string, error)
-}
-
-// InvokableTestMethodClientStub adds universal methods to InvokableTestMethodClientMethods.
-type InvokableTestMethodClientStub interface {
-	InvokableTestMethodClientMethods
-	rpc.UniversalServiceMethods
-}
-
-// InvokableTestMethodClient returns a client stub for InvokableTestMethod.
-func InvokableTestMethodClient(name string) InvokableTestMethodClientStub {
-	return implInvokableTestMethodClientStub{name}
-}
-
-type implInvokableTestMethodClientStub struct {
-	name string
-}
-
-func (c implInvokableTestMethodClientStub) AMethod(ctx *context.T, opts ...rpc.CallOpt) (o0 string, err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "AMethod", nil, []interface{}{&o0}, opts...)
-	return
-}
-
-// InvokableTestMethodServerMethods is the interface a server writer
-// implements for InvokableTestMethod.
-type InvokableTestMethodServerMethods interface {
-	AMethod(*context.T, rpc.ServerCall) (string, error)
-}
-
-// InvokableTestMethodServerStubMethods is the server interface containing
-// InvokableTestMethod methods, as expected by rpc.Server.
-// There is no difference between this interface and InvokableTestMethodServerMethods
-// since there are no streaming methods.
-type InvokableTestMethodServerStubMethods InvokableTestMethodServerMethods
-
-// InvokableTestMethodServerStub adds universal methods to InvokableTestMethodServerStubMethods.
-type InvokableTestMethodServerStub interface {
-	InvokableTestMethodServerStubMethods
-	// Describe the InvokableTestMethod interfaces.
-	Describe__() []rpc.InterfaceDesc
-}
-
-// InvokableTestMethodServer returns a server stub for InvokableTestMethod.
-// It converts an implementation of InvokableTestMethodServerMethods into
-// an object that may be used by rpc.Server.
-func InvokableTestMethodServer(impl InvokableTestMethodServerMethods) InvokableTestMethodServerStub {
-	stub := implInvokableTestMethodServerStub{
-		impl: impl,
-	}
-	// Initialize GlobState; always check the stub itself first, to handle the
-	// case where the user has the Glob method defined in their VDL source.
-	if gs := rpc.NewGlobState(stub); gs != nil {
-		stub.gs = gs
-	} else if gs := rpc.NewGlobState(impl); gs != nil {
-		stub.gs = gs
-	}
-	return stub
-}
-
-type implInvokableTestMethodServerStub struct {
-	impl InvokableTestMethodServerMethods
-	gs   *rpc.GlobState
-}
-
-func (s implInvokableTestMethodServerStub) AMethod(ctx *context.T, call rpc.ServerCall) (string, error) {
-	return s.impl.AMethod(ctx, call)
-}
-
-func (s implInvokableTestMethodServerStub) Globber() *rpc.GlobState {
-	return s.gs
-}
-
-func (s implInvokableTestMethodServerStub) Describe__() []rpc.InterfaceDesc {
-	return []rpc.InterfaceDesc{InvokableTestMethodDesc}
-}
-
-// InvokableTestMethodDesc describes the InvokableTestMethod interface.
-var InvokableTestMethodDesc rpc.InterfaceDesc = descInvokableTestMethod
-
-// descInvokableTestMethod hides the desc to keep godoc clean.
-var descInvokableTestMethod = rpc.InterfaceDesc{
-	Name:    "InvokableTestMethod",
-	PkgPath: "v.io/x/js.core/test_service",
-	Methods: []rpc.MethodDesc{
-		{
-			Name: "AMethod",
-			OutArgs: []rpc.ArgDesc{
-				{"", ``}, // string
-			},
-		},
-	},
-}
-
-// InvokeMethodWithCaveatedIdentityClientMethods is the client interface
-// containing InvokeMethodWithCaveatedIdentity methods.
-type InvokeMethodWithCaveatedIdentityClientMethods interface {
-	Invoke(_ *context.T, name string, cavDesc security.CaveatDescriptor, cavParam *vom.RawBytes, _ ...rpc.CallOpt) error
-}
-
-// InvokeMethodWithCaveatedIdentityClientStub adds universal methods to InvokeMethodWithCaveatedIdentityClientMethods.
-type InvokeMethodWithCaveatedIdentityClientStub interface {
-	InvokeMethodWithCaveatedIdentityClientMethods
-	rpc.UniversalServiceMethods
-}
-
-// InvokeMethodWithCaveatedIdentityClient returns a client stub for InvokeMethodWithCaveatedIdentity.
-func InvokeMethodWithCaveatedIdentityClient(name string) InvokeMethodWithCaveatedIdentityClientStub {
-	return implInvokeMethodWithCaveatedIdentityClientStub{name}
-}
-
-type implInvokeMethodWithCaveatedIdentityClientStub struct {
-	name string
-}
-
-func (c implInvokeMethodWithCaveatedIdentityClientStub) Invoke(ctx *context.T, i0 string, i1 security.CaveatDescriptor, i2 *vom.RawBytes, opts ...rpc.CallOpt) (err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "Invoke", []interface{}{i0, i1, i2}, nil, opts...)
-	return
-}
-
-// InvokeMethodWithCaveatedIdentityServerMethods is the interface a server writer
-// implements for InvokeMethodWithCaveatedIdentity.
-type InvokeMethodWithCaveatedIdentityServerMethods interface {
-	Invoke(_ *context.T, _ rpc.ServerCall, name string, cavDesc security.CaveatDescriptor, cavParam *vom.RawBytes) error
-}
-
-// InvokeMethodWithCaveatedIdentityServerStubMethods is the server interface containing
-// InvokeMethodWithCaveatedIdentity methods, as expected by rpc.Server.
-// There is no difference between this interface and InvokeMethodWithCaveatedIdentityServerMethods
-// since there are no streaming methods.
-type InvokeMethodWithCaveatedIdentityServerStubMethods InvokeMethodWithCaveatedIdentityServerMethods
-
-// InvokeMethodWithCaveatedIdentityServerStub adds universal methods to InvokeMethodWithCaveatedIdentityServerStubMethods.
-type InvokeMethodWithCaveatedIdentityServerStub interface {
-	InvokeMethodWithCaveatedIdentityServerStubMethods
-	// Describe the InvokeMethodWithCaveatedIdentity interfaces.
-	Describe__() []rpc.InterfaceDesc
-}
-
-// InvokeMethodWithCaveatedIdentityServer returns a server stub for InvokeMethodWithCaveatedIdentity.
-// It converts an implementation of InvokeMethodWithCaveatedIdentityServerMethods into
-// an object that may be used by rpc.Server.
-func InvokeMethodWithCaveatedIdentityServer(impl InvokeMethodWithCaveatedIdentityServerMethods) InvokeMethodWithCaveatedIdentityServerStub {
-	stub := implInvokeMethodWithCaveatedIdentityServerStub{
-		impl: impl,
-	}
-	// Initialize GlobState; always check the stub itself first, to handle the
-	// case where the user has the Glob method defined in their VDL source.
-	if gs := rpc.NewGlobState(stub); gs != nil {
-		stub.gs = gs
-	} else if gs := rpc.NewGlobState(impl); gs != nil {
-		stub.gs = gs
-	}
-	return stub
-}
-
-type implInvokeMethodWithCaveatedIdentityServerStub struct {
-	impl InvokeMethodWithCaveatedIdentityServerMethods
-	gs   *rpc.GlobState
-}
-
-func (s implInvokeMethodWithCaveatedIdentityServerStub) Invoke(ctx *context.T, call rpc.ServerCall, i0 string, i1 security.CaveatDescriptor, i2 *vom.RawBytes) error {
-	return s.impl.Invoke(ctx, call, i0, i1, i2)
-}
-
-func (s implInvokeMethodWithCaveatedIdentityServerStub) Globber() *rpc.GlobState {
-	return s.gs
-}
-
-func (s implInvokeMethodWithCaveatedIdentityServerStub) Describe__() []rpc.InterfaceDesc {
-	return []rpc.InterfaceDesc{InvokeMethodWithCaveatedIdentityDesc}
-}
-
-// InvokeMethodWithCaveatedIdentityDesc describes the InvokeMethodWithCaveatedIdentity interface.
-var InvokeMethodWithCaveatedIdentityDesc rpc.InterfaceDesc = descInvokeMethodWithCaveatedIdentity
-
-// descInvokeMethodWithCaveatedIdentity hides the desc to keep godoc clean.
-var descInvokeMethodWithCaveatedIdentity = rpc.InterfaceDesc{
-	Name:    "InvokeMethodWithCaveatedIdentity",
-	PkgPath: "v.io/x/js.core/test_service",
-	Methods: []rpc.MethodDesc{
-		{
-			Name: "Invoke",
-			InArgs: []rpc.ArgDesc{
-				{"name", ``},     // string
-				{"cavDesc", ``},  // security.CaveatDescriptor
-				{"cavParam", ``}, // *vom.RawBytes
-			},
-		},
-	},
-}
diff --git a/go/src/v.io/x/js.core/test_service/native.vdl.go b/go/src/v.io/x/js.core/test_service/native.vdl.go
deleted file mode 100644
index 2a53e3b..0000000
--- a/go/src/v.io/x/js.core/test_service/native.vdl.go
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright 2015 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file was auto-generated by the vanadium vdl tool.
-// Source: native.vdl
-
-package test_service
-
-import (
-	"time"
-	"v.io/v23"
-	"v.io/v23/context"
-	"v.io/v23/rpc"
-	_ "v.io/v23/vdlroot/time"
-)
-
-func __VDLEnsureNativeBuilt_native() {
-}
-
-// NativeTestClientMethods is the client interface
-// containing NativeTest methods.
-type NativeTestClientMethods interface {
-	PassTime(_ *context.T, t time.Time, _ ...rpc.CallOpt) (time.Time, error)
-	PassError(_ *context.T, e error, _ ...rpc.CallOpt) error
-}
-
-// NativeTestClientStub adds universal methods to NativeTestClientMethods.
-type NativeTestClientStub interface {
-	NativeTestClientMethods
-	rpc.UniversalServiceMethods
-}
-
-// NativeTestClient returns a client stub for NativeTest.
-func NativeTestClient(name string) NativeTestClientStub {
-	return implNativeTestClientStub{name}
-}
-
-type implNativeTestClientStub struct {
-	name string
-}
-
-func (c implNativeTestClientStub) PassTime(ctx *context.T, i0 time.Time, opts ...rpc.CallOpt) (o0 time.Time, err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "PassTime", []interface{}{i0}, []interface{}{&o0}, opts...)
-	return
-}
-
-func (c implNativeTestClientStub) PassError(ctx *context.T, i0 error, opts ...rpc.CallOpt) (err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "PassError", []interface{}{&i0}, nil, opts...)
-	return
-}
-
-// NativeTestServerMethods is the interface a server writer
-// implements for NativeTest.
-type NativeTestServerMethods interface {
-	PassTime(_ *context.T, _ rpc.ServerCall, t time.Time) (time.Time, error)
-	PassError(_ *context.T, _ rpc.ServerCall, e error) error
-}
-
-// NativeTestServerStubMethods is the server interface containing
-// NativeTest methods, as expected by rpc.Server.
-// There is no difference between this interface and NativeTestServerMethods
-// since there are no streaming methods.
-type NativeTestServerStubMethods NativeTestServerMethods
-
-// NativeTestServerStub adds universal methods to NativeTestServerStubMethods.
-type NativeTestServerStub interface {
-	NativeTestServerStubMethods
-	// Describe the NativeTest interfaces.
-	Describe__() []rpc.InterfaceDesc
-}
-
-// NativeTestServer returns a server stub for NativeTest.
-// It converts an implementation of NativeTestServerMethods into
-// an object that may be used by rpc.Server.
-func NativeTestServer(impl NativeTestServerMethods) NativeTestServerStub {
-	stub := implNativeTestServerStub{
-		impl: impl,
-	}
-	// Initialize GlobState; always check the stub itself first, to handle the
-	// case where the user has the Glob method defined in their VDL source.
-	if gs := rpc.NewGlobState(stub); gs != nil {
-		stub.gs = gs
-	} else if gs := rpc.NewGlobState(impl); gs != nil {
-		stub.gs = gs
-	}
-	return stub
-}
-
-type implNativeTestServerStub struct {
-	impl NativeTestServerMethods
-	gs   *rpc.GlobState
-}
-
-func (s implNativeTestServerStub) PassTime(ctx *context.T, call rpc.ServerCall, i0 time.Time) (time.Time, error) {
-	return s.impl.PassTime(ctx, call, i0)
-}
-
-func (s implNativeTestServerStub) PassError(ctx *context.T, call rpc.ServerCall, i0 error) error {
-	return s.impl.PassError(ctx, call, i0)
-}
-
-func (s implNativeTestServerStub) Globber() *rpc.GlobState {
-	return s.gs
-}
-
-func (s implNativeTestServerStub) Describe__() []rpc.InterfaceDesc {
-	return []rpc.InterfaceDesc{NativeTestDesc}
-}
-
-// NativeTestDesc describes the NativeTest interface.
-var NativeTestDesc rpc.InterfaceDesc = descNativeTest
-
-// descNativeTest hides the desc to keep godoc clean.
-var descNativeTest = rpc.InterfaceDesc{
-	Name:    "NativeTest",
-	PkgPath: "v.io/x/js.core/test_service",
-	Methods: []rpc.MethodDesc{
-		{
-			Name: "PassTime",
-			InArgs: []rpc.ArgDesc{
-				{"t", ``}, // time.Time
-			},
-			OutArgs: []rpc.ArgDesc{
-				{"", ``}, // time.Time
-			},
-		},
-		{
-			Name: "PassError",
-			InArgs: []rpc.ArgDesc{
-				{"e", ``}, // error
-			},
-		},
-	},
-}
diff --git a/go/src/v.io/x/js.core/test_service/test_service.vdl.go b/go/src/v.io/x/js.core/test_service/test_service.vdl.go
new file mode 100644
index 0000000..ce5208b
--- /dev/null
+++ b/go/src/v.io/x/js.core/test_service/test_service.vdl.go
@@ -0,0 +1,1718 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file was auto-generated by the vanadium vdl tool.
+// Package: test_service
+
+package test_service
+
+import (
+	"fmt"
+	"io"
+	"reflect"
+	"time"
+	"v.io/v23"
+	"v.io/v23/context"
+	"v.io/v23/rpc"
+	"v.io/v23/security"
+	"v.io/v23/uniqueid"
+	"v.io/v23/vdl"
+	_ "v.io/v23/vdlroot/time"
+	"v.io/v23/vom"
+)
+
+// KeyPageResult is a page of 10 keys.
+type KeyPageResult [10]string
+
+func (KeyPageResult) __VDLReflect(struct {
+	Name string `vdl:"v.io/x/js.core/test_service.KeyPageResult"`
+}) {
+}
+
+func (m *KeyPageResult) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	listTarget1, err := t.StartList(__VDLType_v_io_x_js_core_test_service_KeyPageResult, 10)
+	if err != nil {
+		return err
+	}
+	for i, elem3 := range *m {
+		elemTarget2, err := listTarget1.StartElem(i)
+		if err != nil {
+			return err
+		}
+		if err := elemTarget2.FromString(string(elem3), vdl.StringType); err != nil {
+			return err
+		}
+		if err := listTarget1.FinishElem(elemTarget2); err != nil {
+			return err
+		}
+	}
+	if err := t.FinishList(listTarget1); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (m *KeyPageResult) MakeVDLTarget() vdl.Target {
+	return &KeyPageResultTarget{Value: m}
+}
+
+type KeyPageResultTarget struct {
+	Value *KeyPageResult
+	vdl.TargetBase
+	vdl.ListTargetBase
+}
+
+func (t *KeyPageResultTarget) StartList(tt *vdl.Type, len int) (vdl.ListTarget, error) {
+	if !vdl.Compatible(tt, __VDLType_v_io_x_js_core_test_service_KeyPageResult) {
+		return nil, fmt.Errorf("type %v incompatible with %v", tt, __VDLType_v_io_x_js_core_test_service_KeyPageResult)
+	}
+	return t, nil
+}
+func (t *KeyPageResultTarget) StartElem(index int) (elem vdl.Target, _ error) {
+	return &vdl.StringTarget{Value: &(*t.Value)[index]}, error(nil)
+}
+func (t *KeyPageResultTarget) FinishElem(elem vdl.Target) error {
+	return nil
+}
+func (t *KeyPageResultTarget) FinishList(elem vdl.ListTarget) error {
+
+	return nil
+}
+
+// KeyValuePair is a representation of a cached key and value pair.
+type KeyValuePair struct {
+	Key   string
+	Value *vom.RawBytes
+}
+
+func (KeyValuePair) __VDLReflect(struct {
+	Name string `vdl:"v.io/x/js.core/test_service.KeyValuePair"`
+}) {
+}
+
+func (m *KeyValuePair) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	if __VDLType_v_io_x_js_core_test_service_KeyValuePair == nil || __VDLType0 == nil {
+		panic("Initialization order error: types generated for FillVDLTarget not initialized. Consider moving caller to an init() block.")
+	}
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Key")
+	if err != vdl.ErrFieldNoExist && err != nil {
+		return err
+	}
+	if err != vdl.ErrFieldNoExist {
+		if err := fieldTarget3.FromString(string(m.Key), vdl.StringType); err != nil {
+			return err
+		}
+		if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+			return err
+		}
+	}
+	keyTarget4, fieldTarget5, err := fieldsTarget1.StartField("Value")
+	if err != vdl.ErrFieldNoExist && err != nil {
+		return err
+	}
+	if err != vdl.ErrFieldNoExist {
+
+		if m.Value == nil {
+			if err := fieldTarget5.FromNil(vdl.AnyType); err != nil {
+				return err
+			}
+		} else {
+			if err := m.Value.FillVDLTarget(fieldTarget5, vdl.AnyType); err != nil {
+				return err
+			}
+		}
+		if err := fieldsTarget1.FinishField(keyTarget4, fieldTarget5); err != nil {
+			return err
+		}
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (m *KeyValuePair) MakeVDLTarget() vdl.Target {
+	return &KeyValuePairTarget{Value: m}
+}
+
+type KeyValuePairTarget struct {
+	Value *KeyValuePair
+	vdl.TargetBase
+	vdl.FieldsTargetBase
+}
+
+func (t *KeyValuePairTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {
+	if !vdl.Compatible(tt, __VDLType_v_io_x_js_core_test_service_KeyValuePair) {
+		return nil, fmt.Errorf("type %v incompatible with %v", tt, __VDLType_v_io_x_js_core_test_service_KeyValuePair)
+	}
+	return t, nil
+}
+func (t *KeyValuePairTarget) StartField(name string) (key, field vdl.Target, _ error) {
+	switch name {
+	case "Key":
+		val, err := &vdl.StringTarget{Value: &t.Value.Key}, error(nil)
+		return nil, val, err
+	case "Value":
+		val, err := vdl.ReflectTarget(reflect.ValueOf(&t.Value.Value))
+		return nil, val, err
+	default:
+		return nil, nil, fmt.Errorf("field %s not in struct %v", name, __VDLType_v_io_x_js_core_test_service_KeyValuePair)
+	}
+}
+func (t *KeyValuePairTarget) FinishField(_, _ vdl.Target) error {
+	return nil
+}
+func (t *KeyValuePairTarget) FinishFields(_ vdl.FieldsTarget) error {
+
+	return nil
+}
+
+type TestCaveatData struct {
+	A string
+	B *vom.RawBytes // Use any for value so that we can confirm VDL is being used properly.
+}
+
+func (TestCaveatData) __VDLReflect(struct {
+	Name string `vdl:"v.io/x/js.core/test_service.TestCaveatData"`
+}) {
+}
+
+func (m *TestCaveatData) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	if __VDLType_v_io_x_js_core_test_service_TestCaveatData == nil || __VDLType1 == nil {
+		panic("Initialization order error: types generated for FillVDLTarget not initialized. Consider moving caller to an init() block.")
+	}
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("A")
+	if err != vdl.ErrFieldNoExist && err != nil {
+		return err
+	}
+	if err != vdl.ErrFieldNoExist {
+		if err := fieldTarget3.FromString(string(m.A), vdl.StringType); err != nil {
+			return err
+		}
+		if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+			return err
+		}
+	}
+	keyTarget4, fieldTarget5, err := fieldsTarget1.StartField("B")
+	if err != vdl.ErrFieldNoExist && err != nil {
+		return err
+	}
+	if err != vdl.ErrFieldNoExist {
+
+		if m.B == nil {
+			if err := fieldTarget5.FromNil(vdl.AnyType); err != nil {
+				return err
+			}
+		} else {
+			if err := m.B.FillVDLTarget(fieldTarget5, vdl.AnyType); err != nil {
+				return err
+			}
+		}
+		if err := fieldsTarget1.FinishField(keyTarget4, fieldTarget5); err != nil {
+			return err
+		}
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (m *TestCaveatData) MakeVDLTarget() vdl.Target {
+	return &TestCaveatDataTarget{Value: m}
+}
+
+type TestCaveatDataTarget struct {
+	Value *TestCaveatData
+	vdl.TargetBase
+	vdl.FieldsTargetBase
+}
+
+func (t *TestCaveatDataTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {
+	if !vdl.Compatible(tt, __VDLType_v_io_x_js_core_test_service_TestCaveatData) {
+		return nil, fmt.Errorf("type %v incompatible with %v", tt, __VDLType_v_io_x_js_core_test_service_TestCaveatData)
+	}
+	return t, nil
+}
+func (t *TestCaveatDataTarget) StartField(name string) (key, field vdl.Target, _ error) {
+	switch name {
+	case "A":
+		val, err := &vdl.StringTarget{Value: &t.Value.A}, error(nil)
+		return nil, val, err
+	case "B":
+		val, err := vdl.ReflectTarget(reflect.ValueOf(&t.Value.B))
+		return nil, val, err
+	default:
+		return nil, nil, fmt.Errorf("field %s not in struct %v", name, __VDLType_v_io_x_js_core_test_service_TestCaveatData)
+	}
+}
+func (t *TestCaveatDataTarget) FinishField(_, _ vdl.Target) error {
+	return nil
+}
+func (t *TestCaveatDataTarget) FinishFields(_ vdl.FieldsTarget) error {
+
+	return nil
+}
+
+func init() {
+	vdl.Register((*KeyPageResult)(nil))
+	vdl.Register((*KeyValuePair)(nil))
+	vdl.Register((*TestCaveatData)(nil))
+}
+
+var __VDLType0 *vdl.Type = vdl.TypeOf((*KeyValuePair)(nil))
+var __VDLType1 *vdl.Type = vdl.TypeOf((*TestCaveatData)(nil))
+var __VDLType_v_io_x_js_core_test_service_KeyPageResult *vdl.Type = vdl.TypeOf(KeyPageResult{})
+var __VDLType_v_io_x_js_core_test_service_KeyValuePair *vdl.Type = vdl.TypeOf(KeyValuePair{})
+var __VDLType_v_io_x_js_core_test_service_TestCaveatData *vdl.Type = vdl.TypeOf(TestCaveatData{})
+
+func __VDLEnsureNativeBuilt() {
+}
+
+var ConditionallyValidatingTestCaveat = security.CaveatDescriptor{
+	Id: uniqueid.Id{
+		0,
+		17,
+		34,
+		51,
+		68,
+		85,
+		102,
+		119,
+		136,
+		153,
+		170,
+		187,
+		204,
+		221,
+		238,
+		255,
+	},
+	ParamType: vdl.TypeOf(TestCaveatData{}),
+}
+
+// CacheClientMethods is the client interface
+// containing Cache methods.
+//
+// A Cache service mimics the memcache interface.
+type CacheClientMethods interface {
+	// Set sets a value for a key.
+	Set(_ *context.T, key string, value *vom.RawBytes, _ ...rpc.CallOpt) error
+	// Get returns the value for a key.  If the value is not found, returns
+	// a not found error.
+	Get(_ *context.T, key string, _ ...rpc.CallOpt) (*vom.RawBytes, error)
+	// Same as Get, but casts the return argument to an byte.
+	GetAsByte(_ *context.T, key string, _ ...rpc.CallOpt) (byte, error)
+	// Same as Get, but casts the return argument to an int32.
+	GetAsInt32(_ *context.T, key string, _ ...rpc.CallOpt) (int32, error)
+	// Same as Get, but casts the return argument to an int64.
+	GetAsInt64(_ *context.T, key string, _ ...rpc.CallOpt) (int64, error)
+	// Same as Get, but casts the return argument to an uint32.
+	GetAsUint32(_ *context.T, key string, _ ...rpc.CallOpt) (uint32, error)
+	// Same as Get, but casts the return argument to an uint64.
+	GetAsUint64(_ *context.T, key string, _ ...rpc.CallOpt) (uint64, error)
+	// Same as Get, but casts the return argument to an float32.
+	GetAsFloat32(_ *context.T, key string, _ ...rpc.CallOpt) (float32, error)
+	// Same as Get, but casts the return argument to an float64.
+	GetAsFloat64(_ *context.T, key string, _ ...rpc.CallOpt) (float64, error)
+	// Same as Get, but casts the return argument to a string.
+	GetAsString(_ *context.T, key string, _ ...rpc.CallOpt) (string, error)
+	// Same as Get, but casts the return argument to a bool.
+	GetAsBool(_ *context.T, key string, _ ...rpc.CallOpt) (bool, error)
+	// Same as Get, but casts the return argument to an error.
+	GetAsError(_ *context.T, key string, _ ...rpc.CallOpt) (error, error)
+	// AsMap returns the full contents of the cache as a map.
+	AsMap(*context.T, ...rpc.CallOpt) (map[string]*vom.RawBytes, error)
+	// KeyValuePairs returns the full contents of the cache as a slice of pairs.
+	KeyValuePairs(*context.T, ...rpc.CallOpt) ([]KeyValuePair, error)
+	// MostRecentSet returns the key and value and the timestamp for the most
+	// recent set operation
+	// TODO(bprosnitz) support type types and change time to native time type
+	MostRecentSet(*context.T, ...rpc.CallOpt) (value KeyValuePair, time int64, _ error)
+	// KeyPage indexes into the keys (in alphanumerically sorted order) and
+	// returns the indexth page of 10 keys.
+	KeyPage(_ *context.T, index int64, _ ...rpc.CallOpt) (KeyPageResult, error)
+	// Size returns the total number of entries in the cache.
+	Size(*context.T, ...rpc.CallOpt) (int64, error)
+	// MultiGet sets up a stream that allows fetching multiple keys.
+	MultiGet(*context.T, ...rpc.CallOpt) (CacheMultiGetClientCall, error)
+}
+
+// CacheClientStub adds universal methods to CacheClientMethods.
+type CacheClientStub interface {
+	CacheClientMethods
+	rpc.UniversalServiceMethods
+}
+
+// CacheClient returns a client stub for Cache.
+func CacheClient(name string) CacheClientStub {
+	return implCacheClientStub{name}
+}
+
+type implCacheClientStub struct {
+	name string
+}
+
+func (c implCacheClientStub) Set(ctx *context.T, i0 string, i1 *vom.RawBytes, opts ...rpc.CallOpt) (err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "Set", []interface{}{i0, i1}, nil, opts...)
+	return
+}
+
+func (c implCacheClientStub) Get(ctx *context.T, i0 string, opts ...rpc.CallOpt) (o0 *vom.RawBytes, err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "Get", []interface{}{i0}, []interface{}{&o0}, opts...)
+	return
+}
+
+func (c implCacheClientStub) GetAsByte(ctx *context.T, i0 string, opts ...rpc.CallOpt) (o0 byte, err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "GetAsByte", []interface{}{i0}, []interface{}{&o0}, opts...)
+	return
+}
+
+func (c implCacheClientStub) GetAsInt32(ctx *context.T, i0 string, opts ...rpc.CallOpt) (o0 int32, err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "GetAsInt32", []interface{}{i0}, []interface{}{&o0}, opts...)
+	return
+}
+
+func (c implCacheClientStub) GetAsInt64(ctx *context.T, i0 string, opts ...rpc.CallOpt) (o0 int64, err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "GetAsInt64", []interface{}{i0}, []interface{}{&o0}, opts...)
+	return
+}
+
+func (c implCacheClientStub) GetAsUint32(ctx *context.T, i0 string, opts ...rpc.CallOpt) (o0 uint32, err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "GetAsUint32", []interface{}{i0}, []interface{}{&o0}, opts...)
+	return
+}
+
+func (c implCacheClientStub) GetAsUint64(ctx *context.T, i0 string, opts ...rpc.CallOpt) (o0 uint64, err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "GetAsUint64", []interface{}{i0}, []interface{}{&o0}, opts...)
+	return
+}
+
+func (c implCacheClientStub) GetAsFloat32(ctx *context.T, i0 string, opts ...rpc.CallOpt) (o0 float32, err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "GetAsFloat32", []interface{}{i0}, []interface{}{&o0}, opts...)
+	return
+}
+
+func (c implCacheClientStub) GetAsFloat64(ctx *context.T, i0 string, opts ...rpc.CallOpt) (o0 float64, err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "GetAsFloat64", []interface{}{i0}, []interface{}{&o0}, opts...)
+	return
+}
+
+func (c implCacheClientStub) GetAsString(ctx *context.T, i0 string, opts ...rpc.CallOpt) (o0 string, err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "GetAsString", []interface{}{i0}, []interface{}{&o0}, opts...)
+	return
+}
+
+func (c implCacheClientStub) GetAsBool(ctx *context.T, i0 string, opts ...rpc.CallOpt) (o0 bool, err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "GetAsBool", []interface{}{i0}, []interface{}{&o0}, opts...)
+	return
+}
+
+func (c implCacheClientStub) GetAsError(ctx *context.T, i0 string, opts ...rpc.CallOpt) (o0 error, err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "GetAsError", []interface{}{i0}, []interface{}{&o0}, opts...)
+	return
+}
+
+func (c implCacheClientStub) AsMap(ctx *context.T, opts ...rpc.CallOpt) (o0 map[string]*vom.RawBytes, err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "AsMap", nil, []interface{}{&o0}, opts...)
+	return
+}
+
+func (c implCacheClientStub) KeyValuePairs(ctx *context.T, opts ...rpc.CallOpt) (o0 []KeyValuePair, err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "KeyValuePairs", nil, []interface{}{&o0}, opts...)
+	return
+}
+
+func (c implCacheClientStub) MostRecentSet(ctx *context.T, opts ...rpc.CallOpt) (o0 KeyValuePair, o1 int64, err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "MostRecentSet", nil, []interface{}{&o0, &o1}, opts...)
+	return
+}
+
+func (c implCacheClientStub) KeyPage(ctx *context.T, i0 int64, opts ...rpc.CallOpt) (o0 KeyPageResult, err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "KeyPage", []interface{}{i0}, []interface{}{&o0}, opts...)
+	return
+}
+
+func (c implCacheClientStub) Size(ctx *context.T, opts ...rpc.CallOpt) (o0 int64, err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "Size", nil, []interface{}{&o0}, opts...)
+	return
+}
+
+func (c implCacheClientStub) MultiGet(ctx *context.T, opts ...rpc.CallOpt) (ocall CacheMultiGetClientCall, err error) {
+	var call rpc.ClientCall
+	if call, err = v23.GetClient(ctx).StartCall(ctx, c.name, "MultiGet", nil, opts...); err != nil {
+		return
+	}
+	ocall = &implCacheMultiGetClientCall{ClientCall: call}
+	return
+}
+
+// CacheMultiGetClientStream is the client stream for Cache.MultiGet.
+type CacheMultiGetClientStream interface {
+	// RecvStream returns the receiver side of the Cache.MultiGet client stream.
+	RecvStream() interface {
+		// Advance stages an item so that it may be retrieved via Value.  Returns
+		// true iff there is an item to retrieve.  Advance must be called before
+		// Value is called.  May block if an item is not available.
+		Advance() bool
+		// Value returns the item that was staged by Advance.  May panic if Advance
+		// returned false or was not called.  Never blocks.
+		Value() *vom.RawBytes
+		// Err returns any error encountered by Advance.  Never blocks.
+		Err() error
+	}
+	// SendStream returns the send side of the Cache.MultiGet client stream.
+	SendStream() interface {
+		// Send places the item onto the output stream.  Returns errors
+		// encountered while sending, or if Send is called after Close or
+		// the stream has been canceled.  Blocks if there is no buffer
+		// space; will unblock when buffer space is available or after
+		// the stream has been canceled.
+		Send(item string) error
+		// Close indicates to the server that no more items will be sent;
+		// server Recv calls will receive io.EOF after all sent items.
+		// This is an optional call - e.g. a client might call Close if it
+		// needs to continue receiving items from the server after it's
+		// done sending.  Returns errors encountered while closing, or if
+		// Close is called after the stream has been canceled.  Like Send,
+		// blocks if there is no buffer space available.
+		Close() error
+	}
+}
+
+// CacheMultiGetClientCall represents the call returned from Cache.MultiGet.
+type CacheMultiGetClientCall interface {
+	CacheMultiGetClientStream
+	// Finish performs the equivalent of SendStream().Close, then blocks until
+	// the server is done, and returns the positional return values for the call.
+	//
+	// Finish returns immediately if the call has been canceled; depending on the
+	// timing the output could either be an error signaling cancelation, or the
+	// valid positional return values from the server.
+	//
+	// Calling Finish is mandatory for releasing stream resources, unless the call
+	// has been canceled or any of the other methods return an error.  Finish should
+	// be called at most once.
+	Finish() error
+}
+
+type implCacheMultiGetClientCall struct {
+	rpc.ClientCall
+	valRecv *vom.RawBytes
+	errRecv error
+}
+
+func (c *implCacheMultiGetClientCall) RecvStream() interface {
+	Advance() bool
+	Value() *vom.RawBytes
+	Err() error
+} {
+	return implCacheMultiGetClientCallRecv{c}
+}
+
+type implCacheMultiGetClientCallRecv struct {
+	c *implCacheMultiGetClientCall
+}
+
+func (c implCacheMultiGetClientCallRecv) Advance() bool {
+	c.c.valRecv = nil
+	c.c.errRecv = c.c.Recv(&c.c.valRecv)
+	return c.c.errRecv == nil
+}
+func (c implCacheMultiGetClientCallRecv) Value() *vom.RawBytes {
+	return c.c.valRecv
+}
+func (c implCacheMultiGetClientCallRecv) Err() error {
+	if c.c.errRecv == io.EOF {
+		return nil
+	}
+	return c.c.errRecv
+}
+func (c *implCacheMultiGetClientCall) SendStream() interface {
+	Send(item string) error
+	Close() error
+} {
+	return implCacheMultiGetClientCallSend{c}
+}
+
+type implCacheMultiGetClientCallSend struct {
+	c *implCacheMultiGetClientCall
+}
+
+func (c implCacheMultiGetClientCallSend) Send(item string) error {
+	return c.c.Send(item)
+}
+func (c implCacheMultiGetClientCallSend) Close() error {
+	return c.c.CloseSend()
+}
+func (c *implCacheMultiGetClientCall) Finish() (err error) {
+	err = c.ClientCall.Finish()
+	return
+}
+
+// CacheServerMethods is the interface a server writer
+// implements for Cache.
+//
+// A Cache service mimics the memcache interface.
+type CacheServerMethods interface {
+	// Set sets a value for a key.
+	Set(_ *context.T, _ rpc.ServerCall, key string, value *vom.RawBytes) error
+	// Get returns the value for a key.  If the value is not found, returns
+	// a not found error.
+	Get(_ *context.T, _ rpc.ServerCall, key string) (*vom.RawBytes, error)
+	// Same as Get, but casts the return argument to an byte.
+	GetAsByte(_ *context.T, _ rpc.ServerCall, key string) (byte, error)
+	// Same as Get, but casts the return argument to an int32.
+	GetAsInt32(_ *context.T, _ rpc.ServerCall, key string) (int32, error)
+	// Same as Get, but casts the return argument to an int64.
+	GetAsInt64(_ *context.T, _ rpc.ServerCall, key string) (int64, error)
+	// Same as Get, but casts the return argument to an uint32.
+	GetAsUint32(_ *context.T, _ rpc.ServerCall, key string) (uint32, error)
+	// Same as Get, but casts the return argument to an uint64.
+	GetAsUint64(_ *context.T, _ rpc.ServerCall, key string) (uint64, error)
+	// Same as Get, but casts the return argument to an float32.
+	GetAsFloat32(_ *context.T, _ rpc.ServerCall, key string) (float32, error)
+	// Same as Get, but casts the return argument to an float64.
+	GetAsFloat64(_ *context.T, _ rpc.ServerCall, key string) (float64, error)
+	// Same as Get, but casts the return argument to a string.
+	GetAsString(_ *context.T, _ rpc.ServerCall, key string) (string, error)
+	// Same as Get, but casts the return argument to a bool.
+	GetAsBool(_ *context.T, _ rpc.ServerCall, key string) (bool, error)
+	// Same as Get, but casts the return argument to an error.
+	GetAsError(_ *context.T, _ rpc.ServerCall, key string) (error, error)
+	// AsMap returns the full contents of the cache as a map.
+	AsMap(*context.T, rpc.ServerCall) (map[string]*vom.RawBytes, error)
+	// KeyValuePairs returns the full contents of the cache as a slice of pairs.
+	KeyValuePairs(*context.T, rpc.ServerCall) ([]KeyValuePair, error)
+	// MostRecentSet returns the key and value and the timestamp for the most
+	// recent set operation
+	// TODO(bprosnitz) support type types and change time to native time type
+	MostRecentSet(*context.T, rpc.ServerCall) (value KeyValuePair, time int64, _ error)
+	// KeyPage indexes into the keys (in alphanumerically sorted order) and
+	// returns the indexth page of 10 keys.
+	KeyPage(_ *context.T, _ rpc.ServerCall, index int64) (KeyPageResult, error)
+	// Size returns the total number of entries in the cache.
+	Size(*context.T, rpc.ServerCall) (int64, error)
+	// MultiGet sets up a stream that allows fetching multiple keys.
+	MultiGet(*context.T, CacheMultiGetServerCall) error
+}
+
+// CacheServerStubMethods is the server interface containing
+// Cache methods, as expected by rpc.Server.
+// The only difference between this interface and CacheServerMethods
+// is the streaming methods.
+type CacheServerStubMethods interface {
+	// Set sets a value for a key.
+	Set(_ *context.T, _ rpc.ServerCall, key string, value *vom.RawBytes) error
+	// Get returns the value for a key.  If the value is not found, returns
+	// a not found error.
+	Get(_ *context.T, _ rpc.ServerCall, key string) (*vom.RawBytes, error)
+	// Same as Get, but casts the return argument to an byte.
+	GetAsByte(_ *context.T, _ rpc.ServerCall, key string) (byte, error)
+	// Same as Get, but casts the return argument to an int32.
+	GetAsInt32(_ *context.T, _ rpc.ServerCall, key string) (int32, error)
+	// Same as Get, but casts the return argument to an int64.
+	GetAsInt64(_ *context.T, _ rpc.ServerCall, key string) (int64, error)
+	// Same as Get, but casts the return argument to an uint32.
+	GetAsUint32(_ *context.T, _ rpc.ServerCall, key string) (uint32, error)
+	// Same as Get, but casts the return argument to an uint64.
+	GetAsUint64(_ *context.T, _ rpc.ServerCall, key string) (uint64, error)
+	// Same as Get, but casts the return argument to an float32.
+	GetAsFloat32(_ *context.T, _ rpc.ServerCall, key string) (float32, error)
+	// Same as Get, but casts the return argument to an float64.
+	GetAsFloat64(_ *context.T, _ rpc.ServerCall, key string) (float64, error)
+	// Same as Get, but casts the return argument to a string.
+	GetAsString(_ *context.T, _ rpc.ServerCall, key string) (string, error)
+	// Same as Get, but casts the return argument to a bool.
+	GetAsBool(_ *context.T, _ rpc.ServerCall, key string) (bool, error)
+	// Same as Get, but casts the return argument to an error.
+	GetAsError(_ *context.T, _ rpc.ServerCall, key string) (error, error)
+	// AsMap returns the full contents of the cache as a map.
+	AsMap(*context.T, rpc.ServerCall) (map[string]*vom.RawBytes, error)
+	// KeyValuePairs returns the full contents of the cache as a slice of pairs.
+	KeyValuePairs(*context.T, rpc.ServerCall) ([]KeyValuePair, error)
+	// MostRecentSet returns the key and value and the timestamp for the most
+	// recent set operation
+	// TODO(bprosnitz) support type types and change time to native time type
+	MostRecentSet(*context.T, rpc.ServerCall) (value KeyValuePair, time int64, _ error)
+	// KeyPage indexes into the keys (in alphanumerically sorted order) and
+	// returns the indexth page of 10 keys.
+	KeyPage(_ *context.T, _ rpc.ServerCall, index int64) (KeyPageResult, error)
+	// Size returns the total number of entries in the cache.
+	Size(*context.T, rpc.ServerCall) (int64, error)
+	// MultiGet sets up a stream that allows fetching multiple keys.
+	MultiGet(*context.T, *CacheMultiGetServerCallStub) error
+}
+
+// CacheServerStub adds universal methods to CacheServerStubMethods.
+type CacheServerStub interface {
+	CacheServerStubMethods
+	// Describe the Cache interfaces.
+	Describe__() []rpc.InterfaceDesc
+}
+
+// CacheServer returns a server stub for Cache.
+// It converts an implementation of CacheServerMethods into
+// an object that may be used by rpc.Server.
+func CacheServer(impl CacheServerMethods) CacheServerStub {
+	stub := implCacheServerStub{
+		impl: impl,
+	}
+	// Initialize GlobState; always check the stub itself first, to handle the
+	// case where the user has the Glob method defined in their VDL source.
+	if gs := rpc.NewGlobState(stub); gs != nil {
+		stub.gs = gs
+	} else if gs := rpc.NewGlobState(impl); gs != nil {
+		stub.gs = gs
+	}
+	return stub
+}
+
+type implCacheServerStub struct {
+	impl CacheServerMethods
+	gs   *rpc.GlobState
+}
+
+func (s implCacheServerStub) Set(ctx *context.T, call rpc.ServerCall, i0 string, i1 *vom.RawBytes) error {
+	return s.impl.Set(ctx, call, i0, i1)
+}
+
+func (s implCacheServerStub) Get(ctx *context.T, call rpc.ServerCall, i0 string) (*vom.RawBytes, error) {
+	return s.impl.Get(ctx, call, i0)
+}
+
+func (s implCacheServerStub) GetAsByte(ctx *context.T, call rpc.ServerCall, i0 string) (byte, error) {
+	return s.impl.GetAsByte(ctx, call, i0)
+}
+
+func (s implCacheServerStub) GetAsInt32(ctx *context.T, call rpc.ServerCall, i0 string) (int32, error) {
+	return s.impl.GetAsInt32(ctx, call, i0)
+}
+
+func (s implCacheServerStub) GetAsInt64(ctx *context.T, call rpc.ServerCall, i0 string) (int64, error) {
+	return s.impl.GetAsInt64(ctx, call, i0)
+}
+
+func (s implCacheServerStub) GetAsUint32(ctx *context.T, call rpc.ServerCall, i0 string) (uint32, error) {
+	return s.impl.GetAsUint32(ctx, call, i0)
+}
+
+func (s implCacheServerStub) GetAsUint64(ctx *context.T, call rpc.ServerCall, i0 string) (uint64, error) {
+	return s.impl.GetAsUint64(ctx, call, i0)
+}
+
+func (s implCacheServerStub) GetAsFloat32(ctx *context.T, call rpc.ServerCall, i0 string) (float32, error) {
+	return s.impl.GetAsFloat32(ctx, call, i0)
+}
+
+func (s implCacheServerStub) GetAsFloat64(ctx *context.T, call rpc.ServerCall, i0 string) (float64, error) {
+	return s.impl.GetAsFloat64(ctx, call, i0)
+}
+
+func (s implCacheServerStub) GetAsString(ctx *context.T, call rpc.ServerCall, i0 string) (string, error) {
+	return s.impl.GetAsString(ctx, call, i0)
+}
+
+func (s implCacheServerStub) GetAsBool(ctx *context.T, call rpc.ServerCall, i0 string) (bool, error) {
+	return s.impl.GetAsBool(ctx, call, i0)
+}
+
+func (s implCacheServerStub) GetAsError(ctx *context.T, call rpc.ServerCall, i0 string) (error, error) {
+	return s.impl.GetAsError(ctx, call, i0)
+}
+
+func (s implCacheServerStub) AsMap(ctx *context.T, call rpc.ServerCall) (map[string]*vom.RawBytes, error) {
+	return s.impl.AsMap(ctx, call)
+}
+
+func (s implCacheServerStub) KeyValuePairs(ctx *context.T, call rpc.ServerCall) ([]KeyValuePair, error) {
+	return s.impl.KeyValuePairs(ctx, call)
+}
+
+func (s implCacheServerStub) MostRecentSet(ctx *context.T, call rpc.ServerCall) (KeyValuePair, int64, error) {
+	return s.impl.MostRecentSet(ctx, call)
+}
+
+func (s implCacheServerStub) KeyPage(ctx *context.T, call rpc.ServerCall, i0 int64) (KeyPageResult, error) {
+	return s.impl.KeyPage(ctx, call, i0)
+}
+
+func (s implCacheServerStub) Size(ctx *context.T, call rpc.ServerCall) (int64, error) {
+	return s.impl.Size(ctx, call)
+}
+
+func (s implCacheServerStub) MultiGet(ctx *context.T, call *CacheMultiGetServerCallStub) error {
+	return s.impl.MultiGet(ctx, call)
+}
+
+func (s implCacheServerStub) Globber() *rpc.GlobState {
+	return s.gs
+}
+
+func (s implCacheServerStub) Describe__() []rpc.InterfaceDesc {
+	return []rpc.InterfaceDesc{CacheDesc}
+}
+
+// CacheDesc describes the Cache interface.
+var CacheDesc rpc.InterfaceDesc = descCache
+
+// descCache hides the desc to keep godoc clean.
+var descCache = rpc.InterfaceDesc{
+	Name:    "Cache",
+	PkgPath: "v.io/x/js.core/test_service",
+	Doc:     "// A Cache service mimics the memcache interface.",
+	Methods: []rpc.MethodDesc{
+		{
+			Name: "Set",
+			Doc:  "// Set sets a value for a key.",
+			InArgs: []rpc.ArgDesc{
+				{"key", ``},   // string
+				{"value", ``}, // *vom.RawBytes
+			},
+		},
+		{
+			Name: "Get",
+			Doc:  "// Get returns the value for a key.  If the value is not found, returns\n// a not found error.",
+			InArgs: []rpc.ArgDesc{
+				{"key", ``}, // string
+			},
+			OutArgs: []rpc.ArgDesc{
+				{"", ``}, // *vom.RawBytes
+			},
+		},
+		{
+			Name: "GetAsByte",
+			Doc:  "// Same as Get, but casts the return argument to an byte.",
+			InArgs: []rpc.ArgDesc{
+				{"key", ``}, // string
+			},
+			OutArgs: []rpc.ArgDesc{
+				{"", ``}, // byte
+			},
+		},
+		{
+			Name: "GetAsInt32",
+			Doc:  "// Same as Get, but casts the return argument to an int32.",
+			InArgs: []rpc.ArgDesc{
+				{"key", ``}, // string
+			},
+			OutArgs: []rpc.ArgDesc{
+				{"", ``}, // int32
+			},
+		},
+		{
+			Name: "GetAsInt64",
+			Doc:  "// Same as Get, but casts the return argument to an int64.",
+			InArgs: []rpc.ArgDesc{
+				{"key", ``}, // string
+			},
+			OutArgs: []rpc.ArgDesc{
+				{"", ``}, // int64
+			},
+		},
+		{
+			Name: "GetAsUint32",
+			Doc:  "// Same as Get, but casts the return argument to an uint32.",
+			InArgs: []rpc.ArgDesc{
+				{"key", ``}, // string
+			},
+			OutArgs: []rpc.ArgDesc{
+				{"", ``}, // uint32
+			},
+		},
+		{
+			Name: "GetAsUint64",
+			Doc:  "// Same as Get, but casts the return argument to an uint64.",
+			InArgs: []rpc.ArgDesc{
+				{"key", ``}, // string
+			},
+			OutArgs: []rpc.ArgDesc{
+				{"", ``}, // uint64
+			},
+		},
+		{
+			Name: "GetAsFloat32",
+			Doc:  "// Same as Get, but casts the return argument to an float32.",
+			InArgs: []rpc.ArgDesc{
+				{"key", ``}, // string
+			},
+			OutArgs: []rpc.ArgDesc{
+				{"", ``}, // float32
+			},
+		},
+		{
+			Name: "GetAsFloat64",
+			Doc:  "// Same as Get, but casts the return argument to an float64.",
+			InArgs: []rpc.ArgDesc{
+				{"key", ``}, // string
+			},
+			OutArgs: []rpc.ArgDesc{
+				{"", ``}, // float64
+			},
+		},
+		{
+			Name: "GetAsString",
+			Doc:  "// Same as Get, but casts the return argument to a string.",
+			InArgs: []rpc.ArgDesc{
+				{"key", ``}, // string
+			},
+			OutArgs: []rpc.ArgDesc{
+				{"", ``}, // string
+			},
+		},
+		{
+			Name: "GetAsBool",
+			Doc:  "// Same as Get, but casts the return argument to a bool.",
+			InArgs: []rpc.ArgDesc{
+				{"key", ``}, // string
+			},
+			OutArgs: []rpc.ArgDesc{
+				{"", ``}, // bool
+			},
+		},
+		{
+			Name: "GetAsError",
+			Doc:  "// Same as Get, but casts the return argument to an error.",
+			InArgs: []rpc.ArgDesc{
+				{"key", ``}, // string
+			},
+			OutArgs: []rpc.ArgDesc{
+				{"", ``}, // error
+			},
+		},
+		{
+			Name: "AsMap",
+			Doc:  "// AsMap returns the full contents of the cache as a map.",
+			OutArgs: []rpc.ArgDesc{
+				{"", ``}, // map[string]*vom.RawBytes
+			},
+		},
+		{
+			Name: "KeyValuePairs",
+			Doc:  "// KeyValuePairs returns the full contents of the cache as a slice of pairs.",
+			OutArgs: []rpc.ArgDesc{
+				{"", ``}, // []KeyValuePair
+			},
+		},
+		{
+			Name: "MostRecentSet",
+			Doc:  "// MostRecentSet returns the key and value and the timestamp for the most\n// recent set operation\n// TODO(bprosnitz) support type types and change time to native time type",
+			OutArgs: []rpc.ArgDesc{
+				{"value", ``}, // KeyValuePair
+				{"time", ``},  // int64
+			},
+		},
+		{
+			Name: "KeyPage",
+			Doc:  "// KeyPage indexes into the keys (in alphanumerically sorted order) and\n// returns the indexth page of 10 keys.",
+			InArgs: []rpc.ArgDesc{
+				{"index", ``}, // int64
+			},
+			OutArgs: []rpc.ArgDesc{
+				{"", ``}, // KeyPageResult
+			},
+		},
+		{
+			Name: "Size",
+			Doc:  "// Size returns the total number of entries in the cache.",
+			OutArgs: []rpc.ArgDesc{
+				{"", ``}, // int64
+			},
+		},
+		{
+			Name: "MultiGet",
+			Doc:  "// MultiGet sets up a stream that allows fetching multiple keys.",
+		},
+	},
+}
+
+// CacheMultiGetServerStream is the server stream for Cache.MultiGet.
+type CacheMultiGetServerStream interface {
+	// RecvStream returns the receiver side of the Cache.MultiGet server stream.
+	RecvStream() interface {
+		// Advance stages an item so that it may be retrieved via Value.  Returns
+		// true iff there is an item to retrieve.  Advance must be called before
+		// Value is called.  May block if an item is not available.
+		Advance() bool
+		// Value returns the item that was staged by Advance.  May panic if Advance
+		// returned false or was not called.  Never blocks.
+		Value() string
+		// Err returns any error encountered by Advance.  Never blocks.
+		Err() error
+	}
+	// SendStream returns the send side of the Cache.MultiGet server stream.
+	SendStream() interface {
+		// Send places the item onto the output stream.  Returns errors encountered
+		// while sending.  Blocks if there is no buffer space; will unblock when
+		// buffer space is available.
+		Send(item *vom.RawBytes) error
+	}
+}
+
+// CacheMultiGetServerCall represents the context passed to Cache.MultiGet.
+type CacheMultiGetServerCall interface {
+	rpc.ServerCall
+	CacheMultiGetServerStream
+}
+
+// CacheMultiGetServerCallStub is a wrapper that converts rpc.StreamServerCall into
+// a typesafe stub that implements CacheMultiGetServerCall.
+type CacheMultiGetServerCallStub struct {
+	rpc.StreamServerCall
+	valRecv string
+	errRecv error
+}
+
+// Init initializes CacheMultiGetServerCallStub from rpc.StreamServerCall.
+func (s *CacheMultiGetServerCallStub) Init(call rpc.StreamServerCall) {
+	s.StreamServerCall = call
+}
+
+// RecvStream returns the receiver side of the Cache.MultiGet server stream.
+func (s *CacheMultiGetServerCallStub) RecvStream() interface {
+	Advance() bool
+	Value() string
+	Err() error
+} {
+	return implCacheMultiGetServerCallRecv{s}
+}
+
+type implCacheMultiGetServerCallRecv struct {
+	s *CacheMultiGetServerCallStub
+}
+
+func (s implCacheMultiGetServerCallRecv) Advance() bool {
+	s.s.errRecv = s.s.Recv(&s.s.valRecv)
+	return s.s.errRecv == nil
+}
+func (s implCacheMultiGetServerCallRecv) Value() string {
+	return s.s.valRecv
+}
+func (s implCacheMultiGetServerCallRecv) Err() error {
+	if s.s.errRecv == io.EOF {
+		return nil
+	}
+	return s.s.errRecv
+}
+
+// SendStream returns the send side of the Cache.MultiGet server stream.
+func (s *CacheMultiGetServerCallStub) SendStream() interface {
+	Send(item *vom.RawBytes) error
+} {
+	return implCacheMultiGetServerCallSend{s}
+}
+
+type implCacheMultiGetServerCallSend struct {
+	s *CacheMultiGetServerCallStub
+}
+
+func (s implCacheMultiGetServerCallSend) Send(item *vom.RawBytes) error {
+	return s.s.Send(item)
+}
+
+// CancelCollectorClientMethods is the client interface
+// containing CancelCollector methods.
+//
+// CancelCollector is a test interface for use in testing cancellation and deadlines.
+type CancelCollectorClientMethods interface {
+	// A function that never returns, but records the status of the given key.
+	NeverReturn(_ *context.T, key int64, _ ...rpc.CallOpt) error
+	// Wait for the call with the given key to have the given status.  Possible statuses are:
+	// "running", and, "cancelled".  Returns the number of nanoseconds left on
+	// the deadline of the specified call when the call first began.
+	WaitForStatus(_ *context.T, key int64, status string, _ ...rpc.CallOpt) (timeout int64, _ error)
+}
+
+// CancelCollectorClientStub adds universal methods to CancelCollectorClientMethods.
+type CancelCollectorClientStub interface {
+	CancelCollectorClientMethods
+	rpc.UniversalServiceMethods
+}
+
+// CancelCollectorClient returns a client stub for CancelCollector.
+func CancelCollectorClient(name string) CancelCollectorClientStub {
+	return implCancelCollectorClientStub{name}
+}
+
+type implCancelCollectorClientStub struct {
+	name string
+}
+
+func (c implCancelCollectorClientStub) NeverReturn(ctx *context.T, i0 int64, opts ...rpc.CallOpt) (err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "NeverReturn", []interface{}{i0}, nil, opts...)
+	return
+}
+
+func (c implCancelCollectorClientStub) WaitForStatus(ctx *context.T, i0 int64, i1 string, opts ...rpc.CallOpt) (o0 int64, err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "WaitForStatus", []interface{}{i0, i1}, []interface{}{&o0}, opts...)
+	return
+}
+
+// CancelCollectorServerMethods is the interface a server writer
+// implements for CancelCollector.
+//
+// CancelCollector is a test interface for use in testing cancellation and deadlines.
+type CancelCollectorServerMethods interface {
+	// A function that never returns, but records the status of the given key.
+	NeverReturn(_ *context.T, _ rpc.ServerCall, key int64) error
+	// Wait for the call with the given key to have the given status.  Possible statuses are:
+	// "running", and, "cancelled".  Returns the number of nanoseconds left on
+	// the deadline of the specified call when the call first began.
+	WaitForStatus(_ *context.T, _ rpc.ServerCall, key int64, status string) (timeout int64, _ error)
+}
+
+// CancelCollectorServerStubMethods is the server interface containing
+// CancelCollector methods, as expected by rpc.Server.
+// There is no difference between this interface and CancelCollectorServerMethods
+// since there are no streaming methods.
+type CancelCollectorServerStubMethods CancelCollectorServerMethods
+
+// CancelCollectorServerStub adds universal methods to CancelCollectorServerStubMethods.
+type CancelCollectorServerStub interface {
+	CancelCollectorServerStubMethods
+	// Describe the CancelCollector interfaces.
+	Describe__() []rpc.InterfaceDesc
+}
+
+// CancelCollectorServer returns a server stub for CancelCollector.
+// It converts an implementation of CancelCollectorServerMethods into
+// an object that may be used by rpc.Server.
+func CancelCollectorServer(impl CancelCollectorServerMethods) CancelCollectorServerStub {
+	stub := implCancelCollectorServerStub{
+		impl: impl,
+	}
+	// Initialize GlobState; always check the stub itself first, to handle the
+	// case where the user has the Glob method defined in their VDL source.
+	if gs := rpc.NewGlobState(stub); gs != nil {
+		stub.gs = gs
+	} else if gs := rpc.NewGlobState(impl); gs != nil {
+		stub.gs = gs
+	}
+	return stub
+}
+
+type implCancelCollectorServerStub struct {
+	impl CancelCollectorServerMethods
+	gs   *rpc.GlobState
+}
+
+func (s implCancelCollectorServerStub) NeverReturn(ctx *context.T, call rpc.ServerCall, i0 int64) error {
+	return s.impl.NeverReturn(ctx, call, i0)
+}
+
+func (s implCancelCollectorServerStub) WaitForStatus(ctx *context.T, call rpc.ServerCall, i0 int64, i1 string) (int64, error) {
+	return s.impl.WaitForStatus(ctx, call, i0, i1)
+}
+
+func (s implCancelCollectorServerStub) Globber() *rpc.GlobState {
+	return s.gs
+}
+
+func (s implCancelCollectorServerStub) Describe__() []rpc.InterfaceDesc {
+	return []rpc.InterfaceDesc{CancelCollectorDesc}
+}
+
+// CancelCollectorDesc describes the CancelCollector interface.
+var CancelCollectorDesc rpc.InterfaceDesc = descCancelCollector
+
+// descCancelCollector hides the desc to keep godoc clean.
+var descCancelCollector = rpc.InterfaceDesc{
+	Name:    "CancelCollector",
+	PkgPath: "v.io/x/js.core/test_service",
+	Doc:     "// CancelCollector is a test interface for use in testing cancellation and deadlines.",
+	Methods: []rpc.MethodDesc{
+		{
+			Name: "NeverReturn",
+			Doc:  "// A function that never returns, but records the status of the given key.",
+			InArgs: []rpc.ArgDesc{
+				{"key", ``}, // int64
+			},
+		},
+		{
+			Name: "WaitForStatus",
+			Doc:  "// Wait for the call with the given key to have the given status.  Possible statuses are:\n// \"running\", and, \"cancelled\".  Returns the number of nanoseconds left on\n// the deadline of the specified call when the call first began.",
+			InArgs: []rpc.ArgDesc{
+				{"key", ``},    // int64
+				{"status", ``}, // string
+			},
+			OutArgs: []rpc.ArgDesc{
+				{"timeout", ``}, // int64
+			},
+		},
+	},
+}
+
+// ErrorThrowerClientMethods is the client interface
+// containing ErrorThrower methods.
+//
+// A testing interface with methods that throw various types of errors
+type ErrorThrowerClientMethods interface {
+	// Throws v23/vError.Aborted error
+	ThrowAborted(*context.T, ...rpc.CallOpt) error
+	// Throws v23/vError.BadArg error
+	ThrowBadArg(*context.T, ...rpc.CallOpt) error
+	// Throws v23/vError.BadProtocol error
+	ThrowBadProtocol(*context.T, ...rpc.CallOpt) error
+	// Throws v23/vError.Internal error
+	ThrowInternal(*context.T, ...rpc.CallOpt) error
+	// Throws v23/vError.NoAccess error
+	ThrowNoAccess(*context.T, ...rpc.CallOpt) error
+	// Throws v23/vError.NoExist error
+	ThrowNoExist(*context.T, ...rpc.CallOpt) error
+	// Throws v23/vError.NoExistOrNoAccess error
+	ThrowNoExistOrNoAccess(*context.T, ...rpc.CallOpt) error
+	// Throws v23/vError.Unknown error
+	ThrowUnknown(*context.T, ...rpc.CallOpt) error
+	// Throws normal Go error
+	ThrowGoError(*context.T, ...rpc.CallOpt) error
+	// Throws custom error created by using Standard
+	ThrowCustomStandardError(*context.T, ...rpc.CallOpt) error
+}
+
+// ErrorThrowerClientStub adds universal methods to ErrorThrowerClientMethods.
+type ErrorThrowerClientStub interface {
+	ErrorThrowerClientMethods
+	rpc.UniversalServiceMethods
+}
+
+// ErrorThrowerClient returns a client stub for ErrorThrower.
+func ErrorThrowerClient(name string) ErrorThrowerClientStub {
+	return implErrorThrowerClientStub{name}
+}
+
+type implErrorThrowerClientStub struct {
+	name string
+}
+
+func (c implErrorThrowerClientStub) ThrowAborted(ctx *context.T, opts ...rpc.CallOpt) (err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "ThrowAborted", nil, nil, opts...)
+	return
+}
+
+func (c implErrorThrowerClientStub) ThrowBadArg(ctx *context.T, opts ...rpc.CallOpt) (err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "ThrowBadArg", nil, nil, opts...)
+	return
+}
+
+func (c implErrorThrowerClientStub) ThrowBadProtocol(ctx *context.T, opts ...rpc.CallOpt) (err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "ThrowBadProtocol", nil, nil, opts...)
+	return
+}
+
+func (c implErrorThrowerClientStub) ThrowInternal(ctx *context.T, opts ...rpc.CallOpt) (err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "ThrowInternal", nil, nil, opts...)
+	return
+}
+
+func (c implErrorThrowerClientStub) ThrowNoAccess(ctx *context.T, opts ...rpc.CallOpt) (err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "ThrowNoAccess", nil, nil, opts...)
+	return
+}
+
+func (c implErrorThrowerClientStub) ThrowNoExist(ctx *context.T, opts ...rpc.CallOpt) (err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "ThrowNoExist", nil, nil, opts...)
+	return
+}
+
+func (c implErrorThrowerClientStub) ThrowNoExistOrNoAccess(ctx *context.T, opts ...rpc.CallOpt) (err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "ThrowNoExistOrNoAccess", nil, nil, opts...)
+	return
+}
+
+func (c implErrorThrowerClientStub) ThrowUnknown(ctx *context.T, opts ...rpc.CallOpt) (err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "ThrowUnknown", nil, nil, opts...)
+	return
+}
+
+func (c implErrorThrowerClientStub) ThrowGoError(ctx *context.T, opts ...rpc.CallOpt) (err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "ThrowGoError", nil, nil, opts...)
+	return
+}
+
+func (c implErrorThrowerClientStub) ThrowCustomStandardError(ctx *context.T, opts ...rpc.CallOpt) (err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "ThrowCustomStandardError", nil, nil, opts...)
+	return
+}
+
+// ErrorThrowerServerMethods is the interface a server writer
+// implements for ErrorThrower.
+//
+// A testing interface with methods that throw various types of errors
+type ErrorThrowerServerMethods interface {
+	// Throws v23/vError.Aborted error
+	ThrowAborted(*context.T, rpc.ServerCall) error
+	// Throws v23/vError.BadArg error
+	ThrowBadArg(*context.T, rpc.ServerCall) error
+	// Throws v23/vError.BadProtocol error
+	ThrowBadProtocol(*context.T, rpc.ServerCall) error
+	// Throws v23/vError.Internal error
+	ThrowInternal(*context.T, rpc.ServerCall) error
+	// Throws v23/vError.NoAccess error
+	ThrowNoAccess(*context.T, rpc.ServerCall) error
+	// Throws v23/vError.NoExist error
+	ThrowNoExist(*context.T, rpc.ServerCall) error
+	// Throws v23/vError.NoExistOrNoAccess error
+	ThrowNoExistOrNoAccess(*context.T, rpc.ServerCall) error
+	// Throws v23/vError.Unknown error
+	ThrowUnknown(*context.T, rpc.ServerCall) error
+	// Throws normal Go error
+	ThrowGoError(*context.T, rpc.ServerCall) error
+	// Throws custom error created by using Standard
+	ThrowCustomStandardError(*context.T, rpc.ServerCall) error
+}
+
+// ErrorThrowerServerStubMethods is the server interface containing
+// ErrorThrower methods, as expected by rpc.Server.
+// There is no difference between this interface and ErrorThrowerServerMethods
+// since there are no streaming methods.
+type ErrorThrowerServerStubMethods ErrorThrowerServerMethods
+
+// ErrorThrowerServerStub adds universal methods to ErrorThrowerServerStubMethods.
+type ErrorThrowerServerStub interface {
+	ErrorThrowerServerStubMethods
+	// Describe the ErrorThrower interfaces.
+	Describe__() []rpc.InterfaceDesc
+}
+
+// ErrorThrowerServer returns a server stub for ErrorThrower.
+// It converts an implementation of ErrorThrowerServerMethods into
+// an object that may be used by rpc.Server.
+func ErrorThrowerServer(impl ErrorThrowerServerMethods) ErrorThrowerServerStub {
+	stub := implErrorThrowerServerStub{
+		impl: impl,
+	}
+	// Initialize GlobState; always check the stub itself first, to handle the
+	// case where the user has the Glob method defined in their VDL source.
+	if gs := rpc.NewGlobState(stub); gs != nil {
+		stub.gs = gs
+	} else if gs := rpc.NewGlobState(impl); gs != nil {
+		stub.gs = gs
+	}
+	return stub
+}
+
+type implErrorThrowerServerStub struct {
+	impl ErrorThrowerServerMethods
+	gs   *rpc.GlobState
+}
+
+func (s implErrorThrowerServerStub) ThrowAborted(ctx *context.T, call rpc.ServerCall) error {
+	return s.impl.ThrowAborted(ctx, call)
+}
+
+func (s implErrorThrowerServerStub) ThrowBadArg(ctx *context.T, call rpc.ServerCall) error {
+	return s.impl.ThrowBadArg(ctx, call)
+}
+
+func (s implErrorThrowerServerStub) ThrowBadProtocol(ctx *context.T, call rpc.ServerCall) error {
+	return s.impl.ThrowBadProtocol(ctx, call)
+}
+
+func (s implErrorThrowerServerStub) ThrowInternal(ctx *context.T, call rpc.ServerCall) error {
+	return s.impl.ThrowInternal(ctx, call)
+}
+
+func (s implErrorThrowerServerStub) ThrowNoAccess(ctx *context.T, call rpc.ServerCall) error {
+	return s.impl.ThrowNoAccess(ctx, call)
+}
+
+func (s implErrorThrowerServerStub) ThrowNoExist(ctx *context.T, call rpc.ServerCall) error {
+	return s.impl.ThrowNoExist(ctx, call)
+}
+
+func (s implErrorThrowerServerStub) ThrowNoExistOrNoAccess(ctx *context.T, call rpc.ServerCall) error {
+	return s.impl.ThrowNoExistOrNoAccess(ctx, call)
+}
+
+func (s implErrorThrowerServerStub) ThrowUnknown(ctx *context.T, call rpc.ServerCall) error {
+	return s.impl.ThrowUnknown(ctx, call)
+}
+
+func (s implErrorThrowerServerStub) ThrowGoError(ctx *context.T, call rpc.ServerCall) error {
+	return s.impl.ThrowGoError(ctx, call)
+}
+
+func (s implErrorThrowerServerStub) ThrowCustomStandardError(ctx *context.T, call rpc.ServerCall) error {
+	return s.impl.ThrowCustomStandardError(ctx, call)
+}
+
+func (s implErrorThrowerServerStub) Globber() *rpc.GlobState {
+	return s.gs
+}
+
+func (s implErrorThrowerServerStub) Describe__() []rpc.InterfaceDesc {
+	return []rpc.InterfaceDesc{ErrorThrowerDesc}
+}
+
+// ErrorThrowerDesc describes the ErrorThrower interface.
+var ErrorThrowerDesc rpc.InterfaceDesc = descErrorThrower
+
+// descErrorThrower hides the desc to keep godoc clean.
+var descErrorThrower = rpc.InterfaceDesc{
+	Name:    "ErrorThrower",
+	PkgPath: "v.io/x/js.core/test_service",
+	Doc:     "// A testing interface with methods that throw various types of errors",
+	Methods: []rpc.MethodDesc{
+		{
+			Name: "ThrowAborted",
+			Doc:  "// Throws v23/vError.Aborted error",
+		},
+		{
+			Name: "ThrowBadArg",
+			Doc:  "// Throws v23/vError.BadArg error",
+		},
+		{
+			Name: "ThrowBadProtocol",
+			Doc:  "// Throws v23/vError.BadProtocol error",
+		},
+		{
+			Name: "ThrowInternal",
+			Doc:  "// Throws v23/vError.Internal error",
+		},
+		{
+			Name: "ThrowNoAccess",
+			Doc:  "// Throws v23/vError.NoAccess error",
+		},
+		{
+			Name: "ThrowNoExist",
+			Doc:  "// Throws v23/vError.NoExist error",
+		},
+		{
+			Name: "ThrowNoExistOrNoAccess",
+			Doc:  "// Throws v23/vError.NoExistOrNoAccess error",
+		},
+		{
+			Name: "ThrowUnknown",
+			Doc:  "// Throws v23/vError.Unknown error",
+		},
+		{
+			Name: "ThrowGoError",
+			Doc:  "// Throws normal Go error",
+		},
+		{
+			Name: "ThrowCustomStandardError",
+			Doc:  "// Throws custom error created by using Standard",
+		},
+	},
+}
+
+// InvokableTestMethodClientMethods is the client interface
+// containing InvokableTestMethod methods.
+type InvokableTestMethodClientMethods interface {
+	AMethod(*context.T, ...rpc.CallOpt) (string, error)
+}
+
+// InvokableTestMethodClientStub adds universal methods to InvokableTestMethodClientMethods.
+type InvokableTestMethodClientStub interface {
+	InvokableTestMethodClientMethods
+	rpc.UniversalServiceMethods
+}
+
+// InvokableTestMethodClient returns a client stub for InvokableTestMethod.
+func InvokableTestMethodClient(name string) InvokableTestMethodClientStub {
+	return implInvokableTestMethodClientStub{name}
+}
+
+type implInvokableTestMethodClientStub struct {
+	name string
+}
+
+func (c implInvokableTestMethodClientStub) AMethod(ctx *context.T, opts ...rpc.CallOpt) (o0 string, err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "AMethod", nil, []interface{}{&o0}, opts...)
+	return
+}
+
+// InvokableTestMethodServerMethods is the interface a server writer
+// implements for InvokableTestMethod.
+type InvokableTestMethodServerMethods interface {
+	AMethod(*context.T, rpc.ServerCall) (string, error)
+}
+
+// InvokableTestMethodServerStubMethods is the server interface containing
+// InvokableTestMethod methods, as expected by rpc.Server.
+// There is no difference between this interface and InvokableTestMethodServerMethods
+// since there are no streaming methods.
+type InvokableTestMethodServerStubMethods InvokableTestMethodServerMethods
+
+// InvokableTestMethodServerStub adds universal methods to InvokableTestMethodServerStubMethods.
+type InvokableTestMethodServerStub interface {
+	InvokableTestMethodServerStubMethods
+	// Describe the InvokableTestMethod interfaces.
+	Describe__() []rpc.InterfaceDesc
+}
+
+// InvokableTestMethodServer returns a server stub for InvokableTestMethod.
+// It converts an implementation of InvokableTestMethodServerMethods into
+// an object that may be used by rpc.Server.
+func InvokableTestMethodServer(impl InvokableTestMethodServerMethods) InvokableTestMethodServerStub {
+	stub := implInvokableTestMethodServerStub{
+		impl: impl,
+	}
+	// Initialize GlobState; always check the stub itself first, to handle the
+	// case where the user has the Glob method defined in their VDL source.
+	if gs := rpc.NewGlobState(stub); gs != nil {
+		stub.gs = gs
+	} else if gs := rpc.NewGlobState(impl); gs != nil {
+		stub.gs = gs
+	}
+	return stub
+}
+
+type implInvokableTestMethodServerStub struct {
+	impl InvokableTestMethodServerMethods
+	gs   *rpc.GlobState
+}
+
+func (s implInvokableTestMethodServerStub) AMethod(ctx *context.T, call rpc.ServerCall) (string, error) {
+	return s.impl.AMethod(ctx, call)
+}
+
+func (s implInvokableTestMethodServerStub) Globber() *rpc.GlobState {
+	return s.gs
+}
+
+func (s implInvokableTestMethodServerStub) Describe__() []rpc.InterfaceDesc {
+	return []rpc.InterfaceDesc{InvokableTestMethodDesc}
+}
+
+// InvokableTestMethodDesc describes the InvokableTestMethod interface.
+var InvokableTestMethodDesc rpc.InterfaceDesc = descInvokableTestMethod
+
+// descInvokableTestMethod hides the desc to keep godoc clean.
+var descInvokableTestMethod = rpc.InterfaceDesc{
+	Name:    "InvokableTestMethod",
+	PkgPath: "v.io/x/js.core/test_service",
+	Methods: []rpc.MethodDesc{
+		{
+			Name: "AMethod",
+			OutArgs: []rpc.ArgDesc{
+				{"", ``}, // string
+			},
+		},
+	},
+}
+
+// InvokeMethodWithCaveatedIdentityClientMethods is the client interface
+// containing InvokeMethodWithCaveatedIdentity methods.
+type InvokeMethodWithCaveatedIdentityClientMethods interface {
+	Invoke(_ *context.T, name string, cavDesc security.CaveatDescriptor, cavParam *vom.RawBytes, _ ...rpc.CallOpt) error
+}
+
+// InvokeMethodWithCaveatedIdentityClientStub adds universal methods to InvokeMethodWithCaveatedIdentityClientMethods.
+type InvokeMethodWithCaveatedIdentityClientStub interface {
+	InvokeMethodWithCaveatedIdentityClientMethods
+	rpc.UniversalServiceMethods
+}
+
+// InvokeMethodWithCaveatedIdentityClient returns a client stub for InvokeMethodWithCaveatedIdentity.
+func InvokeMethodWithCaveatedIdentityClient(name string) InvokeMethodWithCaveatedIdentityClientStub {
+	return implInvokeMethodWithCaveatedIdentityClientStub{name}
+}
+
+type implInvokeMethodWithCaveatedIdentityClientStub struct {
+	name string
+}
+
+func (c implInvokeMethodWithCaveatedIdentityClientStub) Invoke(ctx *context.T, i0 string, i1 security.CaveatDescriptor, i2 *vom.RawBytes, opts ...rpc.CallOpt) (err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "Invoke", []interface{}{i0, i1, i2}, nil, opts...)
+	return
+}
+
+// InvokeMethodWithCaveatedIdentityServerMethods is the interface a server writer
+// implements for InvokeMethodWithCaveatedIdentity.
+type InvokeMethodWithCaveatedIdentityServerMethods interface {
+	Invoke(_ *context.T, _ rpc.ServerCall, name string, cavDesc security.CaveatDescriptor, cavParam *vom.RawBytes) error
+}
+
+// InvokeMethodWithCaveatedIdentityServerStubMethods is the server interface containing
+// InvokeMethodWithCaveatedIdentity methods, as expected by rpc.Server.
+// There is no difference between this interface and InvokeMethodWithCaveatedIdentityServerMethods
+// since there are no streaming methods.
+type InvokeMethodWithCaveatedIdentityServerStubMethods InvokeMethodWithCaveatedIdentityServerMethods
+
+// InvokeMethodWithCaveatedIdentityServerStub adds universal methods to InvokeMethodWithCaveatedIdentityServerStubMethods.
+type InvokeMethodWithCaveatedIdentityServerStub interface {
+	InvokeMethodWithCaveatedIdentityServerStubMethods
+	// Describe the InvokeMethodWithCaveatedIdentity interfaces.
+	Describe__() []rpc.InterfaceDesc
+}
+
+// InvokeMethodWithCaveatedIdentityServer returns a server stub for InvokeMethodWithCaveatedIdentity.
+// It converts an implementation of InvokeMethodWithCaveatedIdentityServerMethods into
+// an object that may be used by rpc.Server.
+func InvokeMethodWithCaveatedIdentityServer(impl InvokeMethodWithCaveatedIdentityServerMethods) InvokeMethodWithCaveatedIdentityServerStub {
+	stub := implInvokeMethodWithCaveatedIdentityServerStub{
+		impl: impl,
+	}
+	// Initialize GlobState; always check the stub itself first, to handle the
+	// case where the user has the Glob method defined in their VDL source.
+	if gs := rpc.NewGlobState(stub); gs != nil {
+		stub.gs = gs
+	} else if gs := rpc.NewGlobState(impl); gs != nil {
+		stub.gs = gs
+	}
+	return stub
+}
+
+type implInvokeMethodWithCaveatedIdentityServerStub struct {
+	impl InvokeMethodWithCaveatedIdentityServerMethods
+	gs   *rpc.GlobState
+}
+
+func (s implInvokeMethodWithCaveatedIdentityServerStub) Invoke(ctx *context.T, call rpc.ServerCall, i0 string, i1 security.CaveatDescriptor, i2 *vom.RawBytes) error {
+	return s.impl.Invoke(ctx, call, i0, i1, i2)
+}
+
+func (s implInvokeMethodWithCaveatedIdentityServerStub) Globber() *rpc.GlobState {
+	return s.gs
+}
+
+func (s implInvokeMethodWithCaveatedIdentityServerStub) Describe__() []rpc.InterfaceDesc {
+	return []rpc.InterfaceDesc{InvokeMethodWithCaveatedIdentityDesc}
+}
+
+// InvokeMethodWithCaveatedIdentityDesc describes the InvokeMethodWithCaveatedIdentity interface.
+var InvokeMethodWithCaveatedIdentityDesc rpc.InterfaceDesc = descInvokeMethodWithCaveatedIdentity
+
+// descInvokeMethodWithCaveatedIdentity hides the desc to keep godoc clean.
+var descInvokeMethodWithCaveatedIdentity = rpc.InterfaceDesc{
+	Name:    "InvokeMethodWithCaveatedIdentity",
+	PkgPath: "v.io/x/js.core/test_service",
+	Methods: []rpc.MethodDesc{
+		{
+			Name: "Invoke",
+			InArgs: []rpc.ArgDesc{
+				{"name", ``},     // string
+				{"cavDesc", ``},  // security.CaveatDescriptor
+				{"cavParam", ``}, // *vom.RawBytes
+			},
+		},
+	},
+}
+
+// NativeTestClientMethods is the client interface
+// containing NativeTest methods.
+type NativeTestClientMethods interface {
+	PassTime(_ *context.T, t time.Time, _ ...rpc.CallOpt) (time.Time, error)
+	PassError(_ *context.T, e error, _ ...rpc.CallOpt) error
+}
+
+// NativeTestClientStub adds universal methods to NativeTestClientMethods.
+type NativeTestClientStub interface {
+	NativeTestClientMethods
+	rpc.UniversalServiceMethods
+}
+
+// NativeTestClient returns a client stub for NativeTest.
+func NativeTestClient(name string) NativeTestClientStub {
+	return implNativeTestClientStub{name}
+}
+
+type implNativeTestClientStub struct {
+	name string
+}
+
+func (c implNativeTestClientStub) PassTime(ctx *context.T, i0 time.Time, opts ...rpc.CallOpt) (o0 time.Time, err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "PassTime", []interface{}{i0}, []interface{}{&o0}, opts...)
+	return
+}
+
+func (c implNativeTestClientStub) PassError(ctx *context.T, i0 error, opts ...rpc.CallOpt) (err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "PassError", []interface{}{&i0}, nil, opts...)
+	return
+}
+
+// NativeTestServerMethods is the interface a server writer
+// implements for NativeTest.
+type NativeTestServerMethods interface {
+	PassTime(_ *context.T, _ rpc.ServerCall, t time.Time) (time.Time, error)
+	PassError(_ *context.T, _ rpc.ServerCall, e error) error
+}
+
+// NativeTestServerStubMethods is the server interface containing
+// NativeTest methods, as expected by rpc.Server.
+// There is no difference between this interface and NativeTestServerMethods
+// since there are no streaming methods.
+type NativeTestServerStubMethods NativeTestServerMethods
+
+// NativeTestServerStub adds universal methods to NativeTestServerStubMethods.
+type NativeTestServerStub interface {
+	NativeTestServerStubMethods
+	// Describe the NativeTest interfaces.
+	Describe__() []rpc.InterfaceDesc
+}
+
+// NativeTestServer returns a server stub for NativeTest.
+// It converts an implementation of NativeTestServerMethods into
+// an object that may be used by rpc.Server.
+func NativeTestServer(impl NativeTestServerMethods) NativeTestServerStub {
+	stub := implNativeTestServerStub{
+		impl: impl,
+	}
+	// Initialize GlobState; always check the stub itself first, to handle the
+	// case where the user has the Glob method defined in their VDL source.
+	if gs := rpc.NewGlobState(stub); gs != nil {
+		stub.gs = gs
+	} else if gs := rpc.NewGlobState(impl); gs != nil {
+		stub.gs = gs
+	}
+	return stub
+}
+
+type implNativeTestServerStub struct {
+	impl NativeTestServerMethods
+	gs   *rpc.GlobState
+}
+
+func (s implNativeTestServerStub) PassTime(ctx *context.T, call rpc.ServerCall, i0 time.Time) (time.Time, error) {
+	return s.impl.PassTime(ctx, call, i0)
+}
+
+func (s implNativeTestServerStub) PassError(ctx *context.T, call rpc.ServerCall, i0 error) error {
+	return s.impl.PassError(ctx, call, i0)
+}
+
+func (s implNativeTestServerStub) Globber() *rpc.GlobState {
+	return s.gs
+}
+
+func (s implNativeTestServerStub) Describe__() []rpc.InterfaceDesc {
+	return []rpc.InterfaceDesc{NativeTestDesc}
+}
+
+// NativeTestDesc describes the NativeTest interface.
+var NativeTestDesc rpc.InterfaceDesc = descNativeTest
+
+// descNativeTest hides the desc to keep godoc clean.
+var descNativeTest = rpc.InterfaceDesc{
+	Name:    "NativeTest",
+	PkgPath: "v.io/x/js.core/test_service",
+	Methods: []rpc.MethodDesc{
+		{
+			Name: "PassTime",
+			InArgs: []rpc.ArgDesc{
+				{"t", ``}, // time.Time
+			},
+			OutArgs: []rpc.ArgDesc{
+				{"", ``}, // time.Time
+			},
+		},
+		{
+			Name: "PassError",
+			InArgs: []rpc.ArgDesc{
+				{"e", ``}, // error
+			},
+		},
+	},
+}
