veyron/runtimes/google/namimg: allow 'addresses' to be stored in the mounttable and other 'cleanups'

It seems more natural to me to allow 'addresses' rather than 'names' to be
stored in the mount table, so that a name resolves to an address. In practice
we put endpoints in the mount table, represented as strings - i.e. not typed.
Before this CL the mount table would insist that all addresses be rooted names.
As an aside, there was bug wherebe such errors would not be reported to
the client which is fixed in this CL. This CL changes the mount table to
so that endpoint strings can be used directly without being turned into
names, there is still validation of these strings to make sure they
contain a correctly formed address.

In addition to the above, this CL 'cleans up' various inconsistent
uses of 'address' vs 'name' and changes some uses of Resolve to
ResolveX. In particular:

- the Endpoint interface now has a 'Name' method that returns a rooted
  name.
- the MountEntry type has two new methods:
  a. Names: to obtain a slice of names (endpoint plus suffix) replacing the
  ToStringSlice method
  b. MountedServers: to obtain the server addresses as rooted names
- MountEntry.Names, MountedServers or the values in MountEntry now
  cover all possible uses of the data returned by the Mount Table.
- Various 'modules' and tests have been updated to use 'names' exclusively.

We will need to push a new mount table for newly built clients to function.
Existing client/servers should work fine. I'll try this out on the new
'staging' setup if possible.

Change-Id: I4499fdf438a0e659c4fdc81ceed35c2b10fc596f
MultiPart: 1/3
diff --git a/lib/modules/core/core.go b/lib/modules/core/core.go
index efd71cb..c2919fa 100644
--- a/lib/modules/core/core.go
+++ b/lib/modules/core/core.go
@@ -6,7 +6,7 @@
 // root
 //   runs a root mount table as a subprocess
 //   prints the PID=<pid> variable to stdout followed by
-//   an arbitrary number of MT_NAME and MT_ADDR variables.
+//   an arbitrary number of MT_NAME variables.
 //   waits for stdin to be closed before it exits
 //   prints "done" to stdout when stdin is closed.
 // mt <mp>
@@ -42,7 +42,7 @@
 // echoServer <message> <name>
 //    runs on echoServer at <name>, it will echo back <message>: <text>
 //    where <text> is supplied by the client. It prints the PID=<pid>
-//    variable to stdout followd by an arbitrary number of NAME, ADDR
+//    variable to stdout followd by an arbitrary number of NAME
 //    variables.
 // echoClient <name> <text>
 //    invoke <name>.Echo(<text>)
diff --git a/lib/modules/core/core_test.go b/lib/modules/core/core_test.go
index daf036e..b314ad3 100644
--- a/lib/modules/core/core_test.go
+++ b/lib/modules/core/core_test.go
@@ -66,7 +66,6 @@
 	s := expect.NewSession(t, root.Stdout(), time.Second)
 	s.ExpectVar("PID")
 	s.ExpectVar("MT_NAME")
-	s.ExpectVar("MT_ADDR")
 	root.CloseStdin()
 }
 
diff --git a/lib/modules/core/echo.go b/lib/modules/core/echo.go
index 15fb7b3..34c11b8 100644
--- a/lib/modules/core/echo.go
+++ b/lib/modules/core/echo.go
@@ -8,7 +8,6 @@
 
 	"v.io/core/veyron2"
 	"v.io/core/veyron2/ipc"
-	"v.io/core/veyron2/naming"
 	"v.io/core/veyron2/rt"
 	"v.io/core/veyron2/security"
 
@@ -79,8 +78,7 @@
 	}
 	fmt.Fprintf(stdout, "PID=%d\n", os.Getpid())
 	for _, ep := range eps {
-		fmt.Fprintf(stdout, "NAME=%s\n", naming.JoinAddressName(ep.String(), ""))
-		fmt.Fprintf(stdout, "ADDR=%s\n", ep)
+		fmt.Fprintf(stdout, "NAME=%s\n", ep.Name())
 	}
 	modules.WaitForEOF(stdin)
 	return nil
diff --git a/lib/modules/core/mounttable.go b/lib/modules/core/mounttable.go
index 121d376..b549b65 100644
--- a/lib/modules/core/mounttable.go
+++ b/lib/modules/core/mounttable.go
@@ -7,7 +7,6 @@
 	"strings"
 
 	"v.io/core/veyron2"
-	"v.io/core/veyron2/naming"
 	"v.io/core/veyron2/options"
 	"v.io/core/veyron2/rt"
 
@@ -69,9 +68,7 @@
 	}
 	fmt.Fprintf(stdout, "PID=%d\n", os.Getpid())
 	for _, ep := range eps {
-		name := naming.JoinAddressName(ep.String(), "")
-		fmt.Fprintf(stdout, "MT_NAME=%s\n", name)
-		fmt.Fprintf(stdout, "MT_ADDR=%s\n", ep.String())
+		fmt.Fprintf(stdout, "MT_NAME=%s\n", ep.Name())
 	}
 	modules.WaitForEOF(stdin)
 	return nil
diff --git a/lib/modules/core/proxy.go b/lib/modules/core/proxy.go
index 764dbab..00d1977 100644
--- a/lib/modules/core/proxy.go
+++ b/lib/modules/core/proxy.go
@@ -43,16 +43,14 @@
 	}
 	defer proxy.Shutdown()
 
-	pname := naming.JoinAddressName(proxy.Endpoint().String(), "")
 	fmt.Fprintf(stdout, "PID=%d\n", os.Getpid())
-	fmt.Fprintf(stdout, "PROXY_ADDR=%s\n", proxy.Endpoint().String())
-	fmt.Fprintf(stdout, "PROXY_NAME=%s\n", pname)
+	fmt.Fprintf(stdout, "PROXY_NAME=%s\n", proxy.Endpoint().Name())
 	if expected > 0 {
 		defer r.Cleanup()
 		pub := publisher.New(ctx, veyron2.GetNamespace(ctx), time.Minute)
 		defer pub.WaitForStop()
 		defer pub.Stop()
-		pub.AddServer(pname, false)
+		pub.AddServer(proxy.Endpoint().String(), false)
 		for _, name := range args {
 			if len(name) == 0 {
 				return fmt.Errorf("empty name specified on the command line")
diff --git a/lib/modules/core/test_identityd.go b/lib/modules/core/test_identityd.go
index 15ad0fe..8951102 100644
--- a/lib/modules/core/test_identityd.go
+++ b/lib/modules/core/test_identityd.go
@@ -96,7 +96,7 @@
 
 	_, veyronEPs, externalHttpaddress := s.Listen(ctx, &l, *host, *httpaddr, *tlsconfig)
 
-	fmt.Fprintf(stdout, "TEST_IDENTITYD_ADDR=%s\n", veyronEPs[0])
+	fmt.Fprintf(stdout, "TEST_IDENTITYD_NAME=%s\n", veyronEPs[0])
 	fmt.Fprintf(stdout, "TEST_IDENTITYD_HTTP_ADDR=%s\n", externalHttpaddress)
 
 	modules.WaitForEOF(stdin)
diff --git a/lib/modules/core/wspr.go b/lib/modules/core/wspr.go
index 1298f5c..d6d8dd1 100644
--- a/lib/modules/core/wspr.go
+++ b/lib/modules/core/wspr.go
@@ -46,7 +46,7 @@
 		proxy.Serve()
 	}()
 
-	fmt.Fprintf(stdout, "WSPR_ADDR=%s\n", addr.String())
+	fmt.Fprintf(stdout, "WSPR_ADDR=%s\n", addr)
 	modules.WaitForEOF(stdin)
 	return nil
 }
diff --git a/lib/signals/signals_test.go b/lib/signals/signals_test.go
index ba11718..b5ea0bc 100644
--- a/lib/signals/signals_test.go
+++ b/lib/signals/signals_test.go
@@ -336,7 +336,7 @@
 	if err := server.Serve("", device.ConfigServer(&configServer{ch}), vflag.NewAuthorizerOrDie()); err != nil {
 		t.Fatalf("Got error: %v", err)
 	}
-	return server, naming.JoinAddressName(ep[0].String(), ""), ch
+	return server, ep[0].Name(), ch
 
 }
 
