Merge "veyron/tools/naming/simulator: add support for running proxies, sundry fixes."
diff --git a/lib/exec/exec_test.go b/lib/exec/exec_test.go
index cc1b292..f34b280 100644
--- a/lib/exec/exec_test.go
+++ b/lib/exec/exec_test.go
@@ -394,6 +394,22 @@
 	clean(t, ph)
 }
 
+func TestExitEarly(t *testing.T) {
+	name := "exitEarly"
+	cmd := helperCommand(name)
+	tk := timekeeper.NewManualTime()
+	ph := vexec.NewParentHandle(cmd, vexec.TimeKeeperOpt{tk})
+	err := ph.Start()
+	if err != nil {
+		t.Fatalf("%s: start: %v", name, err)
+	}
+	e := ph.Wait(time.Second)
+	if e == nil || e.Error() != "exit status 1" {
+		t.Errorf("Unexpected value for error: %v\n", e)
+	}
+	clean(t, ph)
+}
+
 func verifyNoExecVariable() {
 	version := os.Getenv(vexec.VersionVariable)
 	if len(version) != 0 {
@@ -434,6 +450,12 @@
 	cmd, args := args[0], args[1:]
 
 	switch cmd {
+	case "exitEarly":
+		_, err := vexec.GetChildHandle()
+		if err != nil {
+			log.Fatal(os.Stderr, "%s\n", err)
+		}
+		os.Exit(1)
 	case "testNeverReady":
 		_, err := vexec.GetChildHandle()
 		if err != nil {
diff --git a/lib/flags/doc.go b/lib/flags/doc.go
index ff98c9d..ef8c2c5 100644
--- a/lib/flags/doc.go
+++ b/lib/flags/doc.go
@@ -1,36 +1,13 @@
 // Package flags provides flag definitions for commonly used flags and
 // and, where appropriate, implementations of the flag.Value interface
-// for those flags to ensure that only valid values of those flags
-// are supplied.
-// In general, this package will be used by veyron profiles and the
-// runtime implementations, but can also be used by any application
+// for those flags to ensure that only valid values of those flags are
+// supplied. In general, this package will be used by veyron profiles and
+// the runtime implementations, but can also be used by any application
 // that wants access to the flags and environment variables it supports.
 //
 // TODO(cnicolaou): move reading of environment variables to here also,
 // flags will override the environment variable settings.
+//
+// TODO(cnicolaou): implement simply subsetting of the flags to be defined
+// and parsed - e.g. for server configs, basic runtime configs/security etc.
 package flags
-
-import "flag"
-
-type Flags struct {
-	ListenProtocolFlag TCPProtocolFlag
-	ListenAddressFlag  IPHostPortFlag
-	ListenProxyFlag    string
-	NamespaceRootsFlag string // TODO(cnicolaou): provide flag.Value impl
-	CredentialsFlag    string // TODO(cnicolaou): provide flag.Value impl
-}
-
-// New returns a new instance of flags.Flags. Calling Parse on the supplied
-// flagSet will populate the fields of the return flags.Flags with the appropriate
-// values.
-func New(fs *flag.FlagSet) *Flags {
-	t := &Flags{}
-	t.ListenProtocolFlag = TCPProtocolFlag{"tcp"}
-	t.ListenAddressFlag = IPHostPortFlag{Port: "0"}
-	fs.Var(&t.ListenProtocolFlag, "veyron.tcp.protocol", "protocol to listen with")
-	fs.Var(&t.ListenAddressFlag, "veyron.tcp.address", "address to listen on")
-	fs.StringVar(&t.ListenProxyFlag, "veyron.proxy", "", "object name of proxy service to use to export services across network boundaries")
-	fs.StringVar(&t.NamespaceRootsFlag, "veyron.namespace.roots", "", ": separated list of roots for the local namespace")
-	fs.StringVar(&t.CredentialsFlag, "veyron.credentials", "", "directory to use for storing security credentials")
-	return t
-}
diff --git a/lib/flags/flags.go b/lib/flags/flags.go
new file mode 100644
index 0000000..270b72f
--- /dev/null
+++ b/lib/flags/flags.go
@@ -0,0 +1,44 @@
+package flags
+
+import "flag"
+
+type Flags struct {
+	// The FlagSet passed in as a parameter to New
+	FlagSet *flag.FlagSet
+
+	// As needed to initialize ipc.ListenSpec.
+	ListenProtocolFlag TCPProtocolFlag
+	ListenAddressFlag  IPHostPortFlag
+	ListenProxyFlag    string
+
+	// TODO(cnicolaou): implement these.
+	NamespaceRootsFlag string // TODO(cnicolaou): provide flag.Value impl
+	CredentialsFlag    string // TODO(cnicolaou): provide flag.Value impl
+}
+
+// New returns a new instance of flags.Flags. Calling Parse on the supplied
+// flagSet will populate the fields of the returned flags.Flags with the
+// appropriate values. The currently supported set of flags only allows
+// for configuring one service at a time, but in the future this will
+// be expanded to support multiple services.
+func New(fs *flag.FlagSet) *Flags {
+	t := &Flags{FlagSet: fs}
+	t.ListenProtocolFlag = TCPProtocolFlag{"tcp"}
+	t.ListenAddressFlag = IPHostPortFlag{Port: "0"}
+	fs.Var(&t.ListenProtocolFlag, "veyron.tcp.protocol", "protocol to listen with")
+	fs.Var(&t.ListenAddressFlag, "veyron.tcp.address", "address to listen on")
+	fs.StringVar(&t.ListenProxyFlag, "veyron.proxy", "", "object name of proxy service to use to export services across network boundaries")
+	fs.StringVar(&t.NamespaceRootsFlag, "veyron.namespace.roots", "", "colon separated list of roots for the local namespace")
+	fs.StringVar(&t.CredentialsFlag, "veyron.credentials", "", "directory to use for storing security credentials")
+	return t
+}
+
+// Args returns the unparsed args, as per flag.Args
+func (fs *Flags) Args() []string {
+	return fs.FlagSet.Args()
+}
+
+// Parse parses the supplied args, as per flag.Parse
+func (fs *Flags) Parse(args []string) error {
+	return fs.FlagSet.Parse(args)
+}
diff --git a/lib/flags/flags_test.go b/lib/flags/flags_test.go
index 4030af6..7b17e99 100644
--- a/lib/flags/flags_test.go
+++ b/lib/flags/flags_test.go
@@ -2,6 +2,7 @@
 
 import (
 	"flag"
+	"io/ioutil"
 	"testing"
 
 	"veyron.io/veyron/veyron/lib/flags"
@@ -21,4 +22,23 @@
 	if got, want := fl.ListenAddressFlag.String(), addr; got != want {
 		t.Errorf("got %q, want %q", got, want)
 	}
+	if got, want := len(fl.Args()), 0; got != want {
+		t.Errorf("got %d, want %d", got, want)
+	}
+}
+
+func TestFlagError(t *testing.T) {
+	fs := flag.NewFlagSet("test", flag.ContinueOnError)
+	fs.SetOutput(ioutil.Discard)
+	fl := flags.New(fs)
+	addr := "192.168.10.1:0"
+	args := []string{"--xxxveyron.tcp.address=" + addr, "not an arg"}
+	err := fl.Parse(args)
+	if err == nil {
+		t.Fatalf("expected this to fail!")
+	}
+	if got, want := len(fl.Args()), 1; got != want {
+		t.Errorf("got %d, want %d [args: %v]", got, want, fl.Args())
+	}
+
 }
diff --git a/lib/modules/core/core.go b/lib/modules/core/core.go
index 9aa5767..bf4e6d4 100644
--- a/lib/modules/core/core.go
+++ b/lib/modules/core/core.go
@@ -37,37 +37,64 @@
 //
 // setRoots <name>...
 //    sets the local namespace's roots to the supplied names.
-// echoClient
-// echoServer
+//
+// echoServer <message> <name>
+//    runs on echoServer at <name>, it will echo back <message>: <text>
+//    where <text> is supplied by the client
+// echoClient <name> <text>
+//    invoke <name>.Echo(<text>)
+//
+// proxyd <names>...
+//    runs a proxy server
 package core
 
 import "veyron.io/veyron/veyron/lib/modules"
 
 const (
-	RootMTCommand            = "root"
-	MTCommand                = "mt"
+	// Functions
 	LSCommand                = "ls"
-	LSExternalCommand        = "lse"
 	SetNamespaceRootsCommand = "setRoots"
 	ResolveCommand           = "resolve"
 	ResolveMTCommand         = "resolveMT"
-	EchoServerCommand        = "echoServer"
-	EchoClientCommand        = "echoClient"
 	SleepCommand             = "sleep"
 	TimeCommand              = "time"
 	MountCommand             = "mount"
 	NamespaceCacheCommand    = "cache"
+	// Subprocesses
+	EchoServerCommand  = "echoServer"
+	EchoClientCommand  = "echoClient"
+	RootMTCommand      = "root"
+	MTCommand          = "mt"
+	LSExternalCommand  = "lse"
+	ProxyServerCommand = "proxyd"
+	ShellCommand       = "sh"
 )
 
 // NewShell returns a new Shell instance with the core commands installed.
 func NewShell() *modules.Shell {
-	shell := modules.NewShell(".*")
+	shell := modules.NewShell("")
 	Install(shell)
 	return shell
 }
 
 // Install installs the core commands into the supplied Shell.
 func Install(shell *modules.Shell) {
+	// Explicitly add the subprocesses so that we can provide a help string
+	shell.AddSubprocess(EchoServerCommand, `<message> <name>
+	mount an echo server at <name>, it will prepend <message> to its responses`)
+	shell.AddSubprocess(EchoClientCommand, `
+		<name> <text>
+		invoke name.Echo(<text>)`)
+	shell.AddSubprocess(RootMTCommand, `run a root mount table
+		it will output MT_NAME, MT_ADDR and PID`)
+	shell.AddSubprocess(MTCommand, `<name>
+		run a mount table mounted at <name>`)
+	shell.AddSubprocess(LSExternalCommand, `<glob>
+		run a glob command as an external subprocess`)
+	shell.AddSubprocess(ProxyServerCommand, `<name>...
+		run a proxy server mounted at the specified names`)
+	//	shell.AddSubprocess(ShellCommand, subshell, "")
+
 	shell.AddFunction(LSCommand, ls, `<glob>...
 	issues glob requests using the current processes namespace library`)
 	shell.AddFunction(ResolveCommand, resolveObject, `<name>
diff --git a/lib/modules/core/core_internal_test.go b/lib/modules/core/core_internal_test.go
new file mode 100644
index 0000000..3679f2b
--- /dev/null
+++ b/lib/modules/core/core_internal_test.go
@@ -0,0 +1,21 @@
+package core
+
+import "testing"
+
+func TestCheckArgs(t *testing.T) {
+	if got, want := checkArgs([]string{}, 1, "<a>"), `wrong # args (got 0, expected 1) expected: "<a>" got: []`; got == nil || got.Error() != want {
+		t.Errorf("got %v, want %v", got, want)
+	}
+	if got, want := checkArgs([]string{}, -1, "<a>"), `wrong # args (got 0, expected >=1) expected: "<a>" got: []`; got == nil || got.Error() != want {
+		t.Errorf("got %v, want %v", got, want)
+	}
+	if got := checkArgs([]string{"a"}, 1, ""); got != nil {
+		t.Errorf("unexpected error: %s", got)
+	}
+	if got := checkArgs([]string{"a"}, -1, ""); got != nil {
+		t.Errorf("unexpected error: %s", got)
+	}
+	if got := checkArgs([]string{"a", "b"}, -1, ""); got != nil {
+		t.Errorf("unexpected error: %s", got)
+	}
+}
diff --git a/lib/modules/core/core_test.go b/lib/modules/core/core_test.go
index 843221c..c108b72 100644
--- a/lib/modules/core/core_test.go
+++ b/lib/modules/core/core_test.go
@@ -11,12 +11,13 @@
 
 	"veyron.io/veyron/veyron2/naming"
 	"veyron.io/veyron/veyron2/rt"
+	"veyron.io/veyron/veyron2/vlog"
 
 	"veyron.io/veyron/veyron/lib/expect"
 	"veyron.io/veyron/veyron/lib/modules"
 	"veyron.io/veyron/veyron/lib/modules/core"
-
 	"veyron.io/veyron/veyron/lib/testutil"
+	_ "veyron.io/veyron/veyron/profiles"
 )
 
 func TestCommands(t *testing.T) {
@@ -38,6 +39,7 @@
 	sh := core.NewShell()
 	return sh, func() {
 		if testing.Verbose() {
+			vlog.Infof("------ cleanup ------")
 			sh.Cleanup(os.Stderr, os.Stderr)
 		} else {
 			sh.Cleanup(nil, nil)
@@ -45,10 +47,15 @@
 	}
 }
 
+func testArgs(args ...string) []string {
+	var targs = []string{"--", "--veyron.tcp.address=127.0.0.1:0"}
+	return append(targs, args...)
+}
+
 func TestRoot(t *testing.T) {
 	shell, fn := newShell()
 	defer fn()
-	root, err := shell.Start(core.RootMTCommand)
+	root, err := shell.Start(core.RootMTCommand, testArgs()...)
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
@@ -59,16 +66,17 @@
 	root.CloseStdin()
 }
 
-func startMountTables(t *testing.T, sh *modules.Shell, mountPoints ...string) (map[string]string, error) {
+func startMountTables(t *testing.T, sh *modules.Shell, mountPoints ...string) (map[string]string, func(), error) {
 	// Start root mount table
-	root, err := sh.Start(core.RootMTCommand)
+	root, err := sh.Start(core.RootMTCommand, testArgs()...)
 	if err != nil {
 		t.Fatalf("unexpected error for root mt: %s", err)
 	}
+	sh.Forget(root)
 	rootSession := expect.NewSession(t, root.Stdout(), time.Minute)
 	rootName := rootSession.ExpectVar("MT_NAME")
 	if t.Failed() {
-		return nil, rootSession.Error()
+		return nil, nil, rootSession.Error()
 	}
 	sh.SetVar("NAMESPACE_ROOT", rootName)
 	mountAddrs := make(map[string]string)
@@ -76,20 +84,27 @@
 
 	// Start the mount tables
 	for _, mp := range mountPoints {
-		h, err := sh.Start(core.MTCommand, mp)
+		h, err := sh.Start(core.MTCommand, testArgs(mp)...)
 		if err != nil {
-			return nil, fmt.Errorf("unexpected error for mt %q: %s", mp, err)
+			return nil, nil, fmt.Errorf("unexpected error for mt %q: %s", mp, err)
 		}
 		s := expect.NewSession(t, h.Stdout(), time.Minute)
 		// Wait until each mount table has at least called Serve to
 		// mount itself.
 		mountAddrs[mp] = s.ExpectVar("MT_NAME")
 		if s.Failed() {
-			return nil, s.Error()
+			return nil, nil, s.Error()
 		}
 	}
-	return mountAddrs, nil
-
+	deferFn := func() {
+		if testing.Verbose() {
+			vlog.Infof("------ root shutdown ------")
+			root.Shutdown(os.Stderr, os.Stderr)
+		} else {
+			root.Shutdown(nil, nil)
+		}
+	}
+	return mountAddrs, deferFn, nil
 }
 
 func getMatchingMountpoint(r [][]string) string {
@@ -115,10 +130,12 @@
 	defer fn()
 
 	mountPoints := []string{"a", "b", "c", "d", "e"}
-	mountAddrs, err := startMountTables(t, shell, mountPoints...)
+	mountAddrs, fn, err := startMountTables(t, shell, mountPoints...)
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
+	defer fn()
+
 	rootName := mountAddrs["root"]
 	ls, err := shell.Start(core.LSCommand, rootName+"/...")
 	if err != nil {
@@ -184,7 +201,7 @@
 	shell, fn := newShell()
 	defer fn()
 
-	srv, err := shell.Start(core.EchoServerCommand, "test", "")
+	srv, err := shell.Start(core.EchoServerCommand, testArgs("test", "")...)
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
@@ -193,13 +210,13 @@
 	if len(name) == 0 {
 		t.Fatalf("failed to get name")
 	}
-
 	clt, err := shell.Start(core.EchoClientCommand, name, "a message")
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
 	cltSession := expect.NewSession(t, clt.Stdout(), time.Minute)
 	cltSession.Expect("test: a message")
+	srv.Shutdown(nil, nil)
 }
 
 func TestResolve(t *testing.T) {
@@ -207,14 +224,15 @@
 	defer fn()
 
 	mountPoints := []string{"a", "b"}
-	mountAddrs, err := startMountTables(t, shell, mountPoints...)
+	mountAddrs, fn, err := startMountTables(t, shell, mountPoints...)
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
+	defer fn()
 	rootName := mountAddrs["root"]
 	mtName := "b"
 	echoName := naming.Join(mtName, "echo")
-	srv, err := shell.Start(core.EchoServerCommand, "test", echoName)
+	srv, err := shell.Start(core.EchoServerCommand, testArgs("test", echoName)...)
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
@@ -279,6 +297,8 @@
 	if err := resolver.Shutdown(nil, os.Stderr); err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
+	srv.Shutdown(nil, nil)
+	nsroots.Shutdown(nil, nil)
 }
 
 func TestHelperProcess(t *testing.T) {
diff --git a/lib/modules/core/echo.go b/lib/modules/core/echo.go
index 9cac914..5fd3307 100644
--- a/lib/modules/core/echo.go
+++ b/lib/modules/core/echo.go
@@ -11,7 +11,6 @@
 	"veyron.io/veyron/veyron2/security"
 
 	"veyron.io/veyron/veyron/lib/modules"
-	"veyron.io/veyron/veyron/profiles"
 )
 
 func init() {
@@ -39,17 +38,22 @@
 }
 
 func echoServer(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
-	if len(args) != 3 {
-		return fmt.Errorf("wrong # args")
+	fl, err := ParseCommonFlags(args)
+	if err != nil {
+		return fmt.Errorf("failed parsing args: %s", err)
 	}
-	id, mp := args[1], args[2]
+	args = fl.Args()
+	if err := checkArgs(args, 2, "<message> <name>"); err != nil {
+		return err
+	}
+	id, mp := args[0], args[1]
 	disp := &treeDispatcher{id: id}
 	server, err := rt.R().NewServer()
 	if err != nil {
 		return err
 	}
 	defer server.Stop()
-	ep, err := server.Listen(profiles.LocalListenSpec)
+	ep, err := server.Listen(initListenSpec(fl))
 	if err != nil {
 		return err
 	}
@@ -64,11 +68,16 @@
 }
 
 func echoClient(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
-	if len(args) < 3 {
-		return fmt.Errorf("wrong # args")
+	fl, err := ParseCommonFlags(args)
+	if err != nil {
+		return fmt.Errorf("failed parsing args: %s", err)
 	}
-	name := args[1]
-	args = args[2:]
+	args = fl.Args()
+	if err := checkArgs(args, 2, "<name> <message>"); err != nil {
+		return err
+	}
+	name := args[0]
+	args = args[1:]
 	client := rt.R().Client()
 	for _, a := range args {
 		ctxt := rt.R().NewContext()
diff --git a/lib/modules/core/flags.go b/lib/modules/core/flags.go
new file mode 100644
index 0000000..9a8bc95
--- /dev/null
+++ b/lib/modules/core/flags.go
@@ -0,0 +1 @@
+package core
diff --git a/lib/modules/core/misc.go b/lib/modules/core/misc.go
index e70aa02..577f3b2 100644
--- a/lib/modules/core/misc.go
+++ b/lib/modules/core/misc.go
@@ -42,8 +42,8 @@
 }
 
 func mountServer(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
-	if len(args) < 4 {
-		return fmt.Errorf("wrong # args")
+	if err := checkArgs(args[1:], -3, "<mount point> <server> <ttl> [M][R]"); err != nil {
+		return err
 	}
 	var opts []naming.MountOpt
 	for _, arg := range args[4:] {
@@ -70,8 +70,8 @@
 }
 
 func namespaceCache(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
-	if len(args) != 2 {
-		return fmt.Errorf("wrong # args")
+	if err := checkArgs(args[1:], 1, "on|off"); err != nil {
+		return err
 	}
 	disable := true
 	switch args[1] {
diff --git a/lib/modules/core/mounttable.go b/lib/modules/core/mounttable.go
index 79d9844..307dde3 100644
--- a/lib/modules/core/mounttable.go
+++ b/lib/modules/core/mounttable.go
@@ -12,7 +12,6 @@
 	"veyron.io/veyron/veyron2/rt"
 
 	"veyron.io/veyron/veyron/lib/modules"
-	"veyron.io/veyron/veyron/profiles"
 	mounttable "veyron.io/veyron/veyron/services/mounttable/lib"
 )
 
@@ -26,34 +25,37 @@
 }
 
 func mountTable(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
-	if len(args) != 2 {
-		return fmt.Errorf("expected exactly one argument: <mount point>")
-	}
 	return runMT(false, stdin, stdout, stderr, env, args...)
 }
 
 func rootMountTable(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
-	if len(args) != 1 {
-		return fmt.Errorf("expected no arguments")
-	}
 	return runMT(true, stdin, stdout, stderr, env, args...)
 }
 
 func runMT(root bool, stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
-	r := rt.Init()
+	r := rt.R()
+	fl, err := ParseCommonFlags(args)
+	if err != nil {
+		return fmt.Errorf("failed parsing args: %s", err)
+	}
+	args = fl.Args()
+	lspec := initListenSpec(fl)
 	server, err := r.NewServer(options.ServesMountTable(true))
 	if err != nil {
 		return fmt.Errorf("root failed: %v", err)
 	}
 	mp := ""
 	if !root {
-		mp = args[1]
+		if err := checkArgs(args, 1, "<mount point>"); err != nil {
+			return err
+		}
+		mp = args[0]
 	}
 	mt, err := mounttable.NewMountTable("")
 	if err != nil {
 		return fmt.Errorf("mounttable.NewMountTable failed: %s", err)
 	}
-	ep, err := server.Listen(profiles.LocalListenSpec)
+	ep, err := server.Listen(lspec)
 	if err != nil {
 		return fmt.Errorf("server.Listen failed: %s", err)
 	}
@@ -110,8 +112,8 @@
 type resolver func(ctx context.T, name string) (names []string, err error)
 
 func resolve(fn resolver, stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
-	if len(args) != 2 {
-		return fmt.Errorf("wrong # args")
+	if err := checkArgs(args[1:], 1, "<name>"); err != nil {
+		return err
 	}
 	name := args[1]
 	servers, err := fn(rt.R().NewContext(), name)
@@ -136,8 +138,8 @@
 
 func setNamespaceRoots(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
 	ns := rt.R().Namespace()
-	if len(args) < 2 {
-		return fmt.Errorf("wrong # args")
+	if err := checkArgs(args, -1, "<name>..."); err != nil {
+		return err
 	}
 	return ns.SetRoots(args[1:]...)
 }
diff --git a/lib/modules/core/proxy.go b/lib/modules/core/proxy.go
new file mode 100644
index 0000000..0e24fe1
--- /dev/null
+++ b/lib/modules/core/proxy.go
@@ -0,0 +1,70 @@
+package core
+
+import (
+	"fmt"
+	"io"
+	"time"
+
+	"veyron.io/veyron/veyron2/naming"
+	"veyron.io/veyron/veyron2/rt"
+
+	"veyron.io/veyron/veyron/lib/modules"
+	"veyron.io/veyron/veyron/runtimes/google/ipc/stream/proxy"
+	"veyron.io/veyron/veyron/runtimes/google/lib/publisher"
+)
+
+func init() {
+	modules.RegisterChild(ProxyServerCommand, `<name>`, proxyServer)
+}
+
+func proxyServer(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
+	fl, err := ParseCommonFlags(args)
+	if err != nil {
+		return fmt.Errorf("failed parsing args: %s", err)
+	}
+	args = fl.Args()
+	if err := checkArgs(args, -1, ""); err != nil {
+		return err
+	}
+	expected := len(args)
+	rid, err := naming.NewRoutingID()
+	if err != nil {
+		return err
+	}
+
+	// TODO(ashankar): Set the second argument to r.Principal() once the
+	// old security model is no longer operational.
+	proxy, err := proxy.New(rid, nil, fl.ListenProtocolFlag.String(), fl.ListenAddressFlag.String(), "")
+	if err != nil {
+		return err
+	}
+	defer proxy.Shutdown()
+	pname := naming.JoinAddressName(proxy.Endpoint().String(), "//")
+	fmt.Fprintf(stdout, "PROXY_ADDR=%s\n", proxy.Endpoint().String())
+	fmt.Fprintf(stdout, "PROXY_NAME=%s\n", pname)
+	r := rt.R()
+	pub := publisher.New(r.NewContext(), r.Namespace(), time.Minute)
+	defer pub.WaitForStop()
+	defer pub.Stop()
+	pub.AddServer(pname, false)
+	for _, name := range args {
+		pub.AddName(name)
+	}
+	// Wait for all the entries to be published.
+	for {
+		got := len(pub.Published())
+		if expected == got {
+			break
+		}
+		fmt.Fprintf(stderr, "%s\n", pub.DebugString())
+		delay := time.Second
+		fmt.Fprintf(stderr, "Sleeping: %s\n", delay)
+		time.Sleep(delay)
+	}
+	for _, p := range pub.Published() {
+		fmt.Fprintf(stdout, "PUBLISHED_PROXY_NAME=%s\n", p)
+	}
+	fmt.Fprintf(stdout, "READY")
+	modules.WaitForEOF(stdin)
+	return nil
+}
diff --git a/lib/modules/core/util.go b/lib/modules/core/util.go
new file mode 100644
index 0000000..507b7e3
--- /dev/null
+++ b/lib/modules/core/util.go
@@ -0,0 +1,47 @@
+package core
+
+import (
+	"flag"
+	"fmt"
+
+	"veyron.io/veyron/veyron2/ipc"
+
+	"veyron.io/veyron/veyron/lib/flags"
+)
+
+// ParseCommonFlags parses the supplied args for the common set of flags
+// and environment variables defined in in the veyron/lib/flags package.
+func ParseCommonFlags(args []string) (*flags.Flags, error) {
+	fs := flag.NewFlagSet("modules/core", flag.ContinueOnError)
+	fl := flags.New(fs)
+	if len(args) == 0 {
+		return fl, fmt.Errorf("no args supplied")
+	}
+	err := fl.Parse(args[1:])
+	return fl, err
+}
+
+func initListenSpec(fl *flags.Flags) ipc.ListenSpec {
+	return ipc.ListenSpec{
+		Protocol: fl.ListenProtocolFlag.String(),
+		Address:  fl.ListenAddressFlag.String(),
+		Proxy:    fl.ListenProxyFlag,
+	}
+}
+
+// checkArgs checks for the expected number of args in args. A -ve
+// value means at least that number of args are expected.
+func checkArgs(args []string, expected int, usage string) error {
+	got := len(args)
+	if expected < 0 {
+		expected = -expected
+		if got < expected {
+			return fmt.Errorf("wrong # args (got %d, expected >=%d) expected: %q got: %v", got, expected, usage, args)
+		}
+	} else {
+		if got != expected {
+			return fmt.Errorf("wrong # args (got %d, expected %d) expected: %q got: %v", got, expected, usage, args)
+		}
+	}
+	return nil
+}
diff --git a/tools/naming/simulator/ambiguity.scr b/tools/naming/simulator/ambiguity.scr
index f20b97b..df47997 100644
--- a/tools/naming/simulator/ambiguity.scr
+++ b/tools/naming/simulator/ambiguity.scr
@@ -19,15 +19,17 @@
 # "s1/a", ["/s3/c"(mountpoint)]
 # "s1/a", ["/s4//"(mountpoint)]
 
-root
+set localaddr="--veyron.tcp.address=127.0.0.1:0"
+
+root -- $localaddr
 eval $_
 set s1=$MT_NAME
 
-root
+root  -- $localaddr
 eval $_
 set s2=$MT_NAME
 
-root
+root -- $localaddr
 eval $_
 set s3=$MT_NAME
 
@@ -37,7 +39,7 @@
 mount $s2/b $s3/c 1h
 wait $_
 
-echoServer "Echo" $s3/c
+echoServer  -- $localaddr "Echo" $s3/c
 set es_h=$_
 
 # Returns the root and three mounts at s1/a.
diff --git a/tools/naming/simulator/commands.go b/tools/naming/simulator/commands.go
index b11a3da..3efbd5b 100644
--- a/tools/naming/simulator/commands.go
+++ b/tools/naming/simulator/commands.go
@@ -13,24 +13,26 @@
 
 type builtinCmd func(sh *modules.Shell, state *cmdState, args ...string) (string, error)
 
-var varRE = regexp.MustCompile("(.*)=(.*)")
+var varRE = regexp.MustCompile("(.*?)=(.*)")
 
 var builtins = map[string]*struct {
-	nargs       int
+	nargs       int // -1 means a variable # of args.
 	usage       string
 	needsHandle bool
 	fn          builtinCmd
 }{
-	"print":  {-1, "print <args>...", false, print},
-	"help":   {-1, "help", false, nil},
-	"set":    {-1, "set <var>=<val>...", false, set},
-	"assert": {2, "val1 val2", false, assert},
-	"read":   {-1, "read <handle> [var]", true, read},
-	"eval":   {1, "eval <handle>", true, eval},
-	"wait":   {1, "wait <handle>", true, wait},
-	"stop":   {1, "stop <handle>", true, stop},
-	"list":   {0, "list", false, list},
-	"quit":   {0, "quit", false, quit},
+	"print":   {-1, "print <args>...", false, print},
+	"help":    {-1, "help", false, nil},
+	"set":     {-1, "set <var>=<val>...", false, set},
+	"splitEP": {-1, "splitEP", false, splitEP},
+	"assert":  {2, "val1 val2", false, assert},
+	"read":    {-1, "read <handle> [var]", true, read},
+	"eval":    {1, "eval <handle>", true, eval},
+	"wait":    {1, "wait <handle>", true, wait},
+	"stop":    {1, "stop <handle>", true, stop},
+	"stderr":  {1, "stderr <handle>", true, stderr},
+	"list":    {0, "list", false, list},
+	"quit":    {0, "quit", false, quit},
 }
 
 func init() {
@@ -42,6 +44,19 @@
 	return r, nil
 }
 
+func splitEP(sh *modules.Shell, _ *cmdState, args ...string) (string, error) {
+	ep := strings.TrimLeft(args[0], "/")
+	ep = strings.TrimRight(ep, "/")
+	ep = strings.TrimLeft(ep, "@")
+	ep = strings.TrimRight(ep, "@")
+	parts := strings.Split(ep, "@")
+	sh.SetVar("PN", fmt.Sprintf("%d", len(parts)))
+	for i, p := range parts {
+		sh.SetVar(fmt.Sprintf("P%d", i), p)
+	}
+	return "", nil
+}
+
 func help(sh *modules.Shell, _ *cmdState, args ...string) (string, error) {
 	r := ""
 	if len(args) == 0 {
@@ -103,6 +118,12 @@
 	return "", nil
 }
 
+func stderr(sh *modules.Shell, state *cmdState, args ...string) (string, error) {
+	state.Session.Finish(nil)
+	delete(handles, args[0])
+	return readStderr(state)
+}
+
 func readStderr(state *cmdState) (string, error) {
 	var b bytes.Buffer
 	if err := state.Handle.Shutdown(nil, &b); err != nil && err != io.EOF {
@@ -164,7 +185,7 @@
 	if err != nil {
 		return r, err
 	}
-	// Now read and return the contents of stderr as e
+	// Now read and return the contents of stderr as a string
 	if str, err := readStderr(state); err != nil && err != io.EOF {
 		return str, err
 	}
@@ -188,7 +209,7 @@
 			r += fmt.Sprintf("%s: ok\n", k)
 		}
 	}
-	fmt.Fprintf(os.Stdout, r)
+	fmt.Fprintf(os.Stdout, "%s\n", r)
 	os.Exit(0)
 	panic("unreachable")
 }
diff --git a/tools/naming/simulator/driver.go b/tools/naming/simulator/driver.go
index db4748e..31e6038 100644
--- a/tools/naming/simulator/driver.go
+++ b/tools/naming/simulator/driver.go
@@ -21,6 +21,7 @@
 	"veyron.io/veyron/veyron/lib/expect"
 	"veyron.io/veyron/veyron/lib/modules"
 	"veyron.io/veyron/veyron/lib/modules/core"
+	_ "veyron.io/veyron/veyron/profiles"
 )
 
 type cmdState struct {
@@ -101,7 +102,7 @@
 		// Subprocess, run the requested command.
 		if err := modules.Dispatch(); err != nil {
 			fmt.Fprintf(os.Stderr, "failed: %v\n", err)
-			return
+			os.Exit(1)
 		}
 		return
 	}
@@ -165,6 +166,9 @@
 		args = []string{}
 	}
 	sub, err := subVariables(sh, args)
+	if err != nil {
+		return err
+	}
 	if cmd := builtins[name]; cmd != nil {
 		if cmd.nargs >= 0 && len(sub) != cmd.nargs {
 			return fmt.Errorf("wrong (%d) # args for %q: usage %s", len(sub), name, cmd.usage)
@@ -177,7 +181,7 @@
 			l, err = cmd.fn(sh, nil, sub...)
 		}
 		if err != nil {
-			return err
+			return fmt.Errorf("%s : %s", err, l)
 		}
 		output(lineno, l)
 	} else {
diff --git a/tools/naming/simulator/echo.scr b/tools/naming/simulator/echo.scr
index 788d1b0..c957371 100644
--- a/tools/naming/simulator/echo.scr
+++ b/tools/naming/simulator/echo.scr
@@ -1,8 +1,10 @@
 # Simple example to show how names work both without and with a mount table
 # and the difference between resolve and resolveMT.
 
+set localaddr=--veyron.tcp.address=127.0.0.1:0
+
 # A 'stand-alone' server
-echoServer "text" ""
+echoServer -- $localaddr "text" ""
 set es=$_
 eval $es
 eval $es
@@ -19,17 +21,17 @@
 wait $ec
 
 # now use a nameserver.
-root
+root -- $localaddr
 eval $_
 set root=$MT_NAME
 
 set NAMESPACE_ROOT=$root
-echoServer "text2" "a/b"
+echoServer -- $localaddr "text2" "a/b"
 set es=$_
 eval $es
 set es_name=$NAME
-set es_addr=$ADDR
 read $es
+set es_addr=$ADDR
 
 echoClient "a/b" "test 2"
 set ec=$_
diff --git a/tools/naming/simulator/mt_complex.scr b/tools/naming/simulator/mt_complex.scr
index 6fb3532..a5c85e2 100644
--- a/tools/naming/simulator/mt_complex.scr
+++ b/tools/naming/simulator/mt_complex.scr
@@ -2,15 +2,17 @@
 #
 # TODO - list the examples and any issues.
 
+set localaddr="--veyron.tcp.address=127.0.0.1:0"
+
 cache off
 
-root
+root -- $localaddr
 set root_h=$_
 eval $root_h
 set root=$MT_NAME
 
 set NAMESPACE_ROOT=$root
-mt tl/a
+mt -- $localaddr tl/a
 set m=$_
 set mt_a_h=$m
 eval $m
@@ -18,7 +20,7 @@
 set mt_a_name=$MT_NAME
 set mt_a_addr=$MT_ADDR
 
-mt tl/b
+mt  -- $localaddr tl/b
 set m=$_
 set mt_b_h=$m
 eval $m
@@ -69,7 +71,7 @@
 #
 
 # run an echo server on tl.
-echoServer "E1" tl
+echoServer  -- $localaddr "E1" tl
 set es_E1=$_
 read $es_E1
 eval $es_E1
@@ -118,7 +120,7 @@
 assert $R0 $mt_a_name
 
 # run an echo server on tl/a
-echoServer "E2" tl/a
+echoServer  -- $localaddr "E2" tl/a
 set es_E2=$_
 read $es_E2
 eval $es_E2
@@ -198,7 +200,7 @@
 
 # Create a mount table with a 'long' name
 set long_name=tl/b/some/deep/name/that/is/a/mount/table
-mt $long_name
+mt -- $localaddr $long_name
 set m=$_
 eval $m
 eval $m
@@ -208,7 +210,7 @@
 
 # Create a second mount table with a 'long' name
 set second_long_name=tl/a/some/deep/name/that/is/a/mount/table
-mt $second_long_name
+mt -- $localaddr $second_long_name
 set m=$_
 eval $m
 eval $m
@@ -216,7 +218,7 @@
 set mt_l2_addr=$MT_ADDR
 
 # Run an echo server that uses that mount table
-echoServer "E3" $long_name/echo
+echoServer -- $localaddr "E3" $long_name/echo
 set es_E3=$_
 read $es_E3
 eval $es_E3
diff --git a/tools/naming/simulator/mt_simple.scr b/tools/naming/simulator/mt_simple.scr
index 1dfb805..db78ef1 100644
--- a/tools/naming/simulator/mt_simple.scr
+++ b/tools/naming/simulator/mt_simple.scr
@@ -1,14 +1,16 @@
 # Simple example showing multiple mount tables, servers and globing
 
-root
+set localaddr="--veyron.tcp.address=127.0.0.1:0"
+
+root -- $localaddr
 eval $_
 set root=$MT_NAME
 
 set NAMESPACE_ROOT=$root
-mt usa
+mt -- $localaddr usa
 eval $_
 set usa_mt=$MT_NAME
-mt uk
+mt -- $localaddr uk
 eval $_
 set uk_mt=$MT_NAME
 
@@ -19,12 +21,12 @@
 wait $l
 
 set NAMESPACE_ROOT=$usa_mt
-mt "palo alto"
+mt -- $localaddr "palo alto"
 eval $_
 set pa_mt=$MT_NAME
 
 set NAMESPACE_ROOT=$uk_mt
-mt "cambridge"
+mt -- $localaddr "cambridge"
 eval $_
 set cam_mt=$MT_NAME
 
@@ -32,6 +34,7 @@
 set l=$_
 eval $l
 assert $RN 7
+wait $l
 
 ls -l $root/...
 wait $_
@@ -69,4 +72,4 @@
 eval $r
 # this behaves differently to the usa/palo alto case?
 assert $R0 $cam_mt
-wait $r
\ No newline at end of file
+wait $r
diff --git a/tools/naming/simulator/proxy.scr b/tools/naming/simulator/proxy.scr
new file mode 100644
index 0000000..56bb960
--- /dev/null
+++ b/tools/naming/simulator/proxy.scr
@@ -0,0 +1,88 @@
+
+cache off
+
+set localaddr=--veyron.tcp.address=127.0.0.1:0
+
+root -- $localaddr
+eval $_
+set root=$MT_NAME
+set NAMESPACE_ROOT=$root
+setRoots $NAMESPACE_ROOT
+
+# run a non-proxied echo server
+echoServer -- $localaddr noproxy echo/noproxy
+set esnp=$_
+eval $esnp
+set NP_ECHOS_NAME=$NAME
+eval $esnp
+set NP_ECHOS_ADDR=$ADDR
+
+
+# run a proxy server
+proxyd -- $localaddr p1
+set proxy=$_
+# PROXY_ADDR=<address of proxy>
+eval $proxy
+# PROXY_NAME=<name of proxy>
+eval $proxy
+read $proxy
+splitEP $PROXY_ADDR
+assert $PN 6
+set PROXY_ADDRESS=$P2
+set PROXY_RID=$P3
+
+
+# TODO(cnicolaou): figure out why ls appears to run slowly when a proxy is
+# running, maybe a problem with the mount table.
+#ls ...
+#set l=$_
+#eval $l
+#assert $RN 3
+#wait $l
+
+echoServer -- $localaddr --veyron.proxy=p1 withproxy echo/withproxy
+set eswp=$_
+eval $eswp
+set ECHOS_NAME=$NAME
+eval $eswp
+set ECHOS_ADDR=$ADDR
+splitEP $ADDR
+set ECHOS_RID=$P3
+
+#ls ...
+#set l=$_
+#eval $l
+#assert $RN 4
+#wait $l
+
+print "root mt:" $NAMESPACE_ROOT
+print "no proxy: " $NP_ECHOS_ADDR
+print "with proxy: " $ECHOS_ADDR
+# The ipc.Server implementation publishes the proxy supplied address
+# in the mount table
+# TODO(cnicolaou): we also need a way of publishing the local address, right
+# only the proxy's address appears.
+resolve echo/withproxy
+set rs=$_
+eval $rs
+assert $RN 1
+eval $rs
+splitEP $R0
+assert $PN 6
+assert $P2 $PROXY_ADDRESS
+assert $P3 $ECHOS_RID
+
+ls -l echo/withproxy
+wait $_
+ls -l echo/noproxy
+wait $_
+
+echoClient echo/withproxy "ohh"
+set ec=$_
+read $ec l
+assert $l "withproxy: ohh"
+
+stop $eswp
+stop $esnp
+stop $proxy
+