diff --git a/examples/bank/bank.vdl b/examples/bank/bank.vdl
new file mode 100644
index 0000000..bbefdad
--- /dev/null
+++ b/examples/bank/bank.vdl
@@ -0,0 +1,28 @@
+/*
+Package bank implements an application to manipulate virtual money. The client's
+Veyron Identity determines the account they can manipulate. New identity's make
+a new account. Clients can deposit, withdraw, transfer, or query their balance
+in virtual currency.
+*/
+package bank
+
+import "veyron2/security"
+
+// Bank allows clients to store virtual money. Certain implementations can use persistent storage.
+// Uses the client's Veyron Identity to determine account access.
+type Bank interface {
+ // Connect causes the bank to bless a new user (string) and return their bank account number (int64). Existing users are not blessed (""), but still receive their account number (int64).
+ Connect() (newIdentity string, accountNumber int64, err error) {security.WriteLabel}
+}
+
+// The BankAccount can only be accessed by blessed users
+type BankAccount interface {
+ // Deposit adds the amount given to this account.
+ Deposit(amount int64) error {security.WriteLabel}
+ // Withdraw reduces the amount given from this account.
+ Withdraw(amount int64) error {security.WriteLabel}
+ // Transfer moves the amount given to the receiver's account.
+ Transfer(receiver int64, amount int64) error {security.WriteLabel}
+ // Balance returns the amount stored in this account.
+ Balance() (int64, error) {security.ReadLabel}
+}
diff --git a/examples/bank/bank.vdl.go b/examples/bank/bank.vdl.go
new file mode 100644
index 0000000..207d354
--- /dev/null
+++ b/examples/bank/bank.vdl.go
@@ -0,0 +1,446 @@
+// This file was auto-generated by the veyron vdl tool.
+// Source: bank.vdl
+
+/*
+Package bank implements an application to manipulate virtual money. The client's
+Veyron Identity determines the account they can manipulate. New identity's make
+a new account. Clients can deposit, withdraw, transfer, or query their balance
+in virtual currency.
+*/
+package bank
+
+import (
+	"veyron2/security"
+
+	// The non-user imports are prefixed with "_gen_" to prevent collisions.
+	_gen_veyron2 "veyron2"
+	_gen_context "veyron2/context"
+	_gen_ipc "veyron2/ipc"
+	_gen_naming "veyron2/naming"
+	_gen_rt "veyron2/rt"
+	_gen_vdl "veyron2/vdl"
+	_gen_wiretype "veyron2/wiretype"
+)
+
+// Bank allows clients to store virtual money. Certain implementations can use persistent storage.
+// Uses the client's Veyron Identity to determine account access.
+// Bank is the interface the client binds and uses.
+// Bank_ExcludingUniversal is the interface without internal framework-added methods
+// to enable embedding without method collisions.  Not to be used directly by clients.
+type Bank_ExcludingUniversal interface {
+	// Connect causes the bank to bless a new user (string) and return their bank account number (int64). Existing users are not blessed (""), but still receive their account number (int64).
+	Connect(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (newIdentity string, accountNumber int64, err error)
+}
+type Bank interface {
+	_gen_ipc.UniversalServiceMethods
+	Bank_ExcludingUniversal
+}
+
+// BankService is the interface the server implements.
+type BankService interface {
+
+	// Connect causes the bank to bless a new user (string) and return their bank account number (int64). Existing users are not blessed (""), but still receive their account number (int64).
+	Connect(context _gen_ipc.ServerContext) (newIdentity string, accountNumber int64, err error)
+}
+
+// BindBank returns the client stub implementing the Bank
+// interface.
+//
+// If no _gen_ipc.Client is specified, the default _gen_ipc.Client in the
+// global Runtime is used.
+func BindBank(name string, opts ..._gen_ipc.BindOpt) (Bank, error) {
+	var client _gen_ipc.Client
+	switch len(opts) {
+	case 0:
+		client = _gen_rt.R().Client()
+	case 1:
+		switch o := opts[0].(type) {
+		case _gen_veyron2.Runtime:
+			client = o.Client()
+		case _gen_ipc.Client:
+			client = o
+		default:
+			return nil, _gen_vdl.ErrUnrecognizedOption
+		}
+	default:
+		return nil, _gen_vdl.ErrTooManyOptionsToBind
+	}
+	stub := &clientStubBank{client: client, name: name}
+
+	return stub, nil
+}
+
+// NewServerBank creates a new server stub.
+//
+// It takes a regular server implementing the BankService
+// interface, and returns a new server stub.
+func NewServerBank(server BankService) interface{} {
+	return &ServerStubBank{
+		service: server,
+	}
+}
+
+// clientStubBank implements Bank.
+type clientStubBank struct {
+	client _gen_ipc.Client
+	name   string
+}
+
+func (__gen_c *clientStubBank) Connect(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (newIdentity string, accountNumber int64, err error) {
+	var call _gen_ipc.Call
+	if call, err = __gen_c.client.StartCall(ctx, __gen_c.name, "Connect", nil, opts...); err != nil {
+		return
+	}
+	if ierr := call.Finish(&newIdentity, &accountNumber, &err); ierr != nil {
+		err = ierr
+	}
+	return
+}
+
+func (__gen_c *clientStubBank) UnresolveStep(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply []string, err error) {
+	var call _gen_ipc.Call
+	if call, err = __gen_c.client.StartCall(ctx, __gen_c.name, "UnresolveStep", nil, opts...); err != nil {
+		return
+	}
+	if ierr := call.Finish(&reply, &err); ierr != nil {
+		err = ierr
+	}
+	return
+}
+
+func (__gen_c *clientStubBank) Signature(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply _gen_ipc.ServiceSignature, err error) {
+	var call _gen_ipc.Call
+	if call, err = __gen_c.client.StartCall(ctx, __gen_c.name, "Signature", nil, opts...); err != nil {
+		return
+	}
+	if ierr := call.Finish(&reply, &err); ierr != nil {
+		err = ierr
+	}
+	return
+}
+
+func (__gen_c *clientStubBank) GetMethodTags(ctx _gen_context.T, method string, opts ..._gen_ipc.CallOpt) (reply []interface{}, err error) {
+	var call _gen_ipc.Call
+	if call, err = __gen_c.client.StartCall(ctx, __gen_c.name, "GetMethodTags", []interface{}{method}, opts...); err != nil {
+		return
+	}
+	if ierr := call.Finish(&reply, &err); ierr != nil {
+		err = ierr
+	}
+	return
+}
+
+// ServerStubBank wraps a server that implements
+// BankService and provides an object that satisfies
+// the requirements of veyron2/ipc.ReflectInvoker.
+type ServerStubBank struct {
+	service BankService
+}
+
+func (__gen_s *ServerStubBank) GetMethodTags(call _gen_ipc.ServerCall, method string) ([]interface{}, error) {
+	// TODO(bprosnitz) GetMethodTags() will be replaces with Signature().
+	// Note: This exhibits some weird behavior like returning a nil error if the method isn't found.
+	// This will change when it is replaced with Signature().
+	switch method {
+	case "Connect":
+		return []interface{}{security.Label(2)}, nil
+	default:
+		return nil, nil
+	}
+}
+
+func (__gen_s *ServerStubBank) Signature(call _gen_ipc.ServerCall) (_gen_ipc.ServiceSignature, error) {
+	result := _gen_ipc.ServiceSignature{Methods: make(map[string]_gen_ipc.MethodSignature)}
+	result.Methods["Connect"] = _gen_ipc.MethodSignature{
+		InArgs: []_gen_ipc.MethodArgument{},
+		OutArgs: []_gen_ipc.MethodArgument{
+			{Name: "newIdentity", Type: 3},
+			{Name: "accountNumber", Type: 37},
+			{Name: "err", Type: 65},
+		},
+	}
+
+	result.TypeDefs = []_gen_vdl.Any{
+		_gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}}
+
+	return result, nil
+}
+
+func (__gen_s *ServerStubBank) UnresolveStep(call _gen_ipc.ServerCall) (reply []string, err error) {
+	if unresolver, ok := __gen_s.service.(_gen_ipc.Unresolver); ok {
+		return unresolver.UnresolveStep(call)
+	}
+	if call.Server() == nil {
+		return
+	}
+	var published []string
+	if published, err = call.Server().Published(); err != nil || published == nil {
+		return
+	}
+	reply = make([]string, len(published))
+	for i, p := range published {
+		reply[i] = _gen_naming.Join(p, call.Name())
+	}
+	return
+}
+
+func (__gen_s *ServerStubBank) Connect(call _gen_ipc.ServerCall) (newIdentity string, accountNumber int64, err error) {
+	newIdentity, accountNumber, err = __gen_s.service.Connect(call)
+	return
+}
+
+// The BankAccount can only be accessed by blessed users
+// BankAccount is the interface the client binds and uses.
+// BankAccount_ExcludingUniversal is the interface without internal framework-added methods
+// to enable embedding without method collisions.  Not to be used directly by clients.
+type BankAccount_ExcludingUniversal interface {
+	// Deposit adds the amount given to this account.
+	Deposit(ctx _gen_context.T, amount int64, opts ..._gen_ipc.CallOpt) (err error)
+	// Withdraw reduces the amount given from this account.
+	Withdraw(ctx _gen_context.T, amount int64, opts ..._gen_ipc.CallOpt) (err error)
+	// Transfer moves the amount given to the receiver's account.
+	Transfer(ctx _gen_context.T, receiver int64, amount int64, opts ..._gen_ipc.CallOpt) (err error)
+	// Balance returns the amount stored in this account.
+	Balance(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply int64, err error)
+}
+type BankAccount interface {
+	_gen_ipc.UniversalServiceMethods
+	BankAccount_ExcludingUniversal
+}
+
+// BankAccountService is the interface the server implements.
+type BankAccountService interface {
+
+	// Deposit adds the amount given to this account.
+	Deposit(context _gen_ipc.ServerContext, amount int64) (err error)
+	// Withdraw reduces the amount given from this account.
+	Withdraw(context _gen_ipc.ServerContext, amount int64) (err error)
+	// Transfer moves the amount given to the receiver's account.
+	Transfer(context _gen_ipc.ServerContext, receiver int64, amount int64) (err error)
+	// Balance returns the amount stored in this account.
+	Balance(context _gen_ipc.ServerContext) (reply int64, err error)
+}
+
+// BindBankAccount returns the client stub implementing the BankAccount
+// interface.
+//
+// If no _gen_ipc.Client is specified, the default _gen_ipc.Client in the
+// global Runtime is used.
+func BindBankAccount(name string, opts ..._gen_ipc.BindOpt) (BankAccount, error) {
+	var client _gen_ipc.Client
+	switch len(opts) {
+	case 0:
+		client = _gen_rt.R().Client()
+	case 1:
+		switch o := opts[0].(type) {
+		case _gen_veyron2.Runtime:
+			client = o.Client()
+		case _gen_ipc.Client:
+			client = o
+		default:
+			return nil, _gen_vdl.ErrUnrecognizedOption
+		}
+	default:
+		return nil, _gen_vdl.ErrTooManyOptionsToBind
+	}
+	stub := &clientStubBankAccount{client: client, name: name}
+
+	return stub, nil
+}
+
+// NewServerBankAccount creates a new server stub.
+//
+// It takes a regular server implementing the BankAccountService
+// interface, and returns a new server stub.
+func NewServerBankAccount(server BankAccountService) interface{} {
+	return &ServerStubBankAccount{
+		service: server,
+	}
+}
+
+// clientStubBankAccount implements BankAccount.
+type clientStubBankAccount struct {
+	client _gen_ipc.Client
+	name   string
+}
+
+func (__gen_c *clientStubBankAccount) Deposit(ctx _gen_context.T, amount int64, opts ..._gen_ipc.CallOpt) (err error) {
+	var call _gen_ipc.Call
+	if call, err = __gen_c.client.StartCall(ctx, __gen_c.name, "Deposit", []interface{}{amount}, opts...); err != nil {
+		return
+	}
+	if ierr := call.Finish(&err); ierr != nil {
+		err = ierr
+	}
+	return
+}
+
+func (__gen_c *clientStubBankAccount) Withdraw(ctx _gen_context.T, amount int64, opts ..._gen_ipc.CallOpt) (err error) {
+	var call _gen_ipc.Call
+	if call, err = __gen_c.client.StartCall(ctx, __gen_c.name, "Withdraw", []interface{}{amount}, opts...); err != nil {
+		return
+	}
+	if ierr := call.Finish(&err); ierr != nil {
+		err = ierr
+	}
+	return
+}
+
+func (__gen_c *clientStubBankAccount) Transfer(ctx _gen_context.T, receiver int64, amount int64, opts ..._gen_ipc.CallOpt) (err error) {
+	var call _gen_ipc.Call
+	if call, err = __gen_c.client.StartCall(ctx, __gen_c.name, "Transfer", []interface{}{receiver, amount}, opts...); err != nil {
+		return
+	}
+	if ierr := call.Finish(&err); ierr != nil {
+		err = ierr
+	}
+	return
+}
+
+func (__gen_c *clientStubBankAccount) Balance(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply int64, err error) {
+	var call _gen_ipc.Call
+	if call, err = __gen_c.client.StartCall(ctx, __gen_c.name, "Balance", nil, opts...); err != nil {
+		return
+	}
+	if ierr := call.Finish(&reply, &err); ierr != nil {
+		err = ierr
+	}
+	return
+}
+
+func (__gen_c *clientStubBankAccount) UnresolveStep(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply []string, err error) {
+	var call _gen_ipc.Call
+	if call, err = __gen_c.client.StartCall(ctx, __gen_c.name, "UnresolveStep", nil, opts...); err != nil {
+		return
+	}
+	if ierr := call.Finish(&reply, &err); ierr != nil {
+		err = ierr
+	}
+	return
+}
+
+func (__gen_c *clientStubBankAccount) Signature(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply _gen_ipc.ServiceSignature, err error) {
+	var call _gen_ipc.Call
+	if call, err = __gen_c.client.StartCall(ctx, __gen_c.name, "Signature", nil, opts...); err != nil {
+		return
+	}
+	if ierr := call.Finish(&reply, &err); ierr != nil {
+		err = ierr
+	}
+	return
+}
+
+func (__gen_c *clientStubBankAccount) GetMethodTags(ctx _gen_context.T, method string, opts ..._gen_ipc.CallOpt) (reply []interface{}, err error) {
+	var call _gen_ipc.Call
+	if call, err = __gen_c.client.StartCall(ctx, __gen_c.name, "GetMethodTags", []interface{}{method}, opts...); err != nil {
+		return
+	}
+	if ierr := call.Finish(&reply, &err); ierr != nil {
+		err = ierr
+	}
+	return
+}
+
+// ServerStubBankAccount wraps a server that implements
+// BankAccountService and provides an object that satisfies
+// the requirements of veyron2/ipc.ReflectInvoker.
+type ServerStubBankAccount struct {
+	service BankAccountService
+}
+
+func (__gen_s *ServerStubBankAccount) GetMethodTags(call _gen_ipc.ServerCall, method string) ([]interface{}, error) {
+	// TODO(bprosnitz) GetMethodTags() will be replaces with Signature().
+	// Note: This exhibits some weird behavior like returning a nil error if the method isn't found.
+	// This will change when it is replaced with Signature().
+	switch method {
+	case "Deposit":
+		return []interface{}{security.Label(2)}, nil
+	case "Withdraw":
+		return []interface{}{security.Label(2)}, nil
+	case "Transfer":
+		return []interface{}{security.Label(2)}, nil
+	case "Balance":
+		return []interface{}{security.Label(1)}, nil
+	default:
+		return nil, nil
+	}
+}
+
+func (__gen_s *ServerStubBankAccount) Signature(call _gen_ipc.ServerCall) (_gen_ipc.ServiceSignature, error) {
+	result := _gen_ipc.ServiceSignature{Methods: make(map[string]_gen_ipc.MethodSignature)}
+	result.Methods["Balance"] = _gen_ipc.MethodSignature{
+		InArgs: []_gen_ipc.MethodArgument{},
+		OutArgs: []_gen_ipc.MethodArgument{
+			{Name: "", Type: 37},
+			{Name: "", Type: 65},
+		},
+	}
+	result.Methods["Deposit"] = _gen_ipc.MethodSignature{
+		InArgs: []_gen_ipc.MethodArgument{
+			{Name: "amount", Type: 37},
+		},
+		OutArgs: []_gen_ipc.MethodArgument{
+			{Name: "", Type: 65},
+		},
+	}
+	result.Methods["Transfer"] = _gen_ipc.MethodSignature{
+		InArgs: []_gen_ipc.MethodArgument{
+			{Name: "receiver", Type: 37},
+			{Name: "amount", Type: 37},
+		},
+		OutArgs: []_gen_ipc.MethodArgument{
+			{Name: "", Type: 65},
+		},
+	}
+	result.Methods["Withdraw"] = _gen_ipc.MethodSignature{
+		InArgs: []_gen_ipc.MethodArgument{
+			{Name: "amount", Type: 37},
+		},
+		OutArgs: []_gen_ipc.MethodArgument{
+			{Name: "", Type: 65},
+		},
+	}
+
+	result.TypeDefs = []_gen_vdl.Any{
+		_gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}}
+
+	return result, nil
+}
+
+func (__gen_s *ServerStubBankAccount) UnresolveStep(call _gen_ipc.ServerCall) (reply []string, err error) {
+	if unresolver, ok := __gen_s.service.(_gen_ipc.Unresolver); ok {
+		return unresolver.UnresolveStep(call)
+	}
+	if call.Server() == nil {
+		return
+	}
+	var published []string
+	if published, err = call.Server().Published(); err != nil || published == nil {
+		return
+	}
+	reply = make([]string, len(published))
+	for i, p := range published {
+		reply[i] = _gen_naming.Join(p, call.Name())
+	}
+	return
+}
+
+func (__gen_s *ServerStubBankAccount) Deposit(call _gen_ipc.ServerCall, amount int64) (err error) {
+	err = __gen_s.service.Deposit(call, amount)
+	return
+}
+
+func (__gen_s *ServerStubBankAccount) Withdraw(call _gen_ipc.ServerCall, amount int64) (err error) {
+	err = __gen_s.service.Withdraw(call, amount)
+	return
+}
+
+func (__gen_s *ServerStubBankAccount) Transfer(call _gen_ipc.ServerCall, receiver int64, amount int64) (err error) {
+	err = __gen_s.service.Transfer(call, receiver, amount)
+	return
+}
+
+func (__gen_s *ServerStubBankAccount) Balance(call _gen_ipc.ServerCall) (reply int64, err error) {
+	reply, err = __gen_s.service.Balance(call)
+	return
+}
diff --git a/examples/bank/bank/main.go b/examples/bank/bank/main.go
new file mode 100644
index 0000000..92228f6
--- /dev/null
+++ b/examples/bank/bank/main.go
@@ -0,0 +1,204 @@
+// Binary bank is a bank client that interacts with bankd and pbankd.
+// Users connect to a bank service and can send commands to it.
+package main
+
+import (
+	"bufio"
+	"flag"
+	"fmt"
+	"os"
+	"strconv"
+	"strings"
+
+	"veyron/examples/bank"
+	idutil "veyron/services/identity/util"
+
+	"veyron2"
+	"veyron2/naming"
+	"veyron2/rt"
+	"veyron2/security"
+)
+
+var (
+	// TODO(rthellend): Remove the address flag when the config manager is working.
+	address               = flag.String("address", "", "the address/endpoint of the bank server")
+	serverPattern         = flag.String("server_pattern", "*", "server_pattern is an optional pattern for the expected identity of the fortune server. Example: the pattern \"myorg/fortune\" matches identities with names \"myorg/fortune\" or \"myorg\". If the flag is absent then the default pattern \"*\" matches all identities.")
+	accountMountTableName string
+)
+
+const bankMountTableName string = "veyron/bank"
+
+// Parses str and returns a nonnegative integer
+func getInt(str string, name string) (int64, bool) {
+	v, err := strconv.ParseInt(str, 0, 64)
+	if err != nil {
+		fmt.Printf("given %s %s was not an integer: %s\n", name, str, err)
+		return 0, true
+	}
+	return v, false
+}
+
+func main() {
+	// Create the Veyron runtime using VEYRON_IDENTITY
+	runtime := rt.Init()
+	log := runtime.Logger()
+
+	// Construct a new stub that binds to serverEndpoint without
+	// using the name service
+	var bankServer bank.Bank
+	var err error
+	if *address != "" {
+		bankServer, err = bank.BindBank(naming.JoinAddressName(*address, "//bank"))
+	} else {
+		bankServer, err = bank.BindBank("veyron/bank")
+	}
+	if err != nil {
+		log.Fatal("error binding to server: ", err)
+	}
+
+	// First, Connect to the bank to retrieve the location you should bind to.
+	newIdentity, bankAccountNumber, err := bankServer.Connect(runtime.TODOContext(), veyron2.RemoteID(*serverPattern))
+	if err != nil {
+		log.Fatalf("%s.Connect failed: %s\n", bankMountTableName, err)
+	}
+	fmt.Printf("Successfully connected to the bank with account: %d\n", bankAccountNumber)
+
+	client := runtime.Client()
+	// If you got a new identity, you should update your PrivateID and make a new client with that identity.
+	if newIdentity != "" {
+		// Decode the new identity
+		var newPublicID security.PublicID
+		err := idutil.Base64VomDecode(newIdentity, &newPublicID)
+		if err != nil {
+			log.Fatalf("failed to decode the given public id: %s\n", err)
+		}
+
+		// Derive the new PrivateID
+		derivedIdentity, err := runtime.Identity().Derive(newPublicID)
+		if err != nil {
+			log.Fatalf("failed to derive identity: %s\n", err)
+		}
+
+		// Update the PrivateID at VEYRON_IDENTITY
+		path := os.Getenv("VEYRON_IDENTITY")
+		f, err := os.OpenFile(path, os.O_WRONLY, 0600)
+		if err != nil {
+			log.Fatalf("failed to open identity file for writing: %s\n", err)
+		}
+		err = security.SaveIdentity(f, derivedIdentity)
+		if err != nil {
+			log.Fatalf("failed to save identity: %s\n", err)
+		}
+		err = f.Close()
+		if err != nil {
+			log.Fatalf("could not close file %q, %s\n", path, err)
+		}
+
+		// Make a NewClient and update the other one. Do not close the old client; we need its connection to the Mount Table.
+		client, err = runtime.NewClient(veyron2.LocalID(derivedIdentity))
+		if err != nil {
+			log.Fatalf("failed to create new client: %s\n", err)
+		}
+	}
+
+	// Bind to the bank account service
+	accountMountTableName = fmt.Sprintf("veyron/bank/%d", bankAccountNumber)
+	bindLocation := fmt.Sprintf("//bank/%d", bankAccountNumber)
+	var accountServer bank.BankAccount
+	if *address != "" { // Connect directly to the server's endpoint
+		accountServer, err = bank.BindBankAccount(naming.JoinAddressName(*address, bindLocation), client)
+	} else { // Use the Mount Table to connect to the server
+		accountServer, err = bank.BindBankAccount(accountMountTableName, client)
+	}
+	if err != nil {
+		log.Fatalf("error binding to server: ", err)
+	}
+
+	// Read commands from standard input until the user decides to quit/exit.
+	end := false
+	for !end {
+		fmt.Print("Your command: ")
+
+		// Read input from user
+		in := bufio.NewReader(os.Stdin)
+		input, _ := in.ReadString('\n')
+		commands := strings.Fields(input)
+
+		if len(commands) == 0 {
+			fmt.Println("Please enter a command. 'help' displays the list of commands.")
+			continue
+		}
+
+		switch commands[0] {
+		case "bankAccountNumber":
+			fmt.Printf("Your bank account number is %d\n", bankAccountNumber)
+		case "deposit":
+			if len(commands) < 2 {
+				fmt.Println("deposit takes an amount")
+				break
+			}
+			amount, e := getInt(commands[1], "amount")
+			if e {
+				break
+			}
+			err := accountServer.Deposit(runtime.TODOContext(), amount, veyron2.RemoteID(*serverPattern))
+			if err != nil {
+				fmt.Printf("%s.Deposit failed: %s\n", accountMountTableName, err)
+				break
+			}
+			fmt.Printf("Deposited %d\n", amount)
+		case "withdraw":
+			if len(commands) < 2 {
+				fmt.Println("withdraw takes an amount")
+				break
+			}
+			amount, e := getInt(commands[1], "amount")
+			if e {
+				break
+			}
+			err := accountServer.Withdraw(runtime.TODOContext(), amount, veyron2.RemoteID(*serverPattern))
+			if err != nil {
+				fmt.Printf("%s.Withdraw failed: %s\n", accountMountTableName, err)
+				break
+			}
+			fmt.Printf("Withdrew %d\n", amount)
+		case "transfer":
+			if len(commands) < 3 {
+				fmt.Println("transfer takes an account number and an amount")
+				break
+			}
+			accountNumber, e1 := getInt(commands[1], "account number")
+			amount, e2 := getInt(commands[2], "amount")
+			if e1 || e2 {
+				break
+			}
+			err := accountServer.Transfer(runtime.TODOContext(), accountNumber, amount, veyron2.RemoteID(*serverPattern))
+			if err != nil {
+				fmt.Printf("%s.Transfer failed: %s\n", accountMountTableName, err)
+				break
+			}
+			fmt.Printf("Transferred %d to %d\n", amount, accountNumber)
+		case "balance":
+			balance, err := accountServer.Balance(runtime.TODOContext(), veyron2.RemoteID(*serverPattern))
+			if err != nil {
+				fmt.Printf("%s.Balance failed: %s\n", accountMountTableName, err)
+				break
+			}
+			fmt.Printf("User has balance %d\n", balance)
+		case "help":
+			fmt.Println("You can do the following actions:")
+			fmt.Println("bankAccountNumber: check your account number")
+			fmt.Println("balance: check your account balance")
+			fmt.Println("deposit [N>=0]: deposit money into your account")
+			fmt.Println("withdraw [N>=0]: withdraw money from your account")
+			fmt.Println("transfer [account number] [N>=0]: transfer money to another account")
+			fmt.Println("quit: quit the program")
+			fmt.Println("exit: also quits the program")
+		case "exit", "quit":
+			fmt.Println("Quitting...")
+			end = true
+		default:
+			fmt.Printf("Unknown command: %s\n", commands[0])
+		}
+	}
+}
diff --git a/examples/bank/pbankd/main.go b/examples/bank/pbankd/main.go
new file mode 100644
index 0000000..9e27a8b
--- /dev/null
+++ b/examples/bank/pbankd/main.go
@@ -0,0 +1,439 @@
+// Binary pbankd is a simple implementation of the bank service.
+// Binary bank clients can connect to this bank service to manage virtual bank
+// accounts. Unlike bankd, pbankd uses the Veyron Store. It can recover user
+// data after a crash, but it must always connect to the stored service.
+// Unlike bankd, pbankd prevents race conditions with transactions.
+package main
+
+import (
+	"errors"
+	"flag"
+	"fmt"
+	"math/rand"
+	"os"
+	"os/user"
+	"path/filepath"
+	"reflect"
+	"regexp"
+	"strings"
+	"time"
+
+	"veyron/examples/bank"
+	"veyron/examples/bank/schema"
+	"veyron/lib/signals"
+	"veyron/security/caveat"
+	idutil "veyron/services/identity/util"
+
+	"veyron2"
+	"veyron2/ipc"
+	"veyron2/rt"
+	"veyron2/security"
+	"veyron2/storage"
+	"veyron2/storage/vstore"
+	"veyron2/storage/vstore/primitives"
+	"veyron2/vlog"
+)
+
+// Duration of a bank account blessing, intended to be very long.
+const BLESS_DURATION = 24 * 10000 * time.Hour
+
+// Ensure that account numbers are all 6 digits long.
+const MIN_ACCOUNT_NUMBER = 100000
+const MAX_ACCOUNT_NUMBER = 999999
+const SUFFIX_REGEXP = "/[0-9]{6}"
+
+// Where we will store the bank in the store database.
+const BANK_ROOT string = "/Bank"
+
+var (
+	storeName string
+	ACCOUNTS  string
+	runtime   veyron2.Runtime
+)
+
+func init() {
+	username := "unknown"
+	if u, err := user.Current(); err == nil {
+		username = u.Username
+	}
+	hostname := "unknown"
+	if h, err := os.Hostname(); err == nil {
+		hostname = h
+	}
+	dir := "global/vstore/" + hostname + "/" + username
+
+	// Parse the flags (variableName, flagName, defaultValue, description)
+	flag.StringVar(&storeName, "store", dir, "Name of the Veyron store")
+
+	// Set the random seed to the current time to increase psuedorandomness.
+	rand.Seed(time.Now().Unix())
+
+	// Set the name for the ACCOUNTS 'constant'. TODO(alexfandrianto): Is there a better way to know the field is named "Accounts"?
+	ACCOUNTS = reflect.TypeOf(schema.Bank{}).Field(0).Name
+}
+
+// The following struct and functions handle construction of the persistent bank.
+type pbankd struct {
+	// Pointer to the store
+	store storage.Store
+
+	// Current Transaction
+	transaction storage.Transaction
+
+	// The bank's private ID (used for blessing)
+	ID security.PrivateID
+}
+
+// newPbankd creates a new persistent bank structure.
+func newPbankd(store storage.Store, identity security.PrivateID) *pbankd {
+	b := &pbankd{
+		store: store,
+		ID:    identity,
+	}
+	return b
+}
+
+// InitializeBank bank details in the store; currently only initializes the root.
+func (b *pbankd) initializeBank() {
+	b.newTransaction()
+	b.initializeBankRoot()
+	if err := b.commit(); err != nil {
+		vlog.Fatal(err)
+	}
+}
+
+// initializeBankRoot prepares the bank root as BANK_ROOT if it isn't yet in the Veyron store.
+func (b *pbankd) initializeBankRoot() {
+	// Create parent directories for the bank root, if necessary
+	l := strings.Split(BANK_ROOT, "/")
+	fmt.Println(l)
+	for i, _ := range l {
+		fmt.Println(i)
+		prefix := filepath.Join(l[:i]...)
+		o := b.store.Bind(prefix)
+		if exist, err := o.Exists(runtime.TODOContext(), b.transaction); err != nil {
+			vlog.Infof("Error checking existence at %q: %s", prefix, err)
+		} else if !exist {
+			if _, err := o.Put(runtime.TODOContext(), b.transaction, &schema.Dir{}); err != nil {
+				vlog.Infof("Error creating parent %q: %s", prefix, err)
+			}
+			fmt.Printf("%q was created!\n", prefix)
+		} else {
+			fmt.Printf("%q was already present in the store.\n", prefix)
+		}
+	}
+
+	// Add the bank schema to the store at BANK_ROOT, if necessary
+	o := b.store.Bind(BANK_ROOT)
+	if exist, err := o.Exists(runtime.TODOContext(), b.transaction); err != nil {
+		vlog.Infof("Error checking existence at %q: %s", BANK_ROOT, err)
+	} else if !exist {
+		_, err := o.Put(runtime.TODOContext(), b.transaction, &schema.Bank{})
+		if err != nil {
+			vlog.Infof("Error creating bank at %q: %s", BANK_ROOT, err)
+		}
+	}
+}
+
+// Register creates an account for a new user with the given bankName.
+func (b *pbankd) Connect(context ipc.ServerContext) (string, int64, error) {
+	// Check if the RemoteID() has been blessed by the bank
+	if num := getBankAccountNumber(context); num != 0 {
+		// Look up the user and return their bank account number
+		fmt.Println("This client is blessed!")
+		fmt.Printf("ID: %d\n", num)
+		return "", num, nil
+	} else {
+		fmt.Println("This client isn't blessed. Let's bless them!")
+		// Use the store
+		b.newTransaction()
+
+		// Keep rolling until we get an unseen number
+		randID := rand.Int63n(MAX_ACCOUNT_NUMBER-MIN_ACCOUNT_NUMBER) + MIN_ACCOUNT_NUMBER
+		for b.isUser(randID) {
+			randID = rand.Int63n(MAX_ACCOUNT_NUMBER-MIN_ACCOUNT_NUMBER) + MIN_ACCOUNT_NUMBER
+		}
+		fmt.Printf("ID: %d\n", randID)
+
+		// Bless the user
+		pp := security.PrincipalPattern(context.LocalID().Names()[0])
+		pID, err := b.ID.Bless(
+			context.RemoteID(),
+			fmt.Sprintf("%d", randID),
+			BLESS_DURATION,
+			[]security.ServiceCaveat{security.UniversalCaveat(caveat.PeerIdentity{pp})},
+		)
+		if err != nil {
+			vlog.Fatal(err)
+		}
+
+		// Encode the public ID
+		enc, err := idutil.Base64VomEncode(pID)
+		if err != nil {
+			vlog.Fatal(err)
+		}
+
+		// Store the user into the database
+		b.registerNewUser(randID)
+		err = b.commit()
+		if err != nil {
+			vlog.Fatal(err)
+		}
+
+		// Ensure the new user is a user before returning the blessing and ID
+		if b.isUser(randID) {
+			return enc, randID, nil
+		}
+		return "", 0, fmt.Errorf("failed to register user")
+	}
+}
+
+// Deposit adds the amount given to this account.
+func (b *pbankd) Deposit(context ipc.ServerContext, amount int64) error {
+	user := getBankAccountNumber(context)
+	if user == 0 {
+		return fmt.Errorf("couldn't retrieve account number")
+	}
+	b.newTransaction()
+	if !b.isUser(user) {
+		return fmt.Errorf("user isn't registered")
+	} else if amount < 0 {
+		return fmt.Errorf("deposit amount %d is negative", amount)
+	}
+	b.changeBalance(user, amount)
+	return b.commit()
+}
+
+// Withdraw reduces the amount given from this account.
+func (b *pbankd) Withdraw(context ipc.ServerContext, amount int64) error {
+	user := getBankAccountNumber(context)
+	if user == 0 {
+		return fmt.Errorf("couldn't retrieve account number")
+	}
+	b.newTransaction()
+	if !b.isUser(user) {
+		return fmt.Errorf("user isn't registered")
+	} else if amount < 0 {
+		return fmt.Errorf("withdraw amount %d is negative", amount)
+	} else if balance := b.checkBalance(user); amount > balance {
+		return fmt.Errorf("withdraw amount %d exceeds balance %d", amount, balance)
+	}
+	b.changeBalance(user, -amount)
+	return b.commit()
+}
+
+// Transfer moves the amount given to the receiver.
+func (b *pbankd) Transfer(context ipc.ServerContext, accountNumber int64, amount int64) error {
+	user := getBankAccountNumber(context)
+	if user == 0 {
+		return fmt.Errorf("couldn't retrieve account number")
+	}
+	b.newTransaction()
+	if !b.isUser(user) {
+		return fmt.Errorf("user isn't registered")
+	} else if !b.isUser(accountNumber) {
+		return fmt.Errorf("%d isn't registered", accountNumber)
+	} else if amount < 0 {
+		return fmt.Errorf("transfer amount %d is negative", amount)
+	} else if balance := b.checkBalance(user); amount > balance {
+		return fmt.Errorf("transfer amount %d exceeds balance %d", amount, balance)
+	}
+	b.changeBalance(user, -amount)
+	b.changeBalance(accountNumber, amount)
+	return b.commit()
+}
+
+// Balance returns the amount stored by the given user.
+// Throws an error if the user is invalid.
+func (b *pbankd) Balance(context ipc.ServerContext) (int64, error) {
+	user := getBankAccountNumber(context)
+	if user == 0 {
+		return 0, fmt.Errorf("couldn't retrieve account number")
+	}
+	if !b.isUser(user) {
+		return 0, fmt.Errorf("user isn't registered")
+	}
+	return b.checkBalance(user), nil
+}
+
+/*
+ Helper functions for the persistent bank service that deal with store access.
+*/
+
+// newTransaction starts a new transaction.
+func (b *pbankd) newTransaction() {
+	b.transaction = primitives.NewTransaction(runtime.TODOContext())
+}
+
+// commit commits the current transaction.
+func (b *pbankd) commit() error {
+	err := b.transaction.Commit(runtime.TODOContext())
+	b.transaction = nil
+	if err != nil {
+		return fmt.Errorf("Failed to commit transaction: %s", err)
+	}
+	return nil
+}
+
+// isUser helps determine if the given user is part of the system or not.
+func (b *pbankd) isUser(accountNumber int64) bool {
+	// If this is a user, their location in the store should exist.
+	prefix := filepath.Join(BANK_ROOT, ACCOUNTS, fmt.Sprintf("%d", accountNumber))
+	o := b.store.Bind(prefix)
+	exist, err := o.Exists(runtime.TODOContext(), b.transaction)
+	if err != nil {
+		vlog.Infof("Error checking existence at %s: %s", prefix, err)
+		return false
+	}
+	return exist
+}
+
+// Obtains the bank account number of the user. Returns 0 if it could not be found.
+func getBankAccountNumber(context ipc.ServerContext) int64 {
+	bankName := context.LocalID().Names()[0]
+
+	// Untrusted clients have no names.
+	if len(context.RemoteID().Names()) == 0 {
+		return 0
+	}
+
+	// Otherwise, extract the account number from the name.
+	name := context.RemoteID().Names()[0]
+	if match, err := regexp.MatchString(bankName+SUFFIX_REGEXP, name); err != nil {
+		vlog.Infof("MatchString error: %s", err)
+		return 0
+	} else if !match {
+		vlog.Infof("No matching name found")
+		return 0
+	}
+	var v int64
+	_, err := fmt.Sscanf(name, bankName+"/%d", &v)
+	if err != nil {
+		vlog.Infof("Failure to parse ID from %s: %s", name, err)
+		return 0
+	}
+	return v
+}
+
+// registerNewUser adds the user to the system under the specified name and returns success.
+func (b *pbankd) registerNewUser(user int64) {
+	// Create the user's account
+	prefix := filepath.Join(BANK_ROOT, ACCOUNTS, fmt.Sprintf("%d", user))
+	o := b.store.Bind(prefix)
+	if _, err := o.Put(runtime.TODOContext(), b.transaction, int64(0)); err != nil {
+		vlog.Infof("Error creating %s: %s", prefix, err)
+	}
+}
+
+// checkBalance gets the user's balance from the store
+func (b *pbankd) checkBalance(user int64) int64 {
+	prefix := filepath.Join(BANK_ROOT, ACCOUNTS, fmt.Sprintf("%d", user))
+	o := b.store.Bind(prefix)
+	e, err := o.Get(runtime.TODOContext(), b.transaction)
+	if err != nil {
+		vlog.Infof("Error getting %s: %s", prefix, err)
+	}
+	value, _ := e.Value.(int64)
+	return value
+}
+
+// changeBalance modifies the user's balance in the store
+func (b *pbankd) changeBalance(user int64, amount int64) {
+	prefix := filepath.Join(BANK_ROOT, ACCOUNTS, fmt.Sprintf("%d", user))
+	o := b.store.Bind(prefix)
+	e, err := o.Get(runtime.TODOContext(), b.transaction)
+	if err != nil {
+		vlog.Infof("Error getting %s: %s", prefix, err)
+	}
+	if _, err := o.Put(runtime.TODOContext(), b.transaction, e.Value.(int64)+amount); err != nil {
+		vlog.Infof("Error changing %s: %s", prefix, err)
+	}
+}
+
+// This custom bank dispatcher has two interfaces with distinct authorizers.
+func newBankDispatcher(bankServer interface{}, bankAccountServer interface{}, authBank security.Authorizer, authBankAccount security.Authorizer) ipc.Dispatcher {
+	return BankDispatcher{ipc.ReflectInvoker(bankServer), ipc.ReflectInvoker(bankAccountServer), authBank, authBankAccount}
+}
+
+type BankDispatcher struct {
+	invokerBank        ipc.Invoker
+	invokerBankAccount ipc.Invoker
+	authBank           security.Authorizer
+	authBankAccount    security.Authorizer
+}
+
+func (d BankDispatcher) Lookup(suffix string) (ipc.Invoker, security.Authorizer, error) {
+	fmt.Println("Dispatcher Lookup Suffix:", suffix)
+	if suffix != "" {
+		return d.invokerBankAccount, d.authBankAccount, nil
+	}
+	return d.invokerBank, d.authBank, nil
+}
+
+// The custom account authorizer checks if the RemoteID matches a regexp pattern and allows only Reads and Writes.
+type AccountAuthorizer string
+
+func (aa AccountAuthorizer) Authorize(ctx security.Context) error {
+	name := ctx.RemoteID().Names()[0]
+	match, err := regexp.MatchString(string(aa), name)
+	fmt.Printf("Authorizing for Account %s %t\n", name, match)
+	if err != nil {
+		return err
+	}
+	if match {
+		if ctx.Label() != security.ReadLabel && ctx.Label() != security.WriteLabel {
+			return errors.New("unauthorized; may only read or write")
+		}
+		return nil
+	}
+	return errors.New("unauthorized to access account")
+}
+
+func main() {
+	// Create a new server instance.
+	runtime = rt.Init()
+	s, err := runtime.NewServer()
+	if err != nil {
+		vlog.Fatal("failure creating server: ", err)
+	}
+
+	// Connect to the Veyron Store
+	vlog.Infof("Binding to store on %s", storeName)
+	st, err := vstore.New(storeName)
+	if err != nil {
+		vlog.Fatalf("Can't connect to store: %s: %s", storeName, err)
+	}
+
+	// Create the bank server and bank account server stubs, using the store connection
+	pbankd := newPbankd(st, runtime.Identity())
+	pbankd.initializeBank()
+	bankServer := bank.NewServerBank(pbankd)
+	bankAccountServer := bank.NewServerBankAccount(pbankd)
+
+	// Setup bank and account authorizers.
+	bankAuth := security.NewACLAuthorizer(security.ACL{security.AllPrincipals: security.LabelSet(security.ReadLabel | security.WriteLabel)})
+	bankAccountAuth := AccountAuthorizer(runtime.Identity().PublicID().Names()[0] + SUFFIX_REGEXP)
+
+	// Register the "bank" prefix with a bank dispatcher.
+	if err := s.Register("bank", newBankDispatcher(bankServer, bankAccountServer, bankAuth, bankAccountAuth)); err != nil {
+		vlog.Fatal("error registering service: ", err)
+	}
+
+	// Create an endpoint and begin listening.
+	endpoint, err := s.Listen("tcp", "127.0.0.1:0")
+	if err == nil {
+		fmt.Printf("Listening at: %v\n", endpoint)
+	} else {
+		vlog.Fatal("error listening to service: ", err)
+	}
+
+	// Publish the service in the mount table.
+	mountName := "veyron"
+	fmt.Printf("Mounting bank on %s, endpoint /%s\n", mountName, endpoint)
+	if err := s.Publish(mountName); err != nil {
+		vlog.Fatal("s.Publish() failed: ", err)
+	}
+
+	// Wait forever.
+	<-signals.ShutdownOnSignals()
+}
diff --git a/examples/bank/schema/init.go b/examples/bank/schema/init.go
new file mode 100644
index 0000000..2040e0f
--- /dev/null
+++ b/examples/bank/schema/init.go
@@ -0,0 +1,11 @@
+// This schema registers structs used in the bank example to the VOM for the Veyron store.
+package schema
+
+import (
+	"veyron2/vom"
+)
+
+func init() {
+	vom.Register(&Dir{})
+	vom.Register(&Bank{})
+}
diff --git a/examples/bank/schema/schema.vdl b/examples/bank/schema/schema.vdl
new file mode 100644
index 0000000..0a34090
--- /dev/null
+++ b/examples/bank/schema/schema.vdl
@@ -0,0 +1,13 @@
+package schema
+
+// Dir is used to represent directories.
+type Dir struct{
+	// TODO(jyh): The IDL does not recognize empty structs.  Fix it and remove this
+	// useless field.
+	X byte
+}
+
+// Bank is used to represent the information stored in a bank.
+type Bank struct {
+        Accounts map[string]int64
+}
diff --git a/examples/bank/schema/schema.vdl.go b/examples/bank/schema/schema.vdl.go
new file mode 100644
index 0000000..8d51fc8
--- /dev/null
+++ b/examples/bank/schema/schema.vdl.go
@@ -0,0 +1,16 @@
+// This file was auto-generated by the veyron vdl tool.
+// Source: schema.vdl
+
+package schema
+
+// Dir is used to represent directories.
+type Dir struct {
+	// TODO(jyh): The IDL does not recognize empty structs.  Fix it and remove this
+	// useless field.
+	X byte
+}
+
+// Bank is used to represent the information stored in a bank.
+type Bank struct {
+	Accounts map[string]int64
+}
diff --git a/services/store/typeregistryhack/init.go b/services/store/typeregistryhack/init.go
index 31a37f1..2b5c0ac 100644
--- a/services/store/typeregistryhack/init.go
+++ b/services/store/typeregistryhack/init.go
@@ -14,6 +14,8 @@
 	_ "veyron/examples/storage/mdb/schema"
 	// Register todos types.
 	_ "veyron/examples/todos/schema"
+	// Register bank types.
+	_ "veyron/examples/bank/schema"
 
 	"veyron2/vom"
 )