diff --git a/runtimes/google/ipc/benchmark/glob/glob_test.go b/runtimes/google/ipc/benchmark/glob/glob_test.go
index 9c75c43..db032b3 100644
--- a/runtimes/google/ipc/benchmark/glob/glob_test.go
+++ b/runtimes/google/ipc/benchmark/glob/glob_test.go
@@ -90,8 +90,7 @@
 	if err := server.ServeDispatcher("", &disp{obj}); err != nil {
 		return "", nil, err
 	}
-	addr := naming.JoinAddressName(endpoints[0].String(), "")
-	return addr, func() { server.Stop() }, nil
+	return endpoints[0].Name(), func() { server.Stop() }, nil
 }
 
 type globObject struct {
diff --git a/runtimes/google/ipc/benchmark/server.go b/runtimes/google/ipc/benchmark/server.go
index 6a7963e..65926a4 100644
--- a/runtimes/google/ipc/benchmark/server.go
+++ b/runtimes/google/ipc/benchmark/server.go
@@ -6,7 +6,6 @@
 	"v.io/core/veyron2"
 	"v.io/core/veyron2/context"
 	"v.io/core/veyron2/ipc"
-	"v.io/core/veyron2/naming"
 	"v.io/core/veyron2/vlog"
 )
 
@@ -45,7 +44,7 @@
 	if err := server.Serve("", BenchmarkServer(&impl{}), flag.NewAuthorizerOrDie()); err != nil {
 		vlog.Fatalf("Serve failed: %v", err)
 	}
-	return naming.JoinAddressName(eps[0].String(), ""), func() {
+	return eps[0].Name(), func() {
 		if err := server.Stop(); err != nil {
 			vlog.Fatalf("Stop() failed: %v", err)
 		}
diff --git a/runtimes/google/ipc/client.go b/runtimes/google/ipc/client.go
index 5b3cda0..6ef039b 100644
--- a/runtimes/google/ipc/client.go
+++ b/runtimes/google/ipc/client.go
@@ -411,7 +411,7 @@
 			return nil, verror.RetryRefetch, verror.Make(verror.NoServers, ctx, name)
 		}
 		// An empty set of protocols means all protocols...
-		ordered, err := filterAndOrderServers(naming.ToStringSlice(resolved), c.preferredProtocols)
+		ordered, err := filterAndOrderServers(resolved.Names(), c.preferredProtocols)
 		if err != nil {
 			return nil, verror.RetryRefetch, verror.Make(verror.NoServers, ctx, name, err)
 		} else if len(ordered) == 0 {
diff --git a/runtimes/google/ipc/client_test.go b/runtimes/google/ipc/client_test.go
index 46b4360..ace8a6d 100644
--- a/runtimes/google/ipc/client_test.go
+++ b/runtimes/google/ipc/client_test.go
@@ -92,11 +92,11 @@
 }
 
 func numServers(t *testing.T, name string) int {
-	servers, err := veyron2.GetNamespace(gctx).Resolve(gctx, name)
+	me, err := veyron2.GetNamespace(gctx).ResolveX(gctx, name)
 	if err != nil {
 		return 0
 	}
-	return len(servers)
+	return len(me.Servers)
 }
 
 // TODO(cnicolaou): figure out how to test and see what the internals
@@ -191,8 +191,7 @@
 		t.Fatalf("unexpected error: %s", err)
 	}
 	server.Serve("", &simple{done}, nil)
-	name := naming.JoinAddressName(eps[0].String(), "")
-	return name, deferFn
+	return eps[0].Name(), deferFn
 }
 
 func testForVerror(t *testing.T, err error, verr ...verror.IDAction) {
diff --git a/runtimes/google/ipc/debug_test.go b/runtimes/google/ipc/debug_test.go
index 1c5782c..ce4c5b1 100644
--- a/runtimes/google/ipc/debug_test.go
+++ b/runtimes/google/ipc/debug_test.go
@@ -54,8 +54,7 @@
 	ep := eps[0]
 	// Call the Foo method on ""
 	{
-		addr := naming.JoinAddressName(ep.String(), "")
-		call, err := client.StartCall(ctx, addr, "Foo", nil)
+		call, err := client.StartCall(ctx, ep.Name(), "Foo", nil)
 		if err != nil {
 			t.Fatalf("client.StartCall failed: %v", err)
 		}
diff --git a/runtimes/google/ipc/full_test.go b/runtimes/google/ipc/full_test.go
index 55d4bcb..3db30e5 100644
--- a/runtimes/google/ipc/full_test.go
+++ b/runtimes/google/ipc/full_test.go
@@ -233,17 +233,18 @@
 }
 
 func verifyMount(t *testing.T, ns naming.Namespace, name string) []string {
-	addrs, err := ns.Resolve(testContext(), name)
+	me, err := ns.ResolveX(testContext(), name)
 	if err != nil {
 		t.Errorf("%s: %s not found in mounttable", loc(1), name)
 		return nil
 	}
-	return addrs
+	return me.Names()
 }
 
 func verifyMountMissing(t *testing.T, ns naming.Namespace, name string) {
-	if servers, err := ns.Resolve(testContext(), name); err == nil {
-		t.Errorf("%s: %s not supposed to be found in mounttable; got %d servers instead", loc(1), name, len(servers))
+	if me, err := ns.ResolveX(testContext(), name); err == nil {
+		names := me.Names()
+		t.Errorf("%s: %s not supposed to be found in mounttable; got %d servers instead: %v", loc(1), name, len(names), names)
 	}
 }
 
@@ -273,18 +274,23 @@
 	vlog.VI(1).Info("server.Stop DONE")
 }
 
-func resolveWSEndpoint(ns naming.Namespace, name string) (string, error) {
+// fakeWSName creates a name containing a endpoint address that forces
+// the use of websockets. It does so by resolving the original name
+// and choosing the 'ws' endpoint from the set of endpoints returned.
+// It must return a name since it'll be passed to StartCall.
+func fakeWSName(ns naming.Namespace, name string) (string, error) {
 	// Find the ws endpoint and use that.
-	servers, err := ns.Resolve(testContext(), name)
+	me, err := ns.ResolveX(testContext(), name)
 	if err != nil {
 		return "", err
 	}
-	for _, s := range servers {
+	names := me.Names()
+	for _, s := range names {
 		if strings.Index(s, "@ws@") != -1 {
 			return s, nil
 		}
 	}
-	return "", fmt.Errorf("No ws endpoint found %v", servers)
+	return "", fmt.Errorf("No ws endpoint found %v", names)
 }
 
 type bundle struct {
@@ -575,7 +581,7 @@
 		vname := test.name
 		if shouldUseWebsocket {
 			var err error
-			vname, err = resolveWSEndpoint(b.ns, vname)
+			vname, err = fakeWSName(b.ns, vname)
 			if err != nil && err != test.startErr {
 				t.Errorf(`%s ns.Resolve got error "%v", want "%v"`, name(test), err, test.startErr)
 				continue
diff --git a/runtimes/google/ipc/server.go b/runtimes/google/ipc/server.go
index 850c601..432242e 100644
--- a/runtimes/google/ipc/server.go
+++ b/runtimes/google/ipc/server.go
@@ -161,7 +161,7 @@
 		if entry, err = s.ns.ResolveX(s.ctx, address); err != nil {
 			return "", err
 		}
-		names = naming.ToStringSlice(entry)
+		names = entry.Names()
 	} else {
 		names = append(names, address)
 	}
@@ -472,7 +472,7 @@
 	}
 	eps := make([]naming.Endpoint, len(ieps))
 	for i, iep := range ieps {
-		s.publisher.AddServer(naming.JoinAddressName(iep.String(), ""), s.servesMountTable)
+		s.publisher.AddServer(iep.String(), s.servesMountTable)
 		eps[i] = iep
 	}
 	return eps, nil
@@ -495,7 +495,7 @@
 	s.Lock()
 	s.listeners[ln] = struct{}{}
 	s.Unlock()
-	s.publisher.AddServer(naming.JoinAddressName(iep.String(), ""), s.servesMountTable)
+	s.publisher.AddServer(iep.String(), s.servesMountTable)
 	return iep, ln, nil
 }
 
@@ -524,7 +524,7 @@
 			s.listenLoop(ln, iep)
 			// The listener is done, so:
 			// (1) Unpublish its name
-			s.publisher.RemoveServer(naming.JoinAddressName(iep.String(), ""))
+			s.publisher.RemoveServer(iep.String())
 		}
 
 		s.Lock()
@@ -611,7 +611,7 @@
 	// Publish all of the addresses
 	for _, pubAddr := range dhcpl.pubAddrs {
 		ep.Address = net.JoinHostPort(pubAddr.Address().String(), dhcpl.pubPort)
-		s.publisher.AddServer(naming.JoinAddressName(ep.String(), ""), s.servesMountTable)
+		s.publisher.AddServer(ep.String(), s.servesMountTable)
 	}
 
 	for setting := range dhcpl.ch {
@@ -655,6 +655,7 @@
 }
 
 func (s *server) Serve(name string, obj interface{}, authorizer security.Authorizer) error {
+	defer vlog.LogCall()()
 	invoker, err := objectToInvoker(obj)
 	if err != nil {
 		return s.newBadArg(fmt.Sprintf("bad object: %v", err))
@@ -663,6 +664,7 @@
 }
 
 func (s *server) ServeDispatcher(name string, disp ipc.Dispatcher) error {
+	defer vlog.LogCall()()
 	s.Lock()
 	defer s.Unlock()
 	vtrace.GetSpan(s.ctx).Annotate("Serving under name: " + name)
@@ -686,6 +688,7 @@
 }
 
 func (s *server) AddName(name string) error {
+	defer vlog.LogCall()()
 	s.Lock()
 	defer s.Unlock()
 	vtrace.GetSpan(s.ctx).Annotate("Serving under name: " + name)
@@ -706,6 +709,7 @@
 }
 
 func (s *server) RemoveName(name string) error {
+	defer vlog.LogCall()()
 	s.Lock()
 	defer s.Unlock()
 	vtrace.GetSpan(s.ctx).Annotate("Removed name: " + name)
diff --git a/runtimes/google/ipc/server_test.go b/runtimes/google/ipc/server_test.go
index ed8f611..9a2975c 100644
--- a/runtimes/google/ipc/server_test.go
+++ b/runtimes/google/ipc/server_test.go
@@ -102,7 +102,7 @@
 	session := expect.NewSession(t, server.Stdout(), time.Minute)
 	session.ReadLine()
 	serverName := session.ExpectVar("NAME")
-	serverEP := session.ExpectVar("ADDR")
+	serverEP, _ := naming.SplitAddressName(serverName)
 	ep, _ := inaming.NewEndpoint(serverEP)
 	makeCall := func() (string, error) {
 		ctx, _ := context.WithDeadline(testContext(), time.Now().Add(10*time.Second))
@@ -168,7 +168,6 @@
 	h.proxy = p
 	s := expect.NewSession(t, p.Stdout(), time.Minute)
 	s.ReadLine()
-	s.ReadLine()
 	h.name = s.ExpectVar("PROXY_NAME")
 	if len(h.name) == 0 {
 		t.Fatalf("failed to get PROXY_NAME from proxyd")
@@ -263,8 +262,8 @@
 	waitfor := func(expect int) {
 		then := time.Now().Add(time.Minute)
 		for {
-			addrs, _ := ns.Resolve(testContext(), name)
-			if len(addrs) == expect {
+			me, err := ns.ResolveX(testContext(), name)
+			if err == nil && len(me.Servers) == expect {
 				close(ch)
 				return
 			}
@@ -280,14 +279,14 @@
 		t.Fatalf("unexpected error for %q: %s", proxyEP, err)
 	}
 	proxiedEP.RID = naming.FixedRoutingID(0x555555555)
-	expectedEndpoints := []string{proxiedEP.String()}
+	expectedNames := []string{naming.JoinAddressName(proxiedEP.String(), "suffix")}
 	if hasLocalListener {
-		expectedEndpoints = append(expectedEndpoints, eps[0].String())
+		expectedNames = append(expectedNames, naming.JoinAddressName(eps[0].String(), "suffix"))
 	}
 
 	// Proxy connetions are created asynchronously, so we wait for the
 	// expected number of endpoints to appear for the specified service name.
-	go waitfor(len(expectedEndpoints))
+	go waitfor(len(expectedNames))
 	select {
 	case <-time.After(time.Minute):
 		t.Fatalf("timedout waiting for two entries in the mount table")
@@ -296,13 +295,12 @@
 
 	got := []string{}
 	for _, s := range verifyMount(t, ns, name) {
-		addr, _ := naming.SplitAddressName(s)
-		got = append(got, addr)
+		got = append(got, s)
 	}
 	sort.Strings(got)
-	sort.Strings(expectedEndpoints)
-	if !reflect.DeepEqual(got, expectedEndpoints) {
-		t.Errorf("got %v, want %v", got, expectedEndpoints)
+	sort.Strings(expectedNames)
+	if !reflect.DeepEqual(got, expectedNames) {
+		t.Errorf("got %v, want %v", got, expectedNames)
 	}
 
 	if hasLocalListener {
@@ -311,13 +309,12 @@
 		// the local endpoint from the mount table entry!  We have to remove both
 		// the tcp and the websocket address.
 		sep := eps[0].String()
-		//wsep := strings.Replace(sep, "@tcp@", "@ws@", 1)
-		ns.Unmount(testContext(), "mountpoint/server", naming.JoinAddressName(sep, ""))
+		ns.Unmount(testContext(), "mountpoint/server", sep)
 	}
 
 	addrs = verifyMount(t, ns, name)
 	if len(addrs) != 1 {
-		t.Fatalf("failed to lookup proxy")
+		t.Fatalf("failed to lookup proxy: addrs %v", addrs)
 	}
 
 	// Proxied endpoint should be published and RPC should succeed (through proxy)
@@ -329,12 +326,13 @@
 	if err := proxy.Stop(); err != nil {
 		t.Fatal(err)
 	}
+
 	if result, err := makeCall(); err == nil || (!strings.HasPrefix(err.Error(), "RESOLVE") && !strings.Contains(err.Error(), "EOF")) {
 		t.Fatalf(`Got (%v, %v) want ("", "RESOLVE: <err>" or "EOF") as proxy is down`, result, err)
 	}
 
 	for {
-		if _, err := ns.Resolve(testContext(), name); err != nil {
+		if _, err := ns.ResolveX(testContext(), name); err != nil {
 			break
 		}
 		time.Sleep(10 * time.Millisecond)
diff --git a/runtimes/google/ipc/stream/vc/vc_test.go b/runtimes/google/ipc/stream/vc/vc_test.go
index 3c05f16..aa6e129 100644
--- a/runtimes/google/ipc/stream/vc/vc_test.go
+++ b/runtimes/google/ipc/stream/vc/vc_test.go
@@ -529,6 +529,7 @@
 func (e endpoint) Network() string             { return "test" }
 func (e endpoint) VersionedString(int) string  { return e.String() }
 func (e endpoint) String() string              { return naming.RoutingID(e).String() }
+func (e endpoint) Name() string                { return naming.JoinAddressName(e.String(), "") }
 func (e endpoint) RoutingID() naming.RoutingID { return naming.RoutingID(e) }
 func (e endpoint) Addr() net.Addr              { return nil }
 func (e endpoint) ServesMountTable() bool      { return false }
diff --git a/runtimes/google/lib/publisher/publisher_test.go b/runtimes/google/lib/publisher/publisher_test.go
index 7169025..c0d0c4d 100644
--- a/runtimes/google/lib/publisher/publisher_test.go
+++ b/runtimes/google/lib/publisher/publisher_test.go
@@ -40,11 +40,11 @@
 	pub := publisher.New(testContext(), ns, time.Second)
 	pub.AddName("foo")
 	pub.AddServer("foo-addr", false)
-	if got, want := resolve(t, ns, "foo"), []string{"foo-addr"}; !reflect.DeepEqual(got, want) {
+	if got, want := resolve(t, ns, "foo"), []string{"/foo-addr"}; !reflect.DeepEqual(got, want) {
 		t.Errorf("got %q, want %q", got, want)
 	}
 	pub.AddServer("bar-addr", false)
-	got, want := resolve(t, ns, "foo"), []string{"bar-addr", "foo-addr"}
+	got, want := resolve(t, ns, "foo"), []string{"/bar-addr", "/foo-addr"}
 	sort.Strings(got)
 	if !reflect.DeepEqual(got, want) {
 		t.Errorf("got %q, want %q", got, want)
diff --git a/runtimes/google/naming/endpoint.go b/runtimes/google/naming/endpoint.go
index 31d4db1..b5f20a8 100644
--- a/runtimes/google/naming/endpoint.go
+++ b/runtimes/google/naming/endpoint.go
@@ -204,6 +204,11 @@
 	return ep.VersionedString(defaultVersion)
 }
 
+func (ep *Endpoint) Name() string {
+	//nologcall
+	return naming.JoinAddressName(ep.String(), "")
+}
+
 func (ep *Endpoint) Addr() net.Addr {
 	//nologcall
 	return &addr{network: ep.Protocol, address: ep.Address}
diff --git a/runtimes/google/naming/namespace/all_test.go b/runtimes/google/naming/namespace/all_test.go
index b63b54d..406a884 100644
--- a/runtimes/google/naming/namespace/all_test.go
+++ b/runtimes/google/naming/namespace/all_test.go
@@ -140,28 +140,28 @@
 	}
 }
 
-func doResolveTest(t *testing.T, fname string, f func(*context.T, string, ...naming.ResolveOpt) ([]string, error), ctx *context.T, name string, want []string, opts ...naming.ResolveOpt) {
-	servers, err := f(ctx, name, opts...)
+func doResolveTest(t *testing.T, fname string, f func(*context.T, string, ...naming.ResolveOpt) (*naming.MountEntry, error), ctx *context.T, name string, want []string, opts ...naming.ResolveOpt) {
+	me, err := f(ctx, name, opts...)
 	if err != nil {
 		boom(t, "Failed to %s %s: %s", fname, name, err)
 	}
-	compare(t, fname, name, servers, want)
+	compare(t, fname, name, me.Names(), want)
 }
 
 func testResolveToMountTable(t *testing.T, ctx *context.T, ns naming.Namespace, name string, want ...string) {
-	doResolveTest(t, "ResolveToMountTable", ns.ResolveToMountTable, ctx, name, want)
+	doResolveTest(t, "ResolveToMountTable", ns.ResolveToMountTableX, ctx, name, want)
 }
 
 func testResolveToMountTableWithPattern(t *testing.T, ctx *context.T, ns naming.Namespace, name string, pattern naming.ResolveOpt, want ...string) {
-	doResolveTest(t, "ResolveToMountTable", ns.ResolveToMountTable, ctx, name, want, pattern)
+	doResolveTest(t, "ResolveToMountTable", ns.ResolveToMountTableX, ctx, name, want, pattern)
 }
 
 func testResolve(t *testing.T, ctx *context.T, ns naming.Namespace, name string, want ...string) {
-	doResolveTest(t, "Resolve", ns.Resolve, ctx, name, want)
+	doResolveTest(t, "Resolve", ns.ResolveX, ctx, name, want)
 }
 
 func testResolveWithPattern(t *testing.T, ctx *context.T, ns naming.Namespace, name string, pattern naming.ResolveOpt, want ...string) {
-	doResolveTest(t, "Resolve", ns.Resolve, ctx, name, want, pattern)
+	doResolveTest(t, "Resolve", ns.ResolveX, ctx, name, want, pattern)
 }
 
 type serverEntry struct {
@@ -197,8 +197,7 @@
 	if err := s.ServeDispatcher(mountPoint, disp); err != nil {
 		boom(t, "Failed to serve mount table at %s: %s", mountPoint, err)
 	}
-	name := naming.JoinAddressName(eps[0].String(), "")
-	return &serverEntry{mountPoint: mountPoint, server: s, endpoint: eps[0], name: name}
+	return &serverEntry{mountPoint: mountPoint, server: s, endpoint: eps[0], name: eps[0].Name()}
 }
 
 const (
@@ -306,8 +305,7 @@
 	}
 }
 
-// TestNamespaceDetails tests more detailed use of the Namespace library,
-// including the intricacies of // meaning and placement.
+// TestNamespaceDetails tests more detailed use of the Namespace library.
 func TestNamespaceDetails(t *testing.T) {
 	sc, c, cleanup := createRuntimes(t)
 	defer cleanup()
@@ -564,7 +562,7 @@
 	for i := 0; i < 40; i++ {
 		cycle += "/c3/c4"
 	}
-	if _, err := ns.Resolve(c, "c1/"+cycle); !verror.Is(err, naming.ErrResolutionDepthExceeded.ID) {
+	if _, err := ns.ResolveX(c, "c1/"+cycle); !verror.Is(err, naming.ErrResolutionDepthExceeded.ID) {
 		boom(t, "Failed to detect cycle")
 	}
 
diff --git a/runtimes/google/naming/namespace/glob.go b/runtimes/google/naming/namespace/glob.go
index 40a3951..0b85a21 100644
--- a/runtimes/google/naming/namespace/glob.go
+++ b/runtimes/google/naming/namespace/glob.go
@@ -56,7 +56,9 @@
 
 		// Don't further resolve s.Server.
 		callCtx, _ := context.WithTimeout(ctx, callTimeout)
-		call, err := client.StartCall(callCtx, s.Server, ipc.GlobMethod, []interface{}{pstr}, options.NoResolve{})
+		// Make sure that we turn the s.Server address or name into a rooted name.
+		serverName := naming.JoinAddressName(s.Server, "")
+		call, err := client.StartCall(callCtx, serverName, ipc.GlobMethod, []interface{}{pstr}, options.NoResolve{})
 		if err != nil {
 			lastErr = err
 			continue // try another instance
diff --git a/runtimes/google/naming/namespace/mount.go b/runtimes/google/naming/namespace/mount.go
index 7af3cf2..9b7d186 100644
--- a/runtimes/google/naming/namespace/mount.go
+++ b/runtimes/google/naming/namespace/mount.go
@@ -27,7 +27,7 @@
 	if err != nil {
 		return
 	}
-	if ierr := call.Finish(&err); ierr != nil {
+	if ierr := call.Finish(&s.err); ierr != nil {
 		s.err = ierr
 	}
 	return
diff --git a/runtimes/google/naming/namespace/resolve.go b/runtimes/google/naming/namespace/resolve.go
index 61631b7..bc79cc8 100644
--- a/runtimes/google/naming/namespace/resolve.go
+++ b/runtimes/google/naming/namespace/resolve.go
@@ -125,7 +125,7 @@
 	if err != nil {
 		return nil, err
 	}
-	return naming.ToStringSlice(e), nil
+	return e.Names(), nil
 }
 
 // ResolveToMountTableX implements veyron2/naming.Namespace.
@@ -186,7 +186,7 @@
 	if err != nil {
 		return nil, err
 	}
-	return naming.ToStringSlice(e), nil
+	return e.Names(), nil
 }
 
 // FlushCache flushes the most specific entry found for name.  It returns true if anything was
diff --git a/runtimes/google/rt/mgmt.go b/runtimes/google/rt/mgmt.go
index 4599eee..e617410 100644
--- a/runtimes/google/rt/mgmt.go
+++ b/runtimes/google/rt/mgmt.go
@@ -8,7 +8,6 @@
 	"v.io/core/veyron2/context"
 	"v.io/core/veyron2/ipc"
 	"v.io/core/veyron2/mgmt"
-	"v.io/core/veyron2/naming"
 	"v.io/core/veyron2/options"
 
 	"v.io/core/veyron/lib/exec"
@@ -51,7 +50,7 @@
 		server.Stop()
 		return nil, err
 	}
-	err = rt.callbackToParent(parentName, naming.JoinAddressName(eps[0].String(), ""))
+	err = rt.callbackToParent(parentName, eps[0].Name())
 	if err != nil {
 		server.Stop()
 		return nil, err
diff --git a/runtimes/google/rt/mgmt_test.go b/runtimes/google/rt/mgmt_test.go
index 450f23b..d735fe3 100644
--- a/runtimes/google/rt/mgmt_test.go
+++ b/runtimes/google/rt/mgmt_test.go
@@ -298,7 +298,7 @@
 	if err := server.Serve("", device.ConfigServer(&configServer{ch}), vflag.NewAuthorizerOrDie()); err != nil {
 		t.Fatalf("Got error: %v", err)
 	}
-	return server, naming.JoinAddressName(eps[0].String(), ""), ch
+	return server, eps[0].Name(), ch
 }
 
 func setupRemoteAppCycleMgr(t *testing.T) (*context.T, modules.Handle, appcycle.AppCycleClientMethods, func()) {
diff --git a/runtimes/google/testing/mocks/naming/namespace.go b/runtimes/google/testing/mocks/naming/namespace.go
index 3665bb2..c46eca8 100644
--- a/runtimes/google/testing/mocks/naming/namespace.go
+++ b/runtimes/google/testing/mocks/naming/namespace.go
@@ -77,7 +77,7 @@
 			suffix := strings.TrimLeft(strings.TrimPrefix(name, prefix), "/")
 			var ret []string
 			for _, s := range servers {
-				ret = append(ret, naming.Join(s, suffix))
+				ret = append(ret, naming.JoinAddressName(s, suffix))
 			}
 			return ret, nil
 		}
diff --git a/services/identity/revocation/revocation_test.go b/services/identity/revocation/revocation_test.go
index 9e45e33..49b37d9 100644
--- a/services/identity/revocation/revocation_test.go
+++ b/services/identity/revocation/revocation_test.go
@@ -9,7 +9,6 @@
 
 	"v.io/core/veyron2"
 	"v.io/core/veyron2/context"
-	"v.io/core/veyron2/naming"
 	"v.io/core/veyron2/rt"
 	"v.io/core/veyron2/security"
 	"v.io/core/veyron2/vom2"
@@ -30,7 +29,7 @@
 		t.Fatalf("dischargerServer.Serve revoker: %s", err)
 	}
 	return veyron2.GetPrincipal(ctx).PublicKey(),
-		naming.JoinAddressName(dischargerEPs[0].String(), ""),
+		dischargerEPs[0].Name(),
 		revokerService,
 		func() {
 			dischargerServer.Stop()
diff --git a/services/mgmt/application/applicationd/main.go b/services/mgmt/application/applicationd/main.go
index 7b52df7..aed66ab 100644
--- a/services/mgmt/application/applicationd/main.go
+++ b/services/mgmt/application/applicationd/main.go
@@ -4,7 +4,6 @@
 	"flag"
 
 	"v.io/core/veyron2"
-	"v.io/core/veyron2/naming"
 	"v.io/core/veyron2/rt"
 	"v.io/core/veyron2/vlog"
 
@@ -49,7 +48,7 @@
 	if err := server.ServeDispatcher(*name, dispatcher); err != nil {
 		vlog.Fatalf("Serve(%v) failed: %v", *name, err)
 	}
-	epName := naming.JoinAddressName(endpoints[0].String(), "")
+	epName := endpoints[0].Name()
 	if *name != "" {
 		vlog.Infof("Application repository serving at %q (%q)", *name, epName)
 	} else {
diff --git a/services/mgmt/binary/binaryd/main.go b/services/mgmt/binary/binaryd/main.go
index 68c81b7..7dc03fa 100644
--- a/services/mgmt/binary/binaryd/main.go
+++ b/services/mgmt/binary/binaryd/main.go
@@ -7,7 +7,6 @@
 	"os"
 
 	"v.io/core/veyron2"
-	"v.io/core/veyron2/naming"
 	"v.io/core/veyron2/rt"
 	"v.io/core/veyron2/vlog"
 
@@ -97,7 +96,7 @@
 		vlog.Errorf("ServeDispatcher(%v) failed: %v", *name, err)
 		return
 	}
-	epName := naming.JoinAddressName(endpoints[0].String(), "")
+	epName := endpoints[0].Name()
 	if *name != "" {
 		vlog.Infof("Binary repository serving at %q (%q)", *name, epName)
 	} else {
diff --git a/services/mgmt/device/deviced/server.go b/services/mgmt/device/deviced/server.go
index 3a89db5..5ec30e7 100644
--- a/services/mgmt/device/deviced/server.go
+++ b/services/mgmt/device/deviced/server.go
@@ -10,7 +10,6 @@
 	"v.io/core/veyron/services/mgmt/device/config"
 	"v.io/core/veyron/services/mgmt/device/impl"
 	"v.io/core/veyron2"
-	"v.io/core/veyron2/naming"
 	"v.io/core/veyron2/rt"
 	"v.io/core/veyron2/vlog"
 )
@@ -42,7 +41,7 @@
 		vlog.Errorf("Listen(%s) failed: %v", roaming.ListenSpec, err)
 		return err
 	}
-	name := naming.JoinAddressName(endpoints[0].String(), "")
+	name := endpoints[0].Name()
 	vlog.VI(0).Infof("Device manager object name: %v", name)
 	configState, err := config.Load()
 	if err != nil {
diff --git a/services/mgmt/pprof/client/proxy_test.go b/services/mgmt/pprof/client/proxy_test.go
index 8b55bf9..174719a 100644
--- a/services/mgmt/pprof/client/proxy_test.go
+++ b/services/mgmt/pprof/client/proxy_test.go
@@ -7,7 +7,6 @@
 	"testing"
 
 	"v.io/core/veyron2"
-	"v.io/core/veyron2/naming"
 	"v.io/core/veyron2/rt"
 	"v.io/core/veyron2/security"
 
@@ -44,7 +43,7 @@
 	if err := s.ServeDispatcher("", &dispatcher{impl.NewPProfService()}); err != nil {
 		t.Fatalf("failed to serve: %v", err)
 	}
-	l, err := client.StartProxy(r, naming.JoinAddressName(endpoints[0].String(), ""))
+	l, err := client.StartProxy(r, endpoints[0].Name())
 	if err != nil {
 		t.Fatalf("failed to start proxy: %v", err)
 	}
diff --git a/services/mounttable/lib/mounttable.go b/services/mounttable/lib/mounttable.go
index 7c85c71..5ecb22d 100644
--- a/services/mounttable/lib/mounttable.go
+++ b/services/mounttable/lib/mounttable.go
@@ -394,8 +394,11 @@
 	}
 	vlog.VI(2).Infof("*********************Mount %q -> %s", ms.name, server)
 
-	// Make sure the server name is reasonable.
-	epString, _ := naming.SplitAddressName(server)
+	// Make sure the server address is reasonable.
+	epString := server
+	if naming.Rooted(server) {
+		epString, _ = naming.SplitAddressName(server)
+	}
 	_, err := veyron2.NewEndpoint(epString)
 	if err != nil {
 		return fmt.Errorf("malformed address %q for mounted server %q", epString, server)
diff --git a/services/mounttable/mounttabled/mounttable.go b/services/mounttable/mounttabled/mounttable.go
index 0c99254..fd8081f 100644
--- a/services/mounttable/mounttabled/mounttable.go
+++ b/services/mounttable/mounttabled/mounttable.go
@@ -55,9 +55,7 @@
 		os.Exit(1)
 	}
 
-	vlog.Infof("Mount table service at: %q endpoint: %s",
-		name,
-		naming.JoinAddressName(mtEndpoint.String(), ""))
+	vlog.Infof("Mount table service at: %q endpoint: %s", name, mtEndpoint.Name())
 
 	if len(*nhName) > 0 {
 		neighborhoodListenSpec := roaming.ListenSpec
@@ -77,7 +75,7 @@
 			os.Exit(1)
 		}
 
-		myObjectName := naming.JoinAddressName(mtEndpoint.String(), "")
+		myObjectName := mtEndpoint.Name()
 
 		nh, err := mounttable.NewNeighborhoodServer(*nhName, myObjectName)
 		if err != nil {
diff --git a/services/mounttable/mounttabled/test.sh b/services/mounttable/mounttabled/test.sh
index 8f301da..54d8b98 100755
--- a/services/mounttable/mounttabled/test.sh
+++ b/services/mounttable/mounttabled/test.sh
@@ -43,6 +43,7 @@
   NHEP=$(${MOUNTTABLE_BIN} glob "${EP}" nh | grep ^nh | \
 	 sed -e 's/ \/@.@ws@[^ ]* (TTL .m..s)//' | cut -d' ' -f2) \
     || (cat "${MTLOG}"; shell_test::fail "line ${LINENO}: failed to identify neighborhood endpoint")
+  NHEP_NAME="/${NHEP}"
 
   # Mount objects and verify the result.
   ${MOUNTTABLE_BIN} mount "${EP}/myself" "${EP}" 5m > /dev/null \
@@ -60,7 +61,7 @@
   shell_test::assert_eq "${GOT}" "${WANT}" "${LINENO}"
 
   # <neighborhood>.Glob('NHNAME')
-  GOT=$("${MOUNTTABLE_BIN}" glob "${NHEP}" "${NHNAME}" | sed 's/TTL [^)]*/TTL XmXXs/' | sort) \
+  GOT=$("${MOUNTTABLE_BIN}" glob "${NHEP_NAME}" "${NHNAME}" | sed 's/TTL [^)]*/TTL XmXXs/' | sort) \
     || shell_test::fail "line ${LINENO}: failed to run mounttable"
   WANT="${NHNAME} ${EP} (TTL XmXXs)"
   shell_test::assert_eq "${GOT}" "${WANT}" "${LINENO}"
diff --git a/services/proxy/proxyd/main.go b/services/proxy/proxyd/main.go
index b7f155a..6307dd8 100644
--- a/services/proxy/proxyd/main.go
+++ b/services/proxy/proxyd/main.go
@@ -52,8 +52,7 @@
 		publisher := publisher.New(ctx, veyron2.GetNamespace(ctx), time.Minute)
 		defer publisher.WaitForStop()
 		defer publisher.Stop()
-		ep := naming.JoinAddressName(proxy.Endpoint().String(), "")
-		publisher.AddServer(ep, false)
+		publisher.AddServer(proxy.Endpoint().String(), false)
 		publisher.AddName(*name)
 	}
 
diff --git a/tools/debug/test.sh b/tools/debug/test.sh
index 133fed4..527241e 100755
--- a/tools/debug/test.sh
+++ b/tools/debug/test.sh
@@ -50,7 +50,7 @@
   GOT=$("${DEBUG_BIN}" "${DEBUG_FLAGS}" glob "${EP}/__debug/logs/*" 2> "${DBGLOG}" | wc -l) \
     || (dumplogs "${DBGLOG}"; shell_test::fail "line ${LINENO}: failed to run debug")
   shell_test::assert_gt "${GOT}" "0" "${LINENO}"
-  
+
   # Test logs size.
   echo "This is a log file" > "${TMPDIR}/my-test-log-file"
   GOT=$("${DEBUG_BIN}" "${DEBUG_FLAGS}" logs size "${EP}/__debug/logs/my-test-log-file" 2> "${DBGLOG}") \
diff --git a/tools/mgmt/device/acl_test.go b/tools/mgmt/device/acl_test.go
index b39841d..b242182 100644
--- a/tools/mgmt/device/acl_test.go
+++ b/tools/mgmt/device/acl_test.go
@@ -7,7 +7,6 @@
 	"strings"
 	"testing"
 
-	"v.io/core/veyron2/naming"
 	"v.io/core/veyron2/security"
 	"v.io/core/veyron2/services/security/access"
 	verror "v.io/core/veyron2/verror2"
@@ -32,7 +31,7 @@
 	cmd := root()
 	var stdout, stderr bytes.Buffer
 	cmd.Init(nil, &stdout, &stderr)
-	deviceName := naming.JoinAddressName(endpoint.String(), "")
+	deviceName := endpoint.Name()
 
 	// Test the 'get' command.
 	tape.SetResponses([]interface{}{GetACLResponse{
@@ -78,7 +77,7 @@
 	cmd := root()
 	var stdout, stderr bytes.Buffer
 	cmd.Init(nil, &stdout, &stderr)
-	deviceName := naming.JoinAddressName(endpoint.String(), "")
+	deviceName := endpoint.Name()
 
 	// Some tests to validate parse.
 	if err := cmd.Execute([]string{"acl", "set", deviceName}); err == nil {
diff --git a/tools/naming/simulator/echo.scr b/tools/naming/simulator/echo.scr
index ca4228e..fe4f59b 100644
--- a/tools/naming/simulator/echo.scr
+++ b/tools/naming/simulator/echo.scr
@@ -11,9 +11,7 @@
 set es=$_
 read $es
 eval $es
-eval $es
 set esName=$NAME
-set esAddr=$ADDR
 
 echoClient $esName "test"
 set ec=$_
@@ -35,9 +33,7 @@
 set es=$_
 read $es
 eval $es
-eval $es
 set es_name=$NAME
-set es_addr=$ADDR
 
 echoClient "a/b" "test 2"
 set ec=$_
diff --git a/tools/naming/simulator/json_example.scr b/tools/naming/simulator/json_example.scr
index e8f740c..e882725 100644
--- a/tools/naming/simulator/json_example.scr
+++ b/tools/naming/simulator/json_example.scr
@@ -9,14 +9,12 @@
 set ROOT_PID=$PID
 eval $root
 set ROOT_NAME=$MT_NAME
-read $root
 json_set ROOT_NAME ROOT_PID
 
 set PROXY_MOUNTPOINT=$ROOT_NAME/proxy/mp
 proxyd -- $localaddr $PROXY_MOUNTPOINT
 set proxyd=$_
 read $proxyd
-read $proxyd
 eval $proxyd
 set PROXYD_NAME=$PROXY_NAME
 splitEP $PROXY_NAME
diff --git a/tools/naming/simulator/mt_complex.scr b/tools/naming/simulator/mt_complex.scr
index 54aaeeb..620dbc1 100644
--- a/tools/naming/simulator/mt_complex.scr
+++ b/tools/naming/simulator/mt_complex.scr
@@ -19,18 +19,14 @@
 set mt_a_h=$m
 read $m
 eval $m
-eval $m
 set mt_a_name=$MT_NAME
-set mt_a_addr=$MT_ADDR
 
 mt  -- $localaddr tl/b
 set m=$_
 set mt_b_h=$m
 eval $m
 eval $m
-eval $m
 set mt_b_name=$MT_NAME
-set mt_b_addr=$MT_ADDR
 
 setRoots $root
 
@@ -80,9 +76,8 @@
 echoServer  -- $localaddr "E1" tl
 set es_E1=$_
 read $es_E1
-read $es_E1
 eval $es_E1
-set es_E1_addr=$ADDR
+set es_E1_name=$NAME
 
 # the echo server above, obscures the mount tables below it.
 # each of the ls (i.e. glob) calls below will lead to 'ipc:unknown method'
@@ -108,7 +103,7 @@
 assert $RN 1
 eval $r
 set ep1=$R0
-assert /$es_E1_addr $ep1
+assert $es_E1_name $ep1
 
 # let's have the echo server shut down
 stop $es_E1
@@ -134,9 +129,8 @@
 echoServer  -- $localaddr "E2" tl/a
 set es_E2=$_
 read $es_E2
-read $es_E2
 eval $es_E2
-set es_E2_addr=$ADDR
+set es_E2_name=$NAME
 
 # we can invoke the echo server 'E2' just fine, probably because
 # we just get lucky and get the most recently mounted address back first.
@@ -171,7 +165,8 @@
 #
 
 # Mount the same server somewhere else
-mount tl/a/c /$es_E2_addr/ 1h
+# TODO(cnicolaou): $es_E2_name needs to be made into an endpoint.
+mount tl/a/c $es_E2_name 1h
 wait $_
 
 ls ...
@@ -192,7 +187,7 @@
 
 # Mount the same server with a really long name.
 set long_name=tl/b/x/y/z/really/long
-mount $long_name /$es_E2_addr// 1h
+mount $long_name $es_E2_name 1h
 wait $_
 
 echoClient $long_name "long baz"
@@ -203,7 +198,7 @@
 # NOTE: do we really need this functionality?
 #
 # ResolveStep is again called on the server for //tl/b/x/y/z/really/long
-mount tl/b/short1 /$es_E2_addr/$long_name 1h
+mount tl/b/short1 $es_E2_name/$long_name 1h
 wait $_
 
 echoClient tl/b/short1 "short baz"
@@ -216,9 +211,7 @@
 set m=$_
 read $m
 eval $m
-eval $m
 set mt_l_name=$MT_NAME
-set mt_l_addr=$MT_ADDR
 
 
 # Create a second mount table with a 'long' name
@@ -227,16 +220,13 @@
 set m=$_
 read $m
 eval $m
-eval $m
 set mt_l2_name=$MT_NAME
-set mt_l2_addr=$MT_ADDR
 
 # Run an echo server that uses that mount table
 echoServer -- $localaddr "E3" $long_name/echo
 set es_E3=$_
-read $es_E3
 eval $es_E3
-set es_E3_addr=$ADDR
+set es_E3_name=$NAME
 
 echoClient $long_name/echo "long E3"
 read $_ o
@@ -249,11 +239,11 @@
 assert $RN 1
 eval $r
 set ep1=$R0
-assert /$mt_l_addr/echo $ep1
+assert $mt_l_name/echo $ep1
 
 # Now, use mount directly to create a 'symlink'
 set symlink_target=some/deep/name/that/is/a/mount
-mount tl/b/symlink /$mt_b_addr/$symlink_target 1h M
+mount tl/b/symlink $mt_b_name/$symlink_target 1h M
 wait $_
 
 ls -- -l tl/b/symlink
@@ -268,7 +258,7 @@
 # now we get the 'interior' returned.
 assert $RN 1
 eval $r
-assert $R0 /$mt_b_addr/$symlink_target
+assert $R0 $mt_b_name/$symlink_target
 # don't close or wait for this command since it'll error out.
 
 
@@ -279,7 +269,7 @@
 assert $RN 1
 eval $r
 set ep1=$R0
-assert /$mt_b_addr/symlink $ep1
+assert $mt_b_name/symlink $ep1
 
 stop $es_E3
 stop $es_E2
diff --git a/tools/naming/simulator/proxy.scr b/tools/naming/simulator/proxy.scr
index 5438e4f..1093006 100644
--- a/tools/naming/simulator/proxy.scr
+++ b/tools/naming/simulator/proxy.scr
@@ -1,4 +1,3 @@
-
 cache off
 
 set localaddr=--veyron.tcp.address=127.0.0.1:0
@@ -19,9 +18,6 @@
 read $esnp
 eval $esnp
 set NP_ECHOS_NAME=$NAME
-eval $esnp
-set NP_ECHOS_ADDR=$ADDR
-
 
 echoClient echo/noproxy "ohh"
 set ec=$_
@@ -32,16 +28,13 @@
 proxyd -- $localaddr $ws $localaddr p1
 set proxy=$_
 read $proxy
-# PROXY_ADDR=<address of proxy>
-eval $proxy
 # PROXY_NAME=<name of proxy>
 eval $proxy
-read $proxy
-splitEP $PROXY_ADDR
+splitEP $PROXY_NAME
 assert $PN 7
 set PROXY_ADDR=$P2
 set PROXY_RID=$P3
-
+eval $proxy
 
 # TODO(cnicolaou): figure out why ls appears to run slowly when a proxy is
 # running, maybe a problem with the mount table.
@@ -56,9 +49,7 @@
 read $eswp
 eval $eswp
 set ECHOS_NAME=$NAME
-eval $eswp
-set ECHOS_ADDR=$ADDR
-splitEP $ADDR
+splitEP $NAME
 set ECHOS_RID=$P3
 
 echoClient echo/withproxy "ahh"
@@ -74,18 +65,21 @@
 
 print "root mt:" $NAMESPACE_ROOT
 print "proxy:" $PROXY_ADDR
-print "no proxy: " $NP_ECHOS_ADDR
-print "with proxy: " $ECHOS_ADDR
+print "no proxy: " $NP_ECHOS_NAME
+print "with proxy: " $ECHOS_NAME
 # The ipc.Server implementation publishes the proxy supplied address and
 # the local address in the mount table
 
 resolve echo/withproxy
 set rs=$_
+stop $rs
+quit
 eval $rs
 # This will be 4 when ipc.Listen can return all of the endpoints in use,
 # then the proxy can return more than one address. We only see 3 endpoints
 # because the proxy server only returns one to the echo server.
 assert $RN 3
+
 eval $rs
 set ep1=$R0
 eval $rs
diff --git a/tools/naming/simulator/public_echo.scr b/tools/naming/simulator/public_echo.scr
index 6942baa..4e508e9 100644
--- a/tools/naming/simulator/public_echo.scr
+++ b/tools/naming/simulator/public_echo.scr
@@ -14,8 +14,6 @@
 read $es
 eval $es
 set es_name=$NAME
-eval $es
-set es_addr=$ADDR
 
 echoClient "$global_name" "test 2"
 set ec=$_
@@ -26,11 +24,9 @@
 resolve $global_name
 set r=$_
 eval $r
-assert $RN 2
+assert $RN 1
 eval $r
 set ep1=$R0
-eval $r
-set ep2=$R1
-assertOneOf $es_name $ep1 $ep2
+assert $es_name $ep1
 
 stop $es
diff --git a/tools/principal/main.go b/tools/principal/main.go
index 9fbdf04..ba05ae6 100644
--- a/tools/principal/main.go
+++ b/tools/principal/main.go
@@ -18,7 +18,6 @@
 	"v.io/core/veyron2"
 	"v.io/core/veyron2/context"
 	"v.io/core/veyron2/ipc"
-	"v.io/core/veyron2/naming"
 	"v.io/core/veyron2/rt"
 	"v.io/core/veyron2/security"
 	"v.io/core/veyron2/vom2"
@@ -713,7 +712,7 @@
 			fmt.Println("You may want to adjust flags affecting the caveats on this blessing, for example using")
 			fmt.Println("the --for flag, or change the extension to something more meaningful")
 			fmt.Println()
-			fmt.Printf("principal bless --remote_key=%v --remote_token=%v %v %v\n", p.PublicKey(), service.token, naming.JoinAddressName(eps[0].String(), ""), extension)
+			fmt.Printf("principal bless --remote_key=%v --remote_token=%v %v %v\n", p.PublicKey(), service.token, eps[0].Name(), extension)
 			fmt.Println()
 			fmt.Println("...waiting for sender..")
 			return <-service.notify
diff --git a/tools/servicerunner/main.go b/tools/servicerunner/main.go
index e615c2d..25c47c9 100644
--- a/tools/servicerunner/main.go
+++ b/tools/servicerunner/main.go
@@ -93,7 +93,7 @@
 	// while the proxyd command instead uses ListenSpec flags.
 	h, err = sh.Start(core.ProxyServerCommand, nil, "--", "--veyron.tcp.protocol=ws", "--veyron.tcp.address=127.0.0.1:0", "test/proxy")
 	panicOnError(err)
-	panicOnError(updateVars(h, vars, "PROXY_ADDR"))
+	panicOnError(updateVars(h, vars, "PROXY_NAME"))
 
 	h, err = sh.Start(core.WSPRCommand, nil, "--", "--veyron.tcp.protocol=ws", "--veyron.tcp.address=127.0.0.1:0", "--veyron.proxy=test/proxy", "--identd=test/identd")
 	panicOnError(err)
@@ -101,7 +101,7 @@
 
 	h, err = sh.Start(core.TestIdentitydCommand, nil, "--", "--veyron.tcp.protocol=ws", "--veyron.tcp.address=127.0.0.1:0", "--veyron.proxy=test/proxy", "--host=localhost", "--httpaddr=localhost:0")
 	panicOnError(err)
-	panicOnError(updateVars(h, vars, "TEST_IDENTITYD_ADDR", "TEST_IDENTITYD_HTTP_ADDR"))
+	panicOnError(updateVars(h, vars, "TEST_IDENTITYD_NAME", "TEST_IDENTITYD_HTTP_ADDR"))
 
 	bytes, err := json.Marshal(vars)
 	panicOnError(err)
diff --git a/tools/servicerunner/servicerunner_test.go b/tools/servicerunner/servicerunner_test.go
index 4a559f5..9996af2 100644
--- a/tools/servicerunner/servicerunner_test.go
+++ b/tools/servicerunner/servicerunner_test.go
@@ -49,9 +49,9 @@
 	expectedVars := []string{
 		"VEYRON_CREDENTIALS",
 		"MT_NAME",
-		"PROXY_ADDR",
+		"PROXY_NAME",
 		"WSPR_ADDR",
-		"TEST_IDENTITYD_ADDR",
+		"TEST_IDENTITYD_NAME",
 		"TEST_IDENTITYD_HTTP_ADDR",
 	}
 	for _, name := range expectedVars {
diff --git a/tools/vrpc/impl_test.go b/tools/vrpc/impl_test.go
index 08da0c1..6f32b71 100644
--- a/tools/vrpc/impl_test.go
+++ b/tools/vrpc/impl_test.go
@@ -192,7 +192,7 @@
 	var stdout, stderr bytes.Buffer
 	cmd.Init(nil, &stdout, &stderr)
 
-	name := naming.JoinAddressName(endpoint.String(), "")
+	name := endpoint.Name()
 	// Test the 'describe' command.
 	if err := cmd.Execute([]string{"describe", name}); err != nil {
 		t.Errorf("%v", err)