    @Test
    public void setPublicUri() throws Throwable {

        setUp(false);
        ExampleServiceHost h = new ExampleServiceHost();

        try {

            // try invalid arguments
            ServiceHost.Arguments hostArgs = new ServiceHost.Arguments();
            hostArgs.publicUri = "";
            try {
                h.initialize(hostArgs);
                throw new IllegalStateException("should have failed");
            } catch (IllegalArgumentException e) {

            }

            hostArgs = new ServiceHost.Arguments();
            hostArgs.bindAddress = "";
            try {
                h.initialize(hostArgs);
                throw new IllegalStateException("should have failed");
            } catch (IllegalArgumentException e) {

            }

            hostArgs = new ServiceHost.Arguments();
            hostArgs.port = -2;
            try {
                h.initialize(hostArgs);
                throw new IllegalStateException("should have failed");
            } catch (IllegalArgumentException e) {

            }

            String bindAddress = "127.0.0.1";
            String publicAddress = "10.1.1.19";
            int publicPort = 1634;
            String hostId = UUID.randomUUID().toString();

            String[] args = {
                    "--sandbox=" + this.tmpFolder.getRoot().getAbsolutePath(),
                    "--port=0",
                    "--bindAddress=" + bindAddress,
                    "--publicUri=" + new URI("http://" + publicAddress + ":" + publicPort),
                    "--id=" + hostId
            };

            h.initialize(args);
            h.start();

            assertEquals(bindAddress, h.getPreferredAddress());

            assertEquals(h.getPort(), h.getUri().getPort());
            assertEquals(bindAddress, h.getUri().getHost());

            // confirm that public URI takes precedence over bind address
            assertEquals(publicAddress, h.getPublicUri().getHost());
            assertEquals(publicPort, h.getPublicUri().getPort());

            // confirm the node group self node entry uses the public URI for the bind address
            NodeGroupState ngs = this.host.getServiceState(null, NodeGroupState.class,
                    UriUtils.buildUri(h.getUri(), ServiceUriPaths.DEFAULT_NODE_GROUP));

            NodeState selfEntry = ngs.nodes.get(h.getId());
            assertEquals(publicAddress, selfEntry.groupReference.getHost());
            assertEquals(publicPort, selfEntry.groupReference.getPort());
        } finally {
            h.stop();
        }

    }