diff --git a/.gitignore b/.gitignore
index 9460c52..f926279 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,14 +2,12 @@
 /gen
 /lib/gen/dart-pkg
 /lib/gen/mojom
+/java/**/.gradle/
+/java/**/build/
+/java/local.properties
+/.packages
+/.pub
 /packages
 /example/packages
 /test/packages
-/.packages
-/.pub
 /pubspec.lock
-/build
-/java/.gradle
-/java/build/
-/java/local.properties
-*.srcjar
diff --git a/.jiriignore b/.jiriignore
index 6eef5c6..165ad4b 100644
--- a/.jiriignore
+++ b/.jiriignore
@@ -1,3 +1 @@
-go/src/mojom/vanadium/discovery/discovery.mojom.go
 lib/gen/dart-gen/mojom/lib/discovery/discovery.mojom.dart
-java/generated-src/io/v/mojo/discovery
diff --git a/Makefile b/Makefile
index 043c70c..7afd589 100644
--- a/Makefile
+++ b/Makefile
@@ -1,30 +1,27 @@
 include ../shared/mojo.mk
 
 ifdef ANDROID
-	DISCOVERY_BUILD_DIR := $(CURDIR)/gen/mojo/android
-
-	# For some reason we need to set the origin flag when running on Android,
-	# but setting it on Linux causes errors.
-	ORIGIN_FLAG = --origin $(MOJO_SERVICES)
+	BUILD_DIR := $(CURDIR)/gen/mojo/arm_android
+	TEST_BUILD_DIR := $(CURDIR)/gen/mojo_test/arm_android
 else
-	DISCOVERY_BUILD_DIR := $(CURDIR)/gen/mojo/linux_amd64
+	BUILD_DIR := $(CURDIR)/gen/mojo/amd64_linux
+	TEST_BUILD_DIR := $(CURDIR)/gen/mojo_test/amd64_linux
 endif
 
 # If this is not the first mojo shell, then you must reuse the dev servers
 # to avoid a "port in use" error.
-#ifneq ($(shell fuser 32000/tcp),)
-ifneq ($(shell netstat -ntl | fgrep 32000 | wc -l),0)
+ifneq ($(shell netstat -ntl | fgrep 31840 | wc -l),0)
 	REUSE_FLAG := --reuse-servers
 endif
 
 MOJO_SHELL_FLAGS := $(MOJO_SHELL_FLAGS) \
 	--config-alias DISCOVERY_DIR=$(CURDIR) \
-	--config-alias DISCOVERY_BUILD_DIR=$(DISCOVERY_BUILD_DIR) \
-	$(REUSE_FLAG) \
-	$(ORIGIN_FLAG)
+	--config-alias BUILD_DIR=$(BUILD_DIR) \
+	--config-alias TEST_BUILD_DIR=$(TEST_BUILD_DIR) \
+	--origin $(MOJO_SERVICES) \
+	$(REUSE_FLAG)
 
 V23_GO_FILES := $(shell find $(JIRI_ROOT) -name "*.go")
-PYTHONPATH := $(MOJO_SDK)/src/mojo/public/third_party:$(PYTHONPATH)
 
 all: build
 
@@ -35,58 +32,36 @@
 
 # Build mojo app.
 .PHONY: build
-build: packages gen-mojom $(DISCOVERY_BUILD_DIR)/discovery.mojo
+build: packages gen-mojom $(BUILD_DIR)/discovery.mojo
+
+MOJOM_FILE := mojom/v.io/discovery.mojom
+MOJOM_FILE_GO := gen/go/src/mojom/v.io/discovery/discovery.mojom.go
+MOJOM_FILE_JAVA := gen/mojom/v.io/discovery.mojom.srcjar
+MOJOM_FILE_DART := lib/gen/dart-gen/mojom/lib/discovery/discovery.mojom.dart
 
 .PHONY: gen-mojom
-gen-mojom: go/src/mojom/vanadium/discovery/discovery.mojom.go lib/gen/dart-gen/mojom/lib/mojo/discovery.mojom.dart java/generated-src/io/v/mojo/discovery/Advertiser.java
+gen-mojom: $(MOJOM_FILE_GO) $(MOJOM_FILE_JAVA) $(MOJOM_FILE_DART)
 
-go/src/mojom/vanadium/discovery/discovery.mojom.go: mojom/vanadium/discovery.mojom | mojo-env-check
-	$(call MOJOM_GEN,$<,.,.,go)
-	gofmt -w $@
+COMMA := ,
+$(MOJOM_FILE_GO) $(MOJOM_FILE_JAVA): $(MOJOM_FILE) | mojo-env-check
+	$(call MOJOM_GEN,$<,.,gen,go$(COMMA)java)
 
-lib/gen/dart-gen/mojom/lib/mojo/discovery.mojom.dart: mojom/vanadium/discovery.mojom | mojo-env-check
+$(MOJOM_FILE_DART): $(MOJOM_FILE) | mojo-env-check
 	$(call MOJOM_GEN,$<,.,lib/gen,dart)
 	# TODO(nlacasse): mojom_bindings_generator creates bad symlinks on dart
 	# files, so we delete them.  Stop doing this once the generator is fixed.
 	# See https://github.com/domokit/mojo/issues/386
 	rm -f lib/gen/mojom/$(notdir $@)
 
-# Note: These Java files are checked in.
-java/generated-src/io/v/mojo/discovery/Advertiser.java: java/generated-src/mojom/vanadium/discovery.mojom.srcjar
-	cd java/generated-src/ && jar -xf mojom/vanadium/discovery.mojom.srcjar
-
-# Clean up the old files and regenerate mojom files.
-# Due to https://github.com/domokit/mojo/issues/674, we must create the folder
-# that will hold the srcjar. This .srcjar is not checked in, however.
-java/generated-src/mojom/vanadium/discovery.mojom.srcjar: mojom/vanadium/discovery.mojom | mojo-env-check
-	rm -r java/generated-src/io/v/mojo/discovery
-	mkdir -p java/generated-src/mojom/vanadium
-	$(call MOJOM_GEN,$<,.,java/generated-src,java)
-
 ifdef ANDROID
+$(BUILD_DIR)/discovery.mojo: $(MOJOM_FILE_JAVA) gradle-build
+
+.PHONY: gradle-build
 gradle-build:
-	cd java && ./gradlew build
-
-java/build/outputs/apk/java-debug.apk: gradle-build
-
-build/classes.dex: java/build/outputs/apk/java-debug.apk | mojo-env-check
-	mkdir -p build
-	cd build && jar -xf ../$<
-
-$(DISCOVERY_BUILD_DIR)/discovery.mojo: build/classes.dex java/Manifest.txt | mojo-env-check
-	rm -fr build/zip-scratch build/discovery.zip
-	mkdir -p build/zip-scratch/META-INF
-	cp build/classes.dex build/zip-scratch
-	cp java/Manifest.txt build/zip-scratch/META-INF/MANIFEST.MF
-	cp -r build/lib/ build/zip-scratch/
-	cp build/lib/armeabi-v7a/libv23.so build/zip-scratch
-	cd build/zip-scratch && zip -r ../discovery.zip .
-	mkdir -p `dirname $@`
-	echo "#!mojo mojo:java_handler" > $@
-	cat build/discovery.zip >> $@
+	cd java && MOJO_SDK=$(MOJO_SDK) OUT_DIR=$(BUILD_DIR) ./gradlew buildMojo
 else
-$(DISCOVERY_BUILD_DIR)/discovery.mojo: $(V23_GO_FILES) $(MOJO_SHARED_LIB) | mojo-env-check
-	$(call MOGO_BUILD,vanadium/discovery,$@)
+$(BUILD_DIR)/discovery.mojo: $(MOJOM_FILE_GO) $(V23_GO_FILES) $(MOJO_SHARED_LIB) | mojo-env-check
+	$(call MOGO_BUILD,v.io/mojo/discovery,$@)
 endif
 
 # Tests
@@ -94,15 +69,15 @@
 test: unittest apptest
 
 .PHONY: unittest
-unittest: $(V23_GO_FILES) go/src/mojom/vanadium/discovery/discovery.mojom.go | mojo-env-check
-	$(call MOGO_TEST,-v vanadium/discovery/internal/...)
+unittest: $(MOJOM_FILE_GO) $(V23_GO_FILES) $(MOJO_SHARED_LIB) | mojo-env-check
+	$(call MOGO_TEST,-v v.io/mojo/discovery/...)
 
 .PHONY: apptest
-apptest: build mojoapptests | mojo-env-check
+apptest: build $(TEST_BUILD_DIR)/discovery_apptests.mojo mojoapptests | mojo-env-check
 	$(call MOJO_APPTEST,"mojoapptests")
 
-$(DISCOVERY_BUILD_DIR)/discovery_apptests.mojo: $(V23_GO_FILES) | mojo-env-check
-	$(call MOGO_BUILD,vanadium/discovery/internal/apptest/main,$@)
+$(TEST_BUILD_DIR)/discovery_apptests.mojo: $(MOJOM_FILE_GO) $(V23_GO_FILES) $(MOJO_SHARED_LIB) | mojo-env-check
+	$(call MOGO_BUILD,v.io/mojo/discovery/apptest/main,$@)
 
 # Publish
 .PHONY: publish
@@ -133,20 +108,21 @@
 
 # Cleanup
 clean:
-	rm -rf gen
+	rm -rf build
 	rm -rf lib/gen/dart-pkg
 	rm -rf lib/gen/mojom
 	rm -rf $(PACKAGE_MOJO_BIN_DIR)
+	cd java && ./gradlew clean
 
 # Examples
-run-advertiser: $(DISCOVERY_BUILD_DIR)/advertiser.mojo $(DISCOVERY_BUILD_DIR)/discovery.mojo
-	$(call MOJO_RUN,"https://mojo.v.io/advertiser.mojo")
+run-advertiser: $(TEST_BUILD_DIR)/advertiser.mojo $(BUILD_DIR)/discovery.mojo
+	$(call MOJO_RUN,"https://test.v.io/advertiser.mojo")
 
-run-scanner: $(DISCOVERY_BUILD_DIR)/scanner.mojo $(DISCOVERY_BUILD_DIR)/discovery.mojo
-	$(call MOJO_RUN,"https://mojo.v.io/scanner.mojo")
+run-scanner: $(TEST_BUILD_DIR)/scanner.mojo $(BUILD_DIR)/discovery.mojo
+	$(call MOJO_RUN,"https://test.v.io/scanner.mojo")
 
-$(DISCOVERY_BUILD_DIR)/advertiser.mojo: $(V23_GO_FILES) go/src/mojom/vanadium/discovery/discovery.mojom.go | mojo-env-check
+$(TEST_BUILD_DIR)/advertiser.mojo: $(MOJOM_FILE_GO) $(V23_GO_FILES) $(MOJO_SHARED_LIB) | mojo-env-check
 	$(call MOGO_BUILD,examples/advertiser,$@)
 
-$(DISCOVERY_BUILD_DIR)/scanner.mojo: $(V23_GO_FILES) go/src/mojom/vanadium/discovery/discovery.mojom.go | mojo-env-check
+$(TEST_BUILD_DIR)/scanner.mojo: $(MOJOM_FILE_GO) $(V23_GO_FILES) $(MOJO_SHARED_LIB) | mojo-env-check
 	$(call MOGO_BUILD,examples/scanner,$@)
diff --git a/go/src/examples/advertiser/advertiser.go b/go/src/examples/advertiser/advertiser.go
index d360991..6bd13e3 100644
--- a/go/src/examples/advertiser/advertiser.go
+++ b/go/src/examples/advertiser/advertiser.go
@@ -11,7 +11,7 @@
 	"mojo/public/go/bindings"
 	"mojo/public/go/system"
 
-	"mojom/vanadium/discovery"
+	"mojom/v.io/discovery"
 )
 
 //#include "mojo/public/c/system/types.h"
diff --git a/go/src/examples/scanner/scanner.go b/go/src/examples/scanner/scanner.go
index 15d6a7f..9b73dc2 100644
--- a/go/src/examples/scanner/scanner.go
+++ b/go/src/examples/scanner/scanner.go
@@ -11,7 +11,7 @@
 	"mojo/public/go/bindings"
 	"mojo/public/go/system"
 
-	"mojom/vanadium/discovery"
+	"mojom/v.io/discovery"
 )
 
 //#include "mojo/public/c/system/types.h"
diff --git a/go/src/mojom/vanadium/discovery/discovery.mojom.go b/go/src/mojom/vanadium/discovery/discovery.mojom.go
deleted file mode 100644
index 39cdb12..0000000
--- a/go/src/mojom/vanadium/discovery/discovery.mojom.go
+++ /dev/null
@@ -1,3006 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file is autogenerated by:
-//     mojo/public/tools/bindings/mojom_bindings_generator.py
-// For:
-//     mojom/vanadium/discovery.mojom
-//
-
-package discovery
-
-import (
-	fmt "fmt"
-	bindings "mojo/public/go/bindings"
-	system "mojo/public/go/system"
-	mojom_types "mojo/public/interfaces/bindings/mojom_types"
-	service_describer "mojo/public/interfaces/bindings/service_describer"
-	sort "sort"
-)
-
-type Discovery interface {
-	Advertise(inAd Advertisement, inVisibility *[]string) (outInstanceId *[16]uint8, outCloser *Closer_Pointer, outErr *Error, err error)
-	Scan(inQuery string, inHandler ScanHandler_Pointer) (outCloser *Closer_Pointer, outErr *Error, err error)
-}
-
-var discovery_Name = "v23::discovery::Discovery"
-
-type Discovery_Request bindings.InterfaceRequest
-
-func (r *Discovery_Request) Name() string {
-	return discovery_Name
-}
-
-type Discovery_Pointer bindings.InterfacePointer
-
-func (p *Discovery_Pointer) Name() string {
-	return discovery_Name
-}
-
-type Discovery_ServiceFactory struct {
-	Delegate Discovery_Factory
-}
-
-type Discovery_Factory interface {
-	Create(request Discovery_Request)
-}
-
-func (f *Discovery_ServiceFactory) Name() string {
-	return discovery_Name
-}
-
-// TODO(rudominer) This should only be defined for top-level interfaces.
-func (f *Discovery_ServiceFactory) ServiceDescription() service_describer.ServiceDescription {
-	return &Discovery_ServiceDescription{}
-}
-
-func (f *Discovery_ServiceFactory) Create(messagePipe system.MessagePipeHandle) {
-	request := Discovery_Request{bindings.NewMessagePipeHandleOwner(messagePipe)}
-	f.Delegate.Create(request)
-}
-
-// CreateMessagePipeForDiscovery creates a message pipe for use with the
-// Discovery interface with a Discovery_Request on one end and a Discovery_Pointer on the other.
-func CreateMessagePipeForDiscovery() (Discovery_Request, Discovery_Pointer) {
-	r, p := bindings.CreateMessagePipeForMojoInterface()
-	return Discovery_Request(r), Discovery_Pointer(p)
-}
-
-const discovery_Advertise_Name uint32 = 0
-const discovery_Scan_Name uint32 = 1
-
-type Discovery_Proxy struct {
-	router *bindings.Router
-	ids    bindings.Counter
-}
-
-func NewDiscoveryProxy(p Discovery_Pointer, waiter bindings.AsyncWaiter) *Discovery_Proxy {
-	return &Discovery_Proxy{
-		bindings.NewRouter(p.PassMessagePipe(), waiter),
-		bindings.NewCounter(),
-	}
-}
-
-func (p *Discovery_Proxy) Close_Proxy() {
-	p.router.Close()
-}
-
-type discovery_Advertise_Params struct {
-	inAd         Advertisement
-	inVisibility *[]string
-}
-
-func (s *discovery_Advertise_Params) Encode(encoder *bindings.Encoder) error {
-	encoder.StartStruct(16, 0)
-	if err := encoder.WritePointer(); err != nil {
-		return err
-	}
-	if err := s.inAd.Encode(encoder); err != nil {
-		return err
-	}
-	if s.inVisibility == nil {
-		encoder.WriteNullPointer()
-	} else {
-		if err := encoder.WritePointer(); err != nil {
-			return err
-		}
-		encoder.StartArray(uint32(len((*s.inVisibility))), 64)
-		for _, elem0 := range *s.inVisibility {
-			if err := encoder.WritePointer(); err != nil {
-				return err
-			}
-			if err := encoder.WriteString(elem0); err != nil {
-				return err
-			}
-		}
-		if err := encoder.Finish(); err != nil {
-			return err
-		}
-	}
-	if err := encoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-var discovery_Advertise_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
-	bindings.DataHeader{24, 0},
-}
-
-func (s *discovery_Advertise_Params) Decode(decoder *bindings.Decoder) error {
-	header, err := decoder.StartStruct()
-	if err != nil {
-		return err
-	}
-	index := sort.Search(len(discovery_Advertise_Params_Versions), func(i int) bool {
-		return discovery_Advertise_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
-	})
-	if index < len(discovery_Advertise_Params_Versions) {
-		if discovery_Advertise_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
-			index--
-		}
-		expectedSize := discovery_Advertise_Params_Versions[index].Size
-		if expectedSize != header.Size {
-			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
-				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
-			}
-		}
-	}
-	if header.ElementsOrVersion >= 0 {
-		pointer0, err := decoder.ReadPointer()
-		if err != nil {
-			return err
-		}
-		if pointer0 == 0 {
-			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
-		} else {
-			if err := s.inAd.Decode(decoder); err != nil {
-				return err
-			}
-		}
-	}
-	if header.ElementsOrVersion >= 0 {
-		pointer0, err := decoder.ReadPointer()
-		if err != nil {
-			return err
-		}
-		if pointer0 == 0 {
-			s.inVisibility = nil
-		} else {
-			s.inVisibility = new([]string)
-			len0, err := decoder.StartArray(64)
-			if err != nil {
-				return err
-			}
-			(*s.inVisibility) = make([]string, len0)
-			for i0 := uint32(0); i0 < len0; i0++ {
-				pointer1, err := decoder.ReadPointer()
-				if err != nil {
-					return err
-				}
-				if pointer1 == 0 {
-					return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
-				} else {
-					value1, err := decoder.ReadString()
-					if err != nil {
-						return err
-					}
-					(*s.inVisibility)[i0] = value1
-				}
-			}
-			if err := decoder.Finish(); err != nil {
-				return err
-			}
-		}
-	}
-	if err := decoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-type discovery_Advertise_ResponseParams struct {
-	outInstanceId *[16]uint8
-	outCloser     *Closer_Pointer
-	outErr        *Error
-}
-
-func (s *discovery_Advertise_ResponseParams) Encode(encoder *bindings.Encoder) error {
-	encoder.StartStruct(24, 0)
-	if s.outInstanceId == nil {
-		encoder.WriteNullPointer()
-	} else {
-		if err := encoder.WritePointer(); err != nil {
-			return err
-		}
-		encoder.StartArray(uint32(len((*s.outInstanceId))), 8)
-		for _, elem0 := range *s.outInstanceId {
-			if err := encoder.WriteUint8(elem0); err != nil {
-				return err
-			}
-		}
-		if err := encoder.Finish(); err != nil {
-			return err
-		}
-	}
-	if s.outCloser == nil {
-		encoder.WriteInvalidInterface()
-	} else {
-		if err := encoder.WriteInterface((*s.outCloser).PassMessagePipe()); err != nil {
-			return err
-		}
-	}
-	if s.outErr == nil {
-		encoder.WriteNullPointer()
-	} else {
-		if err := encoder.WritePointer(); err != nil {
-			return err
-		}
-		if err := (*s.outErr).Encode(encoder); err != nil {
-			return err
-		}
-	}
-	if err := encoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-var discovery_Advertise_ResponseParams_Versions []bindings.DataHeader = []bindings.DataHeader{
-	bindings.DataHeader{32, 0},
-}
-
-func (s *discovery_Advertise_ResponseParams) Decode(decoder *bindings.Decoder) error {
-	header, err := decoder.StartStruct()
-	if err != nil {
-		return err
-	}
-	index := sort.Search(len(discovery_Advertise_ResponseParams_Versions), func(i int) bool {
-		return discovery_Advertise_ResponseParams_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
-	})
-	if index < len(discovery_Advertise_ResponseParams_Versions) {
-		if discovery_Advertise_ResponseParams_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
-			index--
-		}
-		expectedSize := discovery_Advertise_ResponseParams_Versions[index].Size
-		if expectedSize != header.Size {
-			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
-				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
-			}
-		}
-	}
-	if header.ElementsOrVersion >= 0 {
-		pointer0, err := decoder.ReadPointer()
-		if err != nil {
-			return err
-		}
-		if pointer0 == 0 {
-			s.outInstanceId = nil
-		} else {
-			s.outInstanceId = new([16]uint8)
-			len0, err := decoder.StartArray(8)
-			if err != nil {
-				return err
-			}
-			if len0 != 16 {
-				return &bindings.ValidationError{bindings.UnexpectedArrayHeader,
-					fmt.Sprintf("invalid array length: expected %d, got %d", 16, len0),
-				}
-			}
-			for i0 := uint32(0); i0 < len0; i0++ {
-				value1, err := decoder.ReadUint8()
-				if err != nil {
-					return err
-				}
-				(*s.outInstanceId)[i0] = value1
-			}
-			if err := decoder.Finish(); err != nil {
-				return err
-			}
-		}
-	}
-	if header.ElementsOrVersion >= 0 {
-		handle0, err := decoder.ReadInterface()
-		if err != nil {
-			return err
-		}
-		if handle0.IsValid() {
-			handleOwner := bindings.NewMessagePipeHandleOwner(handle0)
-			s.outCloser = &Closer_Pointer{handleOwner}
-		} else {
-			s.outCloser = nil
-		}
-	}
-	if header.ElementsOrVersion >= 0 {
-		pointer0, err := decoder.ReadPointer()
-		if err != nil {
-			return err
-		}
-		if pointer0 == 0 {
-			s.outErr = nil
-		} else {
-			s.outErr = new(Error)
-			if err := (*s.outErr).Decode(decoder); err != nil {
-				return err
-			}
-		}
-	}
-	if err := decoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (p *Discovery_Proxy) Advertise(inAd Advertisement, inVisibility *[]string) (outInstanceId *[16]uint8, outCloser *Closer_Pointer, outErr *Error, err error) {
-	payload := &discovery_Advertise_Params{
-		inAd,
-		inVisibility,
-	}
-	header := bindings.MessageHeader{
-		Type:      discovery_Advertise_Name,
-		Flags:     bindings.MessageExpectsResponseFlag,
-		RequestId: p.ids.Count(),
-	}
-	var message *bindings.Message
-	if message, err = bindings.EncodeMessage(header, payload); err != nil {
-		err = fmt.Errorf("can't encode request: %v", err.Error())
-		p.Close_Proxy()
-		return
-	}
-	readResult := <-p.router.AcceptWithResponse(message)
-	if err = readResult.Error; err != nil {
-		p.Close_Proxy()
-		return
-	}
-	if readResult.Message.Header.Flags != bindings.MessageIsResponseFlag {
-		err = &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
-			fmt.Sprintf("invalid message header flag: %v", readResult.Message.Header.Flags),
-		}
-		return
-	}
-	if got, want := readResult.Message.Header.Type, discovery_Advertise_Name; got != want {
-		err = &bindings.ValidationError{bindings.MessageHeaderUnknownMethod,
-			fmt.Sprintf("invalid method in response: expected %v, got %v", want, got),
-		}
-		return
-	}
-	var response discovery_Advertise_ResponseParams
-	if err = readResult.Message.DecodePayload(&response); err != nil {
-		p.Close_Proxy()
-		return
-	}
-	outInstanceId = response.outInstanceId
-	outCloser = response.outCloser
-	outErr = response.outErr
-	return
-}
-
-type discovery_Scan_Params struct {
-	inQuery   string
-	inHandler ScanHandler_Pointer
-}
-
-func (s *discovery_Scan_Params) Encode(encoder *bindings.Encoder) error {
-	encoder.StartStruct(16, 0)
-	if err := encoder.WritePointer(); err != nil {
-		return err
-	}
-	if err := encoder.WriteString(s.inQuery); err != nil {
-		return err
-	}
-	if err := encoder.WriteInterface(s.inHandler.PassMessagePipe()); err != nil {
-		return err
-	}
-	if err := encoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-var discovery_Scan_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
-	bindings.DataHeader{24, 0},
-}
-
-func (s *discovery_Scan_Params) Decode(decoder *bindings.Decoder) error {
-	header, err := decoder.StartStruct()
-	if err != nil {
-		return err
-	}
-	index := sort.Search(len(discovery_Scan_Params_Versions), func(i int) bool {
-		return discovery_Scan_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
-	})
-	if index < len(discovery_Scan_Params_Versions) {
-		if discovery_Scan_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
-			index--
-		}
-		expectedSize := discovery_Scan_Params_Versions[index].Size
-		if expectedSize != header.Size {
-			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
-				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
-			}
-		}
-	}
-	if header.ElementsOrVersion >= 0 {
-		pointer0, err := decoder.ReadPointer()
-		if err != nil {
-			return err
-		}
-		if pointer0 == 0 {
-			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
-		} else {
-			value0, err := decoder.ReadString()
-			if err != nil {
-				return err
-			}
-			s.inQuery = value0
-		}
-	}
-	if header.ElementsOrVersion >= 0 {
-		handle0, err := decoder.ReadInterface()
-		if err != nil {
-			return err
-		}
-		if handle0.IsValid() {
-			handleOwner := bindings.NewMessagePipeHandleOwner(handle0)
-			s.inHandler = ScanHandler_Pointer{handleOwner}
-		} else {
-			return &bindings.ValidationError{bindings.UnexpectedInvalidHandle, "unexpected invalid handle"}
-		}
-	}
-	if err := decoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-type discovery_Scan_ResponseParams struct {
-	outCloser *Closer_Pointer
-	outErr    *Error
-}
-
-func (s *discovery_Scan_ResponseParams) Encode(encoder *bindings.Encoder) error {
-	encoder.StartStruct(16, 0)
-	if s.outCloser == nil {
-		encoder.WriteInvalidInterface()
-	} else {
-		if err := encoder.WriteInterface((*s.outCloser).PassMessagePipe()); err != nil {
-			return err
-		}
-	}
-	if s.outErr == nil {
-		encoder.WriteNullPointer()
-	} else {
-		if err := encoder.WritePointer(); err != nil {
-			return err
-		}
-		if err := (*s.outErr).Encode(encoder); err != nil {
-			return err
-		}
-	}
-	if err := encoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-var discovery_Scan_ResponseParams_Versions []bindings.DataHeader = []bindings.DataHeader{
-	bindings.DataHeader{24, 0},
-}
-
-func (s *discovery_Scan_ResponseParams) Decode(decoder *bindings.Decoder) error {
-	header, err := decoder.StartStruct()
-	if err != nil {
-		return err
-	}
-	index := sort.Search(len(discovery_Scan_ResponseParams_Versions), func(i int) bool {
-		return discovery_Scan_ResponseParams_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
-	})
-	if index < len(discovery_Scan_ResponseParams_Versions) {
-		if discovery_Scan_ResponseParams_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
-			index--
-		}
-		expectedSize := discovery_Scan_ResponseParams_Versions[index].Size
-		if expectedSize != header.Size {
-			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
-				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
-			}
-		}
-	}
-	if header.ElementsOrVersion >= 0 {
-		handle0, err := decoder.ReadInterface()
-		if err != nil {
-			return err
-		}
-		if handle0.IsValid() {
-			handleOwner := bindings.NewMessagePipeHandleOwner(handle0)
-			s.outCloser = &Closer_Pointer{handleOwner}
-		} else {
-			s.outCloser = nil
-		}
-	}
-	if header.ElementsOrVersion >= 0 {
-		pointer0, err := decoder.ReadPointer()
-		if err != nil {
-			return err
-		}
-		if pointer0 == 0 {
-			s.outErr = nil
-		} else {
-			s.outErr = new(Error)
-			if err := (*s.outErr).Decode(decoder); err != nil {
-				return err
-			}
-		}
-	}
-	if err := decoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (p *Discovery_Proxy) Scan(inQuery string, inHandler ScanHandler_Pointer) (outCloser *Closer_Pointer, outErr *Error, err error) {
-	payload := &discovery_Scan_Params{
-		inQuery,
-		inHandler,
-	}
-	header := bindings.MessageHeader{
-		Type:      discovery_Scan_Name,
-		Flags:     bindings.MessageExpectsResponseFlag,
-		RequestId: p.ids.Count(),
-	}
-	var message *bindings.Message
-	if message, err = bindings.EncodeMessage(header, payload); err != nil {
-		err = fmt.Errorf("can't encode request: %v", err.Error())
-		p.Close_Proxy()
-		return
-	}
-	readResult := <-p.router.AcceptWithResponse(message)
-	if err = readResult.Error; err != nil {
-		p.Close_Proxy()
-		return
-	}
-	if readResult.Message.Header.Flags != bindings.MessageIsResponseFlag {
-		err = &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
-			fmt.Sprintf("invalid message header flag: %v", readResult.Message.Header.Flags),
-		}
-		return
-	}
-	if got, want := readResult.Message.Header.Type, discovery_Scan_Name; got != want {
-		err = &bindings.ValidationError{bindings.MessageHeaderUnknownMethod,
-			fmt.Sprintf("invalid method in response: expected %v, got %v", want, got),
-		}
-		return
-	}
-	var response discovery_Scan_ResponseParams
-	if err = readResult.Message.DecodePayload(&response); err != nil {
-		p.Close_Proxy()
-		return
-	}
-	outCloser = response.outCloser
-	outErr = response.outErr
-	return
-}
-
-type discovery_Stub struct {
-	connector *bindings.Connector
-	impl      Discovery
-}
-
-func NewDiscoveryStub(r Discovery_Request, impl Discovery, waiter bindings.AsyncWaiter) *bindings.Stub {
-	connector := bindings.NewConnector(r.PassMessagePipe(), waiter)
-	return bindings.NewStub(connector, &discovery_Stub{connector, impl})
-}
-
-func (f *Discovery_Request) ServiceDescription() service_describer.ServiceDescription {
-	return &Discovery_ServiceDescription{}
-}
-
-type Discovery_ServiceDescription struct{}
-
-func (sd *Discovery_ServiceDescription) GetTopLevelInterface() (outMojomInterface mojom_types.MojomInterface, err error) {
-	err = fmt.Errorf("GetTopLevelInterface not implemented")
-	return
-}
-
-func (sd *Discovery_ServiceDescription) GetTypeDefinition(inTypeKey string) (outType mojom_types.UserDefinedType, err error) {
-	err = fmt.Errorf("GetTypeDefinition not implemented")
-	return
-}
-
-func (sd *Discovery_ServiceDescription) GetAllTypeDefinitions() (outDefinitions *map[string]mojom_types.UserDefinedType, err error) {
-	err = fmt.Errorf("GetAllTypeDefinitions not implemented")
-	return
-}
-
-var _ service_describer.ServiceDescription = (*Discovery_ServiceDescription)(nil)
-
-func (s *discovery_Stub) Accept(message *bindings.Message) (err error) {
-	switch message.Header.Type {
-	case discovery_Advertise_Name:
-		if message.Header.Flags != bindings.MessageExpectsResponseFlag {
-			return &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
-				fmt.Sprintf("invalid message header flag: %v", message.Header.Flags),
-			}
-		}
-		var request discovery_Advertise_Params
-		if err := message.DecodePayload(&request); err != nil {
-			return err
-		}
-		var response discovery_Advertise_ResponseParams
-		response.outInstanceId, response.outCloser, response.outErr, err = s.impl.Advertise(request.inAd, request.inVisibility)
-		if err != nil {
-			return
-		}
-		header := bindings.MessageHeader{
-			Type:      discovery_Advertise_Name,
-			Flags:     bindings.MessageIsResponseFlag,
-			RequestId: message.Header.RequestId,
-		}
-		message, err = bindings.EncodeMessage(header, &response)
-		if err != nil {
-			return err
-		}
-		return s.connector.WriteMessage(message)
-	case discovery_Scan_Name:
-		if message.Header.Flags != bindings.MessageExpectsResponseFlag {
-			return &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
-				fmt.Sprintf("invalid message header flag: %v", message.Header.Flags),
-			}
-		}
-		var request discovery_Scan_Params
-		if err := message.DecodePayload(&request); err != nil {
-			return err
-		}
-		var response discovery_Scan_ResponseParams
-		response.outCloser, response.outErr, err = s.impl.Scan(request.inQuery, request.inHandler)
-		if err != nil {
-			return
-		}
-		header := bindings.MessageHeader{
-			Type:      discovery_Scan_Name,
-			Flags:     bindings.MessageIsResponseFlag,
-			RequestId: message.Header.RequestId,
-		}
-		message, err = bindings.EncodeMessage(header, &response)
-		if err != nil {
-			return err
-		}
-		return s.connector.WriteMessage(message)
-	default:
-		return &bindings.ValidationError{
-			bindings.MessageHeaderUnknownMethod,
-			fmt.Sprintf("unknown method %v", message.Header.Type),
-		}
-	}
-	return
-}
-
-type Closer interface {
-	Close() (err error)
-}
-
-type Closer_Request bindings.InterfaceRequest
-
-type Closer_Pointer bindings.InterfacePointer
-
-type Closer_ServiceFactory struct {
-	Delegate Closer_Factory
-}
-
-type Closer_Factory interface {
-	Create(request Closer_Request)
-}
-
-// TODO(rudominer) This should only be defined for top-level interfaces.
-func (f *Closer_ServiceFactory) ServiceDescription() service_describer.ServiceDescription {
-	return &Closer_ServiceDescription{}
-}
-
-func (f *Closer_ServiceFactory) Create(messagePipe system.MessagePipeHandle) {
-	request := Closer_Request{bindings.NewMessagePipeHandleOwner(messagePipe)}
-	f.Delegate.Create(request)
-}
-
-// CreateMessagePipeForCloser creates a message pipe for use with the
-// Closer interface with a Closer_Request on one end and a Closer_Pointer on the other.
-func CreateMessagePipeForCloser() (Closer_Request, Closer_Pointer) {
-	r, p := bindings.CreateMessagePipeForMojoInterface()
-	return Closer_Request(r), Closer_Pointer(p)
-}
-
-const closer_Close_Name uint32 = 0
-
-type Closer_Proxy struct {
-	router *bindings.Router
-	ids    bindings.Counter
-}
-
-func NewCloserProxy(p Closer_Pointer, waiter bindings.AsyncWaiter) *Closer_Proxy {
-	return &Closer_Proxy{
-		bindings.NewRouter(p.PassMessagePipe(), waiter),
-		bindings.NewCounter(),
-	}
-}
-
-func (p *Closer_Proxy) Close_Proxy() {
-	p.router.Close()
-}
-
-type closer_Close_Params struct {
-}
-
-func (s *closer_Close_Params) Encode(encoder *bindings.Encoder) error {
-	encoder.StartStruct(0, 0)
-	if err := encoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-var closer_Close_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
-	bindings.DataHeader{8, 0},
-}
-
-func (s *closer_Close_Params) Decode(decoder *bindings.Decoder) error {
-	header, err := decoder.StartStruct()
-	if err != nil {
-		return err
-	}
-	index := sort.Search(len(closer_Close_Params_Versions), func(i int) bool {
-		return closer_Close_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
-	})
-	if index < len(closer_Close_Params_Versions) {
-		if closer_Close_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
-			index--
-		}
-		expectedSize := closer_Close_Params_Versions[index].Size
-		if expectedSize != header.Size {
-			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
-				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
-			}
-		}
-	}
-	if err := decoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-type closer_Close_ResponseParams struct {
-}
-
-func (s *closer_Close_ResponseParams) Encode(encoder *bindings.Encoder) error {
-	encoder.StartStruct(0, 0)
-	if err := encoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-var closer_Close_ResponseParams_Versions []bindings.DataHeader = []bindings.DataHeader{
-	bindings.DataHeader{8, 0},
-}
-
-func (s *closer_Close_ResponseParams) Decode(decoder *bindings.Decoder) error {
-	header, err := decoder.StartStruct()
-	if err != nil {
-		return err
-	}
-	index := sort.Search(len(closer_Close_ResponseParams_Versions), func(i int) bool {
-		return closer_Close_ResponseParams_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
-	})
-	if index < len(closer_Close_ResponseParams_Versions) {
-		if closer_Close_ResponseParams_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
-			index--
-		}
-		expectedSize := closer_Close_ResponseParams_Versions[index].Size
-		if expectedSize != header.Size {
-			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
-				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
-			}
-		}
-	}
-	if err := decoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (p *Closer_Proxy) Close() (err error) {
-	payload := &closer_Close_Params{}
-	header := bindings.MessageHeader{
-		Type:      closer_Close_Name,
-		Flags:     bindings.MessageExpectsResponseFlag,
-		RequestId: p.ids.Count(),
-	}
-	var message *bindings.Message
-	if message, err = bindings.EncodeMessage(header, payload); err != nil {
-		err = fmt.Errorf("can't encode request: %v", err.Error())
-		p.Close_Proxy()
-		return
-	}
-	readResult := <-p.router.AcceptWithResponse(message)
-	if err = readResult.Error; err != nil {
-		p.Close_Proxy()
-		return
-	}
-	if readResult.Message.Header.Flags != bindings.MessageIsResponseFlag {
-		err = &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
-			fmt.Sprintf("invalid message header flag: %v", readResult.Message.Header.Flags),
-		}
-		return
-	}
-	if got, want := readResult.Message.Header.Type, closer_Close_Name; got != want {
-		err = &bindings.ValidationError{bindings.MessageHeaderUnknownMethod,
-			fmt.Sprintf("invalid method in response: expected %v, got %v", want, got),
-		}
-		return
-	}
-	var response closer_Close_ResponseParams
-	if err = readResult.Message.DecodePayload(&response); err != nil {
-		p.Close_Proxy()
-		return
-	}
-	return
-}
-
-type closer_Stub struct {
-	connector *bindings.Connector
-	impl      Closer
-}
-
-func NewCloserStub(r Closer_Request, impl Closer, waiter bindings.AsyncWaiter) *bindings.Stub {
-	connector := bindings.NewConnector(r.PassMessagePipe(), waiter)
-	return bindings.NewStub(connector, &closer_Stub{connector, impl})
-}
-
-func (f *Closer_Request) ServiceDescription() service_describer.ServiceDescription {
-	return &Closer_ServiceDescription{}
-}
-
-type Closer_ServiceDescription struct{}
-
-func (sd *Closer_ServiceDescription) GetTopLevelInterface() (outMojomInterface mojom_types.MojomInterface, err error) {
-	err = fmt.Errorf("GetTopLevelInterface not implemented")
-	return
-}
-
-func (sd *Closer_ServiceDescription) GetTypeDefinition(inTypeKey string) (outType mojom_types.UserDefinedType, err error) {
-	err = fmt.Errorf("GetTypeDefinition not implemented")
-	return
-}
-
-func (sd *Closer_ServiceDescription) GetAllTypeDefinitions() (outDefinitions *map[string]mojom_types.UserDefinedType, err error) {
-	err = fmt.Errorf("GetAllTypeDefinitions not implemented")
-	return
-}
-
-var _ service_describer.ServiceDescription = (*Closer_ServiceDescription)(nil)
-
-func (s *closer_Stub) Accept(message *bindings.Message) (err error) {
-	switch message.Header.Type {
-	case closer_Close_Name:
-		if message.Header.Flags != bindings.MessageExpectsResponseFlag {
-			return &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
-				fmt.Sprintf("invalid message header flag: %v", message.Header.Flags),
-			}
-		}
-		var request closer_Close_Params
-		if err := message.DecodePayload(&request); err != nil {
-			return err
-		}
-		var response closer_Close_ResponseParams
-		err = s.impl.Close()
-		if err != nil {
-			return
-		}
-		header := bindings.MessageHeader{
-			Type:      closer_Close_Name,
-			Flags:     bindings.MessageIsResponseFlag,
-			RequestId: message.Header.RequestId,
-		}
-		message, err = bindings.EncodeMessage(header, &response)
-		if err != nil {
-			return err
-		}
-		return s.connector.WriteMessage(message)
-	default:
-		return &bindings.ValidationError{
-			bindings.MessageHeaderUnknownMethod,
-			fmt.Sprintf("unknown method %v", message.Header.Type),
-		}
-	}
-	return
-}
-
-type ScanHandler interface {
-	OnUpdate(inUpdate Update_Pointer) (err error)
-}
-
-type ScanHandler_Request bindings.InterfaceRequest
-
-type ScanHandler_Pointer bindings.InterfacePointer
-
-type ScanHandler_ServiceFactory struct {
-	Delegate ScanHandler_Factory
-}
-
-type ScanHandler_Factory interface {
-	Create(request ScanHandler_Request)
-}
-
-// TODO(rudominer) This should only be defined for top-level interfaces.
-func (f *ScanHandler_ServiceFactory) ServiceDescription() service_describer.ServiceDescription {
-	return &ScanHandler_ServiceDescription{}
-}
-
-func (f *ScanHandler_ServiceFactory) Create(messagePipe system.MessagePipeHandle) {
-	request := ScanHandler_Request{bindings.NewMessagePipeHandleOwner(messagePipe)}
-	f.Delegate.Create(request)
-}
-
-// CreateMessagePipeForScanHandler creates a message pipe for use with the
-// ScanHandler interface with a ScanHandler_Request on one end and a ScanHandler_Pointer on the other.
-func CreateMessagePipeForScanHandler() (ScanHandler_Request, ScanHandler_Pointer) {
-	r, p := bindings.CreateMessagePipeForMojoInterface()
-	return ScanHandler_Request(r), ScanHandler_Pointer(p)
-}
-
-const scanHandler_OnUpdate_Name uint32 = 0
-
-type ScanHandler_Proxy struct {
-	router *bindings.Router
-	ids    bindings.Counter
-}
-
-func NewScanHandlerProxy(p ScanHandler_Pointer, waiter bindings.AsyncWaiter) *ScanHandler_Proxy {
-	return &ScanHandler_Proxy{
-		bindings.NewRouter(p.PassMessagePipe(), waiter),
-		bindings.NewCounter(),
-	}
-}
-
-func (p *ScanHandler_Proxy) Close_Proxy() {
-	p.router.Close()
-}
-
-type scanHandler_OnUpdate_Params struct {
-	inUpdate Update_Pointer
-}
-
-func (s *scanHandler_OnUpdate_Params) Encode(encoder *bindings.Encoder) error {
-	encoder.StartStruct(8, 0)
-	if err := encoder.WriteInterface(s.inUpdate.PassMessagePipe()); err != nil {
-		return err
-	}
-	if err := encoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-var scanHandler_OnUpdate_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
-	bindings.DataHeader{16, 0},
-}
-
-func (s *scanHandler_OnUpdate_Params) Decode(decoder *bindings.Decoder) error {
-	header, err := decoder.StartStruct()
-	if err != nil {
-		return err
-	}
-	index := sort.Search(len(scanHandler_OnUpdate_Params_Versions), func(i int) bool {
-		return scanHandler_OnUpdate_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
-	})
-	if index < len(scanHandler_OnUpdate_Params_Versions) {
-		if scanHandler_OnUpdate_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
-			index--
-		}
-		expectedSize := scanHandler_OnUpdate_Params_Versions[index].Size
-		if expectedSize != header.Size {
-			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
-				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
-			}
-		}
-	}
-	if header.ElementsOrVersion >= 0 {
-		handle0, err := decoder.ReadInterface()
-		if err != nil {
-			return err
-		}
-		if handle0.IsValid() {
-			handleOwner := bindings.NewMessagePipeHandleOwner(handle0)
-			s.inUpdate = Update_Pointer{handleOwner}
-		} else {
-			return &bindings.ValidationError{bindings.UnexpectedInvalidHandle, "unexpected invalid handle"}
-		}
-	}
-	if err := decoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (p *ScanHandler_Proxy) OnUpdate(inUpdate Update_Pointer) (err error) {
-	payload := &scanHandler_OnUpdate_Params{
-		inUpdate,
-	}
-	header := bindings.MessageHeader{
-		Type:  scanHandler_OnUpdate_Name,
-		Flags: bindings.MessageNoFlag,
-	}
-	var message *bindings.Message
-	if message, err = bindings.EncodeMessage(header, payload); err != nil {
-		err = fmt.Errorf("can't encode request: %v", err.Error())
-		p.Close_Proxy()
-		return
-	}
-	if err = p.router.Accept(message); err != nil {
-		p.Close_Proxy()
-		return
-	}
-	return
-}
-
-type scanHandler_Stub struct {
-	connector *bindings.Connector
-	impl      ScanHandler
-}
-
-func NewScanHandlerStub(r ScanHandler_Request, impl ScanHandler, waiter bindings.AsyncWaiter) *bindings.Stub {
-	connector := bindings.NewConnector(r.PassMessagePipe(), waiter)
-	return bindings.NewStub(connector, &scanHandler_Stub{connector, impl})
-}
-
-func (f *ScanHandler_Request) ServiceDescription() service_describer.ServiceDescription {
-	return &ScanHandler_ServiceDescription{}
-}
-
-type ScanHandler_ServiceDescription struct{}
-
-func (sd *ScanHandler_ServiceDescription) GetTopLevelInterface() (outMojomInterface mojom_types.MojomInterface, err error) {
-	err = fmt.Errorf("GetTopLevelInterface not implemented")
-	return
-}
-
-func (sd *ScanHandler_ServiceDescription) GetTypeDefinition(inTypeKey string) (outType mojom_types.UserDefinedType, err error) {
-	err = fmt.Errorf("GetTypeDefinition not implemented")
-	return
-}
-
-func (sd *ScanHandler_ServiceDescription) GetAllTypeDefinitions() (outDefinitions *map[string]mojom_types.UserDefinedType, err error) {
-	err = fmt.Errorf("GetAllTypeDefinitions not implemented")
-	return
-}
-
-var _ service_describer.ServiceDescription = (*ScanHandler_ServiceDescription)(nil)
-
-func (s *scanHandler_Stub) Accept(message *bindings.Message) (err error) {
-	switch message.Header.Type {
-	case scanHandler_OnUpdate_Name:
-		if message.Header.Flags != bindings.MessageNoFlag {
-			return &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
-				fmt.Sprintf("invalid message header flag: %v", message.Header.Flags),
-			}
-		}
-		var request scanHandler_OnUpdate_Params
-		if err := message.DecodePayload(&request); err != nil {
-			return err
-		}
-		err = s.impl.OnUpdate(request.inUpdate)
-		if err != nil {
-			return
-		}
-	default:
-		return &bindings.ValidationError{
-			bindings.MessageHeaderUnknownMethod,
-			fmt.Sprintf("unknown method %v", message.Header.Type),
-		}
-	}
-	return
-}
-
-type Update interface {
-	IsLost() (outLost bool, err error)
-	GetId() (outId [16]uint8, err error)
-	GetInterfaceName() (outInterfaceName string, err error)
-	GetAddresses() (outAddresses []string, err error)
-	GetAttribute(inName string) (outAttribute string, err error)
-	GetAttachment(inName string) (outData system.ConsumerHandle, err error)
-	GetAdvertisement() (outAd Advertisement, err error)
-}
-
-type Update_Request bindings.InterfaceRequest
-
-type Update_Pointer bindings.InterfacePointer
-
-type Update_ServiceFactory struct {
-	Delegate Update_Factory
-}
-
-type Update_Factory interface {
-	Create(request Update_Request)
-}
-
-// TODO(rudominer) This should only be defined for top-level interfaces.
-func (f *Update_ServiceFactory) ServiceDescription() service_describer.ServiceDescription {
-	return &Update_ServiceDescription{}
-}
-
-func (f *Update_ServiceFactory) Create(messagePipe system.MessagePipeHandle) {
-	request := Update_Request{bindings.NewMessagePipeHandleOwner(messagePipe)}
-	f.Delegate.Create(request)
-}
-
-// CreateMessagePipeForUpdate creates a message pipe for use with the
-// Update interface with a Update_Request on one end and a Update_Pointer on the other.
-func CreateMessagePipeForUpdate() (Update_Request, Update_Pointer) {
-	r, p := bindings.CreateMessagePipeForMojoInterface()
-	return Update_Request(r), Update_Pointer(p)
-}
-
-const update_IsLost_Name uint32 = 0
-const update_GetId_Name uint32 = 1
-const update_GetInterfaceName_Name uint32 = 2
-const update_GetAddresses_Name uint32 = 3
-const update_GetAttribute_Name uint32 = 4
-const update_GetAttachment_Name uint32 = 5
-const update_GetAdvertisement_Name uint32 = 6
-
-type Update_Proxy struct {
-	router *bindings.Router
-	ids    bindings.Counter
-}
-
-func NewUpdateProxy(p Update_Pointer, waiter bindings.AsyncWaiter) *Update_Proxy {
-	return &Update_Proxy{
-		bindings.NewRouter(p.PassMessagePipe(), waiter),
-		bindings.NewCounter(),
-	}
-}
-
-func (p *Update_Proxy) Close_Proxy() {
-	p.router.Close()
-}
-
-type update_IsLost_Params struct {
-}
-
-func (s *update_IsLost_Params) Encode(encoder *bindings.Encoder) error {
-	encoder.StartStruct(0, 0)
-	if err := encoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-var update_IsLost_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
-	bindings.DataHeader{8, 0},
-}
-
-func (s *update_IsLost_Params) Decode(decoder *bindings.Decoder) error {
-	header, err := decoder.StartStruct()
-	if err != nil {
-		return err
-	}
-	index := sort.Search(len(update_IsLost_Params_Versions), func(i int) bool {
-		return update_IsLost_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
-	})
-	if index < len(update_IsLost_Params_Versions) {
-		if update_IsLost_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
-			index--
-		}
-		expectedSize := update_IsLost_Params_Versions[index].Size
-		if expectedSize != header.Size {
-			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
-				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
-			}
-		}
-	}
-	if err := decoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-type update_IsLost_ResponseParams struct {
-	outLost bool
-}
-
-func (s *update_IsLost_ResponseParams) Encode(encoder *bindings.Encoder) error {
-	encoder.StartStruct(8, 0)
-	if err := encoder.WriteBool(s.outLost); err != nil {
-		return err
-	}
-	if err := encoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-var update_IsLost_ResponseParams_Versions []bindings.DataHeader = []bindings.DataHeader{
-	bindings.DataHeader{16, 0},
-}
-
-func (s *update_IsLost_ResponseParams) Decode(decoder *bindings.Decoder) error {
-	header, err := decoder.StartStruct()
-	if err != nil {
-		return err
-	}
-	index := sort.Search(len(update_IsLost_ResponseParams_Versions), func(i int) bool {
-		return update_IsLost_ResponseParams_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
-	})
-	if index < len(update_IsLost_ResponseParams_Versions) {
-		if update_IsLost_ResponseParams_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
-			index--
-		}
-		expectedSize := update_IsLost_ResponseParams_Versions[index].Size
-		if expectedSize != header.Size {
-			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
-				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
-			}
-		}
-	}
-	if header.ElementsOrVersion >= 0 {
-		value0, err := decoder.ReadBool()
-		if err != nil {
-			return err
-		}
-		s.outLost = value0
-	}
-	if err := decoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (p *Update_Proxy) IsLost() (outLost bool, err error) {
-	payload := &update_IsLost_Params{}
-	header := bindings.MessageHeader{
-		Type:      update_IsLost_Name,
-		Flags:     bindings.MessageExpectsResponseFlag,
-		RequestId: p.ids.Count(),
-	}
-	var message *bindings.Message
-	if message, err = bindings.EncodeMessage(header, payload); err != nil {
-		err = fmt.Errorf("can't encode request: %v", err.Error())
-		p.Close_Proxy()
-		return
-	}
-	readResult := <-p.router.AcceptWithResponse(message)
-	if err = readResult.Error; err != nil {
-		p.Close_Proxy()
-		return
-	}
-	if readResult.Message.Header.Flags != bindings.MessageIsResponseFlag {
-		err = &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
-			fmt.Sprintf("invalid message header flag: %v", readResult.Message.Header.Flags),
-		}
-		return
-	}
-	if got, want := readResult.Message.Header.Type, update_IsLost_Name; got != want {
-		err = &bindings.ValidationError{bindings.MessageHeaderUnknownMethod,
-			fmt.Sprintf("invalid method in response: expected %v, got %v", want, got),
-		}
-		return
-	}
-	var response update_IsLost_ResponseParams
-	if err = readResult.Message.DecodePayload(&response); err != nil {
-		p.Close_Proxy()
-		return
-	}
-	outLost = response.outLost
-	return
-}
-
-type update_GetId_Params struct {
-}
-
-func (s *update_GetId_Params) Encode(encoder *bindings.Encoder) error {
-	encoder.StartStruct(0, 0)
-	if err := encoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-var update_GetId_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
-	bindings.DataHeader{8, 0},
-}
-
-func (s *update_GetId_Params) Decode(decoder *bindings.Decoder) error {
-	header, err := decoder.StartStruct()
-	if err != nil {
-		return err
-	}
-	index := sort.Search(len(update_GetId_Params_Versions), func(i int) bool {
-		return update_GetId_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
-	})
-	if index < len(update_GetId_Params_Versions) {
-		if update_GetId_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
-			index--
-		}
-		expectedSize := update_GetId_Params_Versions[index].Size
-		if expectedSize != header.Size {
-			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
-				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
-			}
-		}
-	}
-	if err := decoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-type update_GetId_ResponseParams struct {
-	outId [16]uint8
-}
-
-func (s *update_GetId_ResponseParams) Encode(encoder *bindings.Encoder) error {
-	encoder.StartStruct(8, 0)
-	if err := encoder.WritePointer(); err != nil {
-		return err
-	}
-	encoder.StartArray(uint32(len(s.outId)), 8)
-	for _, elem0 := range s.outId {
-		if err := encoder.WriteUint8(elem0); err != nil {
-			return err
-		}
-	}
-	if err := encoder.Finish(); err != nil {
-		return err
-	}
-	if err := encoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-var update_GetId_ResponseParams_Versions []bindings.DataHeader = []bindings.DataHeader{
-	bindings.DataHeader{16, 0},
-}
-
-func (s *update_GetId_ResponseParams) Decode(decoder *bindings.Decoder) error {
-	header, err := decoder.StartStruct()
-	if err != nil {
-		return err
-	}
-	index := sort.Search(len(update_GetId_ResponseParams_Versions), func(i int) bool {
-		return update_GetId_ResponseParams_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
-	})
-	if index < len(update_GetId_ResponseParams_Versions) {
-		if update_GetId_ResponseParams_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
-			index--
-		}
-		expectedSize := update_GetId_ResponseParams_Versions[index].Size
-		if expectedSize != header.Size {
-			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
-				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
-			}
-		}
-	}
-	if header.ElementsOrVersion >= 0 {
-		pointer0, err := decoder.ReadPointer()
-		if err != nil {
-			return err
-		}
-		if pointer0 == 0 {
-			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
-		} else {
-			len0, err := decoder.StartArray(8)
-			if err != nil {
-				return err
-			}
-			if len0 != 16 {
-				return &bindings.ValidationError{bindings.UnexpectedArrayHeader,
-					fmt.Sprintf("invalid array length: expected %d, got %d", 16, len0),
-				}
-			}
-			for i0 := uint32(0); i0 < len0; i0++ {
-				value1, err := decoder.ReadUint8()
-				if err != nil {
-					return err
-				}
-				s.outId[i0] = value1
-			}
-			if err := decoder.Finish(); err != nil {
-				return err
-			}
-		}
-	}
-	if err := decoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (p *Update_Proxy) GetId() (outId [16]uint8, err error) {
-	payload := &update_GetId_Params{}
-	header := bindings.MessageHeader{
-		Type:      update_GetId_Name,
-		Flags:     bindings.MessageExpectsResponseFlag,
-		RequestId: p.ids.Count(),
-	}
-	var message *bindings.Message
-	if message, err = bindings.EncodeMessage(header, payload); err != nil {
-		err = fmt.Errorf("can't encode request: %v", err.Error())
-		p.Close_Proxy()
-		return
-	}
-	readResult := <-p.router.AcceptWithResponse(message)
-	if err = readResult.Error; err != nil {
-		p.Close_Proxy()
-		return
-	}
-	if readResult.Message.Header.Flags != bindings.MessageIsResponseFlag {
-		err = &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
-			fmt.Sprintf("invalid message header flag: %v", readResult.Message.Header.Flags),
-		}
-		return
-	}
-	if got, want := readResult.Message.Header.Type, update_GetId_Name; got != want {
-		err = &bindings.ValidationError{bindings.MessageHeaderUnknownMethod,
-			fmt.Sprintf("invalid method in response: expected %v, got %v", want, got),
-		}
-		return
-	}
-	var response update_GetId_ResponseParams
-	if err = readResult.Message.DecodePayload(&response); err != nil {
-		p.Close_Proxy()
-		return
-	}
-	outId = response.outId
-	return
-}
-
-type update_GetInterfaceName_Params struct {
-}
-
-func (s *update_GetInterfaceName_Params) Encode(encoder *bindings.Encoder) error {
-	encoder.StartStruct(0, 0)
-	if err := encoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-var update_GetInterfaceName_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
-	bindings.DataHeader{8, 0},
-}
-
-func (s *update_GetInterfaceName_Params) Decode(decoder *bindings.Decoder) error {
-	header, err := decoder.StartStruct()
-	if err != nil {
-		return err
-	}
-	index := sort.Search(len(update_GetInterfaceName_Params_Versions), func(i int) bool {
-		return update_GetInterfaceName_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
-	})
-	if index < len(update_GetInterfaceName_Params_Versions) {
-		if update_GetInterfaceName_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
-			index--
-		}
-		expectedSize := update_GetInterfaceName_Params_Versions[index].Size
-		if expectedSize != header.Size {
-			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
-				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
-			}
-		}
-	}
-	if err := decoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-type update_GetInterfaceName_ResponseParams struct {
-	outInterfaceName string
-}
-
-func (s *update_GetInterfaceName_ResponseParams) Encode(encoder *bindings.Encoder) error {
-	encoder.StartStruct(8, 0)
-	if err := encoder.WritePointer(); err != nil {
-		return err
-	}
-	if err := encoder.WriteString(s.outInterfaceName); err != nil {
-		return err
-	}
-	if err := encoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-var update_GetInterfaceName_ResponseParams_Versions []bindings.DataHeader = []bindings.DataHeader{
-	bindings.DataHeader{16, 0},
-}
-
-func (s *update_GetInterfaceName_ResponseParams) Decode(decoder *bindings.Decoder) error {
-	header, err := decoder.StartStruct()
-	if err != nil {
-		return err
-	}
-	index := sort.Search(len(update_GetInterfaceName_ResponseParams_Versions), func(i int) bool {
-		return update_GetInterfaceName_ResponseParams_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
-	})
-	if index < len(update_GetInterfaceName_ResponseParams_Versions) {
-		if update_GetInterfaceName_ResponseParams_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
-			index--
-		}
-		expectedSize := update_GetInterfaceName_ResponseParams_Versions[index].Size
-		if expectedSize != header.Size {
-			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
-				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
-			}
-		}
-	}
-	if header.ElementsOrVersion >= 0 {
-		pointer0, err := decoder.ReadPointer()
-		if err != nil {
-			return err
-		}
-		if pointer0 == 0 {
-			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
-		} else {
-			value0, err := decoder.ReadString()
-			if err != nil {
-				return err
-			}
-			s.outInterfaceName = value0
-		}
-	}
-	if err := decoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (p *Update_Proxy) GetInterfaceName() (outInterfaceName string, err error) {
-	payload := &update_GetInterfaceName_Params{}
-	header := bindings.MessageHeader{
-		Type:      update_GetInterfaceName_Name,
-		Flags:     bindings.MessageExpectsResponseFlag,
-		RequestId: p.ids.Count(),
-	}
-	var message *bindings.Message
-	if message, err = bindings.EncodeMessage(header, payload); err != nil {
-		err = fmt.Errorf("can't encode request: %v", err.Error())
-		p.Close_Proxy()
-		return
-	}
-	readResult := <-p.router.AcceptWithResponse(message)
-	if err = readResult.Error; err != nil {
-		p.Close_Proxy()
-		return
-	}
-	if readResult.Message.Header.Flags != bindings.MessageIsResponseFlag {
-		err = &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
-			fmt.Sprintf("invalid message header flag: %v", readResult.Message.Header.Flags),
-		}
-		return
-	}
-	if got, want := readResult.Message.Header.Type, update_GetInterfaceName_Name; got != want {
-		err = &bindings.ValidationError{bindings.MessageHeaderUnknownMethod,
-			fmt.Sprintf("invalid method in response: expected %v, got %v", want, got),
-		}
-		return
-	}
-	var response update_GetInterfaceName_ResponseParams
-	if err = readResult.Message.DecodePayload(&response); err != nil {
-		p.Close_Proxy()
-		return
-	}
-	outInterfaceName = response.outInterfaceName
-	return
-}
-
-type update_GetAddresses_Params struct {
-}
-
-func (s *update_GetAddresses_Params) Encode(encoder *bindings.Encoder) error {
-	encoder.StartStruct(0, 0)
-	if err := encoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-var update_GetAddresses_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
-	bindings.DataHeader{8, 0},
-}
-
-func (s *update_GetAddresses_Params) Decode(decoder *bindings.Decoder) error {
-	header, err := decoder.StartStruct()
-	if err != nil {
-		return err
-	}
-	index := sort.Search(len(update_GetAddresses_Params_Versions), func(i int) bool {
-		return update_GetAddresses_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
-	})
-	if index < len(update_GetAddresses_Params_Versions) {
-		if update_GetAddresses_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
-			index--
-		}
-		expectedSize := update_GetAddresses_Params_Versions[index].Size
-		if expectedSize != header.Size {
-			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
-				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
-			}
-		}
-	}
-	if err := decoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-type update_GetAddresses_ResponseParams struct {
-	outAddresses []string
-}
-
-func (s *update_GetAddresses_ResponseParams) Encode(encoder *bindings.Encoder) error {
-	encoder.StartStruct(8, 0)
-	if err := encoder.WritePointer(); err != nil {
-		return err
-	}
-	encoder.StartArray(uint32(len(s.outAddresses)), 64)
-	for _, elem0 := range s.outAddresses {
-		if err := encoder.WritePointer(); err != nil {
-			return err
-		}
-		if err := encoder.WriteString(elem0); err != nil {
-			return err
-		}
-	}
-	if err := encoder.Finish(); err != nil {
-		return err
-	}
-	if err := encoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-var update_GetAddresses_ResponseParams_Versions []bindings.DataHeader = []bindings.DataHeader{
-	bindings.DataHeader{16, 0},
-}
-
-func (s *update_GetAddresses_ResponseParams) Decode(decoder *bindings.Decoder) error {
-	header, err := decoder.StartStruct()
-	if err != nil {
-		return err
-	}
-	index := sort.Search(len(update_GetAddresses_ResponseParams_Versions), func(i int) bool {
-		return update_GetAddresses_ResponseParams_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
-	})
-	if index < len(update_GetAddresses_ResponseParams_Versions) {
-		if update_GetAddresses_ResponseParams_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
-			index--
-		}
-		expectedSize := update_GetAddresses_ResponseParams_Versions[index].Size
-		if expectedSize != header.Size {
-			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
-				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
-			}
-		}
-	}
-	if header.ElementsOrVersion >= 0 {
-		pointer0, err := decoder.ReadPointer()
-		if err != nil {
-			return err
-		}
-		if pointer0 == 0 {
-			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
-		} else {
-			len0, err := decoder.StartArray(64)
-			if err != nil {
-				return err
-			}
-			s.outAddresses = make([]string, len0)
-			for i0 := uint32(0); i0 < len0; i0++ {
-				pointer1, err := decoder.ReadPointer()
-				if err != nil {
-					return err
-				}
-				if pointer1 == 0 {
-					return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
-				} else {
-					value1, err := decoder.ReadString()
-					if err != nil {
-						return err
-					}
-					s.outAddresses[i0] = value1
-				}
-			}
-			if err := decoder.Finish(); err != nil {
-				return err
-			}
-		}
-	}
-	if err := decoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (p *Update_Proxy) GetAddresses() (outAddresses []string, err error) {
-	payload := &update_GetAddresses_Params{}
-	header := bindings.MessageHeader{
-		Type:      update_GetAddresses_Name,
-		Flags:     bindings.MessageExpectsResponseFlag,
-		RequestId: p.ids.Count(),
-	}
-	var message *bindings.Message
-	if message, err = bindings.EncodeMessage(header, payload); err != nil {
-		err = fmt.Errorf("can't encode request: %v", err.Error())
-		p.Close_Proxy()
-		return
-	}
-	readResult := <-p.router.AcceptWithResponse(message)
-	if err = readResult.Error; err != nil {
-		p.Close_Proxy()
-		return
-	}
-	if readResult.Message.Header.Flags != bindings.MessageIsResponseFlag {
-		err = &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
-			fmt.Sprintf("invalid message header flag: %v", readResult.Message.Header.Flags),
-		}
-		return
-	}
-	if got, want := readResult.Message.Header.Type, update_GetAddresses_Name; got != want {
-		err = &bindings.ValidationError{bindings.MessageHeaderUnknownMethod,
-			fmt.Sprintf("invalid method in response: expected %v, got %v", want, got),
-		}
-		return
-	}
-	var response update_GetAddresses_ResponseParams
-	if err = readResult.Message.DecodePayload(&response); err != nil {
-		p.Close_Proxy()
-		return
-	}
-	outAddresses = response.outAddresses
-	return
-}
-
-type update_GetAttribute_Params struct {
-	inName string
-}
-
-func (s *update_GetAttribute_Params) Encode(encoder *bindings.Encoder) error {
-	encoder.StartStruct(8, 0)
-	if err := encoder.WritePointer(); err != nil {
-		return err
-	}
-	if err := encoder.WriteString(s.inName); err != nil {
-		return err
-	}
-	if err := encoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-var update_GetAttribute_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
-	bindings.DataHeader{16, 0},
-}
-
-func (s *update_GetAttribute_Params) Decode(decoder *bindings.Decoder) error {
-	header, err := decoder.StartStruct()
-	if err != nil {
-		return err
-	}
-	index := sort.Search(len(update_GetAttribute_Params_Versions), func(i int) bool {
-		return update_GetAttribute_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
-	})
-	if index < len(update_GetAttribute_Params_Versions) {
-		if update_GetAttribute_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
-			index--
-		}
-		expectedSize := update_GetAttribute_Params_Versions[index].Size
-		if expectedSize != header.Size {
-			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
-				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
-			}
-		}
-	}
-	if header.ElementsOrVersion >= 0 {
-		pointer0, err := decoder.ReadPointer()
-		if err != nil {
-			return err
-		}
-		if pointer0 == 0 {
-			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
-		} else {
-			value0, err := decoder.ReadString()
-			if err != nil {
-				return err
-			}
-			s.inName = value0
-		}
-	}
-	if err := decoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-type update_GetAttribute_ResponseParams struct {
-	outAttribute string
-}
-
-func (s *update_GetAttribute_ResponseParams) Encode(encoder *bindings.Encoder) error {
-	encoder.StartStruct(8, 0)
-	if err := encoder.WritePointer(); err != nil {
-		return err
-	}
-	if err := encoder.WriteString(s.outAttribute); err != nil {
-		return err
-	}
-	if err := encoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-var update_GetAttribute_ResponseParams_Versions []bindings.DataHeader = []bindings.DataHeader{
-	bindings.DataHeader{16, 0},
-}
-
-func (s *update_GetAttribute_ResponseParams) Decode(decoder *bindings.Decoder) error {
-	header, err := decoder.StartStruct()
-	if err != nil {
-		return err
-	}
-	index := sort.Search(len(update_GetAttribute_ResponseParams_Versions), func(i int) bool {
-		return update_GetAttribute_ResponseParams_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
-	})
-	if index < len(update_GetAttribute_ResponseParams_Versions) {
-		if update_GetAttribute_ResponseParams_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
-			index--
-		}
-		expectedSize := update_GetAttribute_ResponseParams_Versions[index].Size
-		if expectedSize != header.Size {
-			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
-				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
-			}
-		}
-	}
-	if header.ElementsOrVersion >= 0 {
-		pointer0, err := decoder.ReadPointer()
-		if err != nil {
-			return err
-		}
-		if pointer0 == 0 {
-			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
-		} else {
-			value0, err := decoder.ReadString()
-			if err != nil {
-				return err
-			}
-			s.outAttribute = value0
-		}
-	}
-	if err := decoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (p *Update_Proxy) GetAttribute(inName string) (outAttribute string, err error) {
-	payload := &update_GetAttribute_Params{
-		inName,
-	}
-	header := bindings.MessageHeader{
-		Type:      update_GetAttribute_Name,
-		Flags:     bindings.MessageExpectsResponseFlag,
-		RequestId: p.ids.Count(),
-	}
-	var message *bindings.Message
-	if message, err = bindings.EncodeMessage(header, payload); err != nil {
-		err = fmt.Errorf("can't encode request: %v", err.Error())
-		p.Close_Proxy()
-		return
-	}
-	readResult := <-p.router.AcceptWithResponse(message)
-	if err = readResult.Error; err != nil {
-		p.Close_Proxy()
-		return
-	}
-	if readResult.Message.Header.Flags != bindings.MessageIsResponseFlag {
-		err = &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
-			fmt.Sprintf("invalid message header flag: %v", readResult.Message.Header.Flags),
-		}
-		return
-	}
-	if got, want := readResult.Message.Header.Type, update_GetAttribute_Name; got != want {
-		err = &bindings.ValidationError{bindings.MessageHeaderUnknownMethod,
-			fmt.Sprintf("invalid method in response: expected %v, got %v", want, got),
-		}
-		return
-	}
-	var response update_GetAttribute_ResponseParams
-	if err = readResult.Message.DecodePayload(&response); err != nil {
-		p.Close_Proxy()
-		return
-	}
-	outAttribute = response.outAttribute
-	return
-}
-
-type update_GetAttachment_Params struct {
-	inName string
-}
-
-func (s *update_GetAttachment_Params) Encode(encoder *bindings.Encoder) error {
-	encoder.StartStruct(8, 0)
-	if err := encoder.WritePointer(); err != nil {
-		return err
-	}
-	if err := encoder.WriteString(s.inName); err != nil {
-		return err
-	}
-	if err := encoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-var update_GetAttachment_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
-	bindings.DataHeader{16, 0},
-}
-
-func (s *update_GetAttachment_Params) Decode(decoder *bindings.Decoder) error {
-	header, err := decoder.StartStruct()
-	if err != nil {
-		return err
-	}
-	index := sort.Search(len(update_GetAttachment_Params_Versions), func(i int) bool {
-		return update_GetAttachment_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
-	})
-	if index < len(update_GetAttachment_Params_Versions) {
-		if update_GetAttachment_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
-			index--
-		}
-		expectedSize := update_GetAttachment_Params_Versions[index].Size
-		if expectedSize != header.Size {
-			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
-				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
-			}
-		}
-	}
-	if header.ElementsOrVersion >= 0 {
-		pointer0, err := decoder.ReadPointer()
-		if err != nil {
-			return err
-		}
-		if pointer0 == 0 {
-			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
-		} else {
-			value0, err := decoder.ReadString()
-			if err != nil {
-				return err
-			}
-			s.inName = value0
-		}
-	}
-	if err := decoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-type update_GetAttachment_ResponseParams struct {
-	outData system.ConsumerHandle
-}
-
-func (s *update_GetAttachment_ResponseParams) Encode(encoder *bindings.Encoder) error {
-	encoder.StartStruct(8, 0)
-	if err := encoder.WriteHandle(s.outData); err != nil {
-		return err
-	}
-	if err := encoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-var update_GetAttachment_ResponseParams_Versions []bindings.DataHeader = []bindings.DataHeader{
-	bindings.DataHeader{16, 0},
-}
-
-func (s *update_GetAttachment_ResponseParams) Decode(decoder *bindings.Decoder) error {
-	header, err := decoder.StartStruct()
-	if err != nil {
-		return err
-	}
-	index := sort.Search(len(update_GetAttachment_ResponseParams_Versions), func(i int) bool {
-		return update_GetAttachment_ResponseParams_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
-	})
-	if index < len(update_GetAttachment_ResponseParams_Versions) {
-		if update_GetAttachment_ResponseParams_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
-			index--
-		}
-		expectedSize := update_GetAttachment_ResponseParams_Versions[index].Size
-		if expectedSize != header.Size {
-			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
-				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
-			}
-		}
-	}
-	if header.ElementsOrVersion >= 0 {
-		handle0, err := decoder.ReadConsumerHandle()
-		if err != nil {
-			return err
-		}
-		if handle0.IsValid() {
-			s.outData = handle0
-		} else {
-			return &bindings.ValidationError{bindings.UnexpectedInvalidHandle, "unexpected invalid handle"}
-		}
-	}
-	if err := decoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (p *Update_Proxy) GetAttachment(inName string) (outData system.ConsumerHandle, err error) {
-	payload := &update_GetAttachment_Params{
-		inName,
-	}
-	header := bindings.MessageHeader{
-		Type:      update_GetAttachment_Name,
-		Flags:     bindings.MessageExpectsResponseFlag,
-		RequestId: p.ids.Count(),
-	}
-	var message *bindings.Message
-	if message, err = bindings.EncodeMessage(header, payload); err != nil {
-		err = fmt.Errorf("can't encode request: %v", err.Error())
-		p.Close_Proxy()
-		return
-	}
-	readResult := <-p.router.AcceptWithResponse(message)
-	if err = readResult.Error; err != nil {
-		p.Close_Proxy()
-		return
-	}
-	if readResult.Message.Header.Flags != bindings.MessageIsResponseFlag {
-		err = &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
-			fmt.Sprintf("invalid message header flag: %v", readResult.Message.Header.Flags),
-		}
-		return
-	}
-	if got, want := readResult.Message.Header.Type, update_GetAttachment_Name; got != want {
-		err = &bindings.ValidationError{bindings.MessageHeaderUnknownMethod,
-			fmt.Sprintf("invalid method in response: expected %v, got %v", want, got),
-		}
-		return
-	}
-	var response update_GetAttachment_ResponseParams
-	if err = readResult.Message.DecodePayload(&response); err != nil {
-		p.Close_Proxy()
-		return
-	}
-	outData = response.outData
-	return
-}
-
-type update_GetAdvertisement_Params struct {
-}
-
-func (s *update_GetAdvertisement_Params) Encode(encoder *bindings.Encoder) error {
-	encoder.StartStruct(0, 0)
-	if err := encoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-var update_GetAdvertisement_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
-	bindings.DataHeader{8, 0},
-}
-
-func (s *update_GetAdvertisement_Params) Decode(decoder *bindings.Decoder) error {
-	header, err := decoder.StartStruct()
-	if err != nil {
-		return err
-	}
-	index := sort.Search(len(update_GetAdvertisement_Params_Versions), func(i int) bool {
-		return update_GetAdvertisement_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
-	})
-	if index < len(update_GetAdvertisement_Params_Versions) {
-		if update_GetAdvertisement_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
-			index--
-		}
-		expectedSize := update_GetAdvertisement_Params_Versions[index].Size
-		if expectedSize != header.Size {
-			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
-				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
-			}
-		}
-	}
-	if err := decoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-type update_GetAdvertisement_ResponseParams struct {
-	outAd Advertisement
-}
-
-func (s *update_GetAdvertisement_ResponseParams) Encode(encoder *bindings.Encoder) error {
-	encoder.StartStruct(8, 0)
-	if err := encoder.WritePointer(); err != nil {
-		return err
-	}
-	if err := s.outAd.Encode(encoder); err != nil {
-		return err
-	}
-	if err := encoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-var update_GetAdvertisement_ResponseParams_Versions []bindings.DataHeader = []bindings.DataHeader{
-	bindings.DataHeader{16, 0},
-}
-
-func (s *update_GetAdvertisement_ResponseParams) Decode(decoder *bindings.Decoder) error {
-	header, err := decoder.StartStruct()
-	if err != nil {
-		return err
-	}
-	index := sort.Search(len(update_GetAdvertisement_ResponseParams_Versions), func(i int) bool {
-		return update_GetAdvertisement_ResponseParams_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
-	})
-	if index < len(update_GetAdvertisement_ResponseParams_Versions) {
-		if update_GetAdvertisement_ResponseParams_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
-			index--
-		}
-		expectedSize := update_GetAdvertisement_ResponseParams_Versions[index].Size
-		if expectedSize != header.Size {
-			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
-				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
-			}
-		}
-	}
-	if header.ElementsOrVersion >= 0 {
-		pointer0, err := decoder.ReadPointer()
-		if err != nil {
-			return err
-		}
-		if pointer0 == 0 {
-			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
-		} else {
-			if err := s.outAd.Decode(decoder); err != nil {
-				return err
-			}
-		}
-	}
-	if err := decoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (p *Update_Proxy) GetAdvertisement() (outAd Advertisement, err error) {
-	payload := &update_GetAdvertisement_Params{}
-	header := bindings.MessageHeader{
-		Type:      update_GetAdvertisement_Name,
-		Flags:     bindings.MessageExpectsResponseFlag,
-		RequestId: p.ids.Count(),
-	}
-	var message *bindings.Message
-	if message, err = bindings.EncodeMessage(header, payload); err != nil {
-		err = fmt.Errorf("can't encode request: %v", err.Error())
-		p.Close_Proxy()
-		return
-	}
-	readResult := <-p.router.AcceptWithResponse(message)
-	if err = readResult.Error; err != nil {
-		p.Close_Proxy()
-		return
-	}
-	if readResult.Message.Header.Flags != bindings.MessageIsResponseFlag {
-		err = &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
-			fmt.Sprintf("invalid message header flag: %v", readResult.Message.Header.Flags),
-		}
-		return
-	}
-	if got, want := readResult.Message.Header.Type, update_GetAdvertisement_Name; got != want {
-		err = &bindings.ValidationError{bindings.MessageHeaderUnknownMethod,
-			fmt.Sprintf("invalid method in response: expected %v, got %v", want, got),
-		}
-		return
-	}
-	var response update_GetAdvertisement_ResponseParams
-	if err = readResult.Message.DecodePayload(&response); err != nil {
-		p.Close_Proxy()
-		return
-	}
-	outAd = response.outAd
-	return
-}
-
-type update_Stub struct {
-	connector *bindings.Connector
-	impl      Update
-}
-
-func NewUpdateStub(r Update_Request, impl Update, waiter bindings.AsyncWaiter) *bindings.Stub {
-	connector := bindings.NewConnector(r.PassMessagePipe(), waiter)
-	return bindings.NewStub(connector, &update_Stub{connector, impl})
-}
-
-func (f *Update_Request) ServiceDescription() service_describer.ServiceDescription {
-	return &Update_ServiceDescription{}
-}
-
-type Update_ServiceDescription struct{}
-
-func (sd *Update_ServiceDescription) GetTopLevelInterface() (outMojomInterface mojom_types.MojomInterface, err error) {
-	err = fmt.Errorf("GetTopLevelInterface not implemented")
-	return
-}
-
-func (sd *Update_ServiceDescription) GetTypeDefinition(inTypeKey string) (outType mojom_types.UserDefinedType, err error) {
-	err = fmt.Errorf("GetTypeDefinition not implemented")
-	return
-}
-
-func (sd *Update_ServiceDescription) GetAllTypeDefinitions() (outDefinitions *map[string]mojom_types.UserDefinedType, err error) {
-	err = fmt.Errorf("GetAllTypeDefinitions not implemented")
-	return
-}
-
-var _ service_describer.ServiceDescription = (*Update_ServiceDescription)(nil)
-
-func (s *update_Stub) Accept(message *bindings.Message) (err error) {
-	switch message.Header.Type {
-	case update_IsLost_Name:
-		if message.Header.Flags != bindings.MessageExpectsResponseFlag {
-			return &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
-				fmt.Sprintf("invalid message header flag: %v", message.Header.Flags),
-			}
-		}
-		var request update_IsLost_Params
-		if err := message.DecodePayload(&request); err != nil {
-			return err
-		}
-		var response update_IsLost_ResponseParams
-		response.outLost, err = s.impl.IsLost()
-		if err != nil {
-			return
-		}
-		header := bindings.MessageHeader{
-			Type:      update_IsLost_Name,
-			Flags:     bindings.MessageIsResponseFlag,
-			RequestId: message.Header.RequestId,
-		}
-		message, err = bindings.EncodeMessage(header, &response)
-		if err != nil {
-			return err
-		}
-		return s.connector.WriteMessage(message)
-	case update_GetId_Name:
-		if message.Header.Flags != bindings.MessageExpectsResponseFlag {
-			return &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
-				fmt.Sprintf("invalid message header flag: %v", message.Header.Flags),
-			}
-		}
-		var request update_GetId_Params
-		if err := message.DecodePayload(&request); err != nil {
-			return err
-		}
-		var response update_GetId_ResponseParams
-		response.outId, err = s.impl.GetId()
-		if err != nil {
-			return
-		}
-		header := bindings.MessageHeader{
-			Type:      update_GetId_Name,
-			Flags:     bindings.MessageIsResponseFlag,
-			RequestId: message.Header.RequestId,
-		}
-		message, err = bindings.EncodeMessage(header, &response)
-		if err != nil {
-			return err
-		}
-		return s.connector.WriteMessage(message)
-	case update_GetInterfaceName_Name:
-		if message.Header.Flags != bindings.MessageExpectsResponseFlag {
-			return &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
-				fmt.Sprintf("invalid message header flag: %v", message.Header.Flags),
-			}
-		}
-		var request update_GetInterfaceName_Params
-		if err := message.DecodePayload(&request); err != nil {
-			return err
-		}
-		var response update_GetInterfaceName_ResponseParams
-		response.outInterfaceName, err = s.impl.GetInterfaceName()
-		if err != nil {
-			return
-		}
-		header := bindings.MessageHeader{
-			Type:      update_GetInterfaceName_Name,
-			Flags:     bindings.MessageIsResponseFlag,
-			RequestId: message.Header.RequestId,
-		}
-		message, err = bindings.EncodeMessage(header, &response)
-		if err != nil {
-			return err
-		}
-		return s.connector.WriteMessage(message)
-	case update_GetAddresses_Name:
-		if message.Header.Flags != bindings.MessageExpectsResponseFlag {
-			return &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
-				fmt.Sprintf("invalid message header flag: %v", message.Header.Flags),
-			}
-		}
-		var request update_GetAddresses_Params
-		if err := message.DecodePayload(&request); err != nil {
-			return err
-		}
-		var response update_GetAddresses_ResponseParams
-		response.outAddresses, err = s.impl.GetAddresses()
-		if err != nil {
-			return
-		}
-		header := bindings.MessageHeader{
-			Type:      update_GetAddresses_Name,
-			Flags:     bindings.MessageIsResponseFlag,
-			RequestId: message.Header.RequestId,
-		}
-		message, err = bindings.EncodeMessage(header, &response)
-		if err != nil {
-			return err
-		}
-		return s.connector.WriteMessage(message)
-	case update_GetAttribute_Name:
-		if message.Header.Flags != bindings.MessageExpectsResponseFlag {
-			return &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
-				fmt.Sprintf("invalid message header flag: %v", message.Header.Flags),
-			}
-		}
-		var request update_GetAttribute_Params
-		if err := message.DecodePayload(&request); err != nil {
-			return err
-		}
-		var response update_GetAttribute_ResponseParams
-		response.outAttribute, err = s.impl.GetAttribute(request.inName)
-		if err != nil {
-			return
-		}
-		header := bindings.MessageHeader{
-			Type:      update_GetAttribute_Name,
-			Flags:     bindings.MessageIsResponseFlag,
-			RequestId: message.Header.RequestId,
-		}
-		message, err = bindings.EncodeMessage(header, &response)
-		if err != nil {
-			return err
-		}
-		return s.connector.WriteMessage(message)
-	case update_GetAttachment_Name:
-		if message.Header.Flags != bindings.MessageExpectsResponseFlag {
-			return &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
-				fmt.Sprintf("invalid message header flag: %v", message.Header.Flags),
-			}
-		}
-		var request update_GetAttachment_Params
-		if err := message.DecodePayload(&request); err != nil {
-			return err
-		}
-		var response update_GetAttachment_ResponseParams
-		response.outData, err = s.impl.GetAttachment(request.inName)
-		if err != nil {
-			return
-		}
-		header := bindings.MessageHeader{
-			Type:      update_GetAttachment_Name,
-			Flags:     bindings.MessageIsResponseFlag,
-			RequestId: message.Header.RequestId,
-		}
-		message, err = bindings.EncodeMessage(header, &response)
-		if err != nil {
-			return err
-		}
-		return s.connector.WriteMessage(message)
-	case update_GetAdvertisement_Name:
-		if message.Header.Flags != bindings.MessageExpectsResponseFlag {
-			return &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
-				fmt.Sprintf("invalid message header flag: %v", message.Header.Flags),
-			}
-		}
-		var request update_GetAdvertisement_Params
-		if err := message.DecodePayload(&request); err != nil {
-			return err
-		}
-		var response update_GetAdvertisement_ResponseParams
-		response.outAd, err = s.impl.GetAdvertisement()
-		if err != nil {
-			return
-		}
-		header := bindings.MessageHeader{
-			Type:      update_GetAdvertisement_Name,
-			Flags:     bindings.MessageIsResponseFlag,
-			RequestId: message.Header.RequestId,
-		}
-		message, err = bindings.EncodeMessage(header, &response)
-		if err != nil {
-			return err
-		}
-		return s.connector.WriteMessage(message)
-	default:
-		return &bindings.ValidationError{
-			bindings.MessageHeaderUnknownMethod,
-			fmt.Sprintf("unknown method %v", message.Header.Type),
-		}
-	}
-	return
-}
-
-type Advertisement struct {
-	Id            *[16]uint8
-	InterfaceName string
-	Addresses     []string
-	Attributes    *map[string]string
-	Attachments   *map[string][]uint8
-}
-
-func (s *Advertisement) Encode(encoder *bindings.Encoder) error {
-	encoder.StartStruct(40, 0)
-	if s.Id == nil {
-		encoder.WriteNullPointer()
-	} else {
-		if err := encoder.WritePointer(); err != nil {
-			return err
-		}
-		encoder.StartArray(uint32(len((*s.Id))), 8)
-		for _, elem0 := range *s.Id {
-			if err := encoder.WriteUint8(elem0); err != nil {
-				return err
-			}
-		}
-		if err := encoder.Finish(); err != nil {
-			return err
-		}
-	}
-	if err := encoder.WritePointer(); err != nil {
-		return err
-	}
-	if err := encoder.WriteString(s.InterfaceName); err != nil {
-		return err
-	}
-	if err := encoder.WritePointer(); err != nil {
-		return err
-	}
-	encoder.StartArray(uint32(len(s.Addresses)), 64)
-	for _, elem0 := range s.Addresses {
-		if err := encoder.WritePointer(); err != nil {
-			return err
-		}
-		if err := encoder.WriteString(elem0); err != nil {
-			return err
-		}
-	}
-	if err := encoder.Finish(); err != nil {
-		return err
-	}
-	if s.Attributes == nil {
-		encoder.WriteNullPointer()
-	} else {
-		if err := encoder.WritePointer(); err != nil {
-			return err
-		}
-		encoder.StartMap()
-		{
-			var keys0 []string
-			var values0 []string
-			for key0, value0 := range *s.Attributes {
-				keys0 = append(keys0, key0)
-				values0 = append(values0, value0)
-			}
-			if err := encoder.WritePointer(); err != nil {
-				return err
-			}
-			encoder.StartArray(uint32(len(keys0)), 64)
-			for _, elem1 := range keys0 {
-				if err := encoder.WritePointer(); err != nil {
-					return err
-				}
-				if err := encoder.WriteString(elem1); err != nil {
-					return err
-				}
-			}
-			if err := encoder.Finish(); err != nil {
-				return err
-			}
-			if err := encoder.WritePointer(); err != nil {
-				return err
-			}
-			encoder.StartArray(uint32(len(values0)), 64)
-			for _, elem1 := range values0 {
-				if err := encoder.WritePointer(); err != nil {
-					return err
-				}
-				if err := encoder.WriteString(elem1); err != nil {
-					return err
-				}
-			}
-			if err := encoder.Finish(); err != nil {
-				return err
-			}
-		}
-		if err := encoder.Finish(); err != nil {
-			return err
-		}
-	}
-	if s.Attachments == nil {
-		encoder.WriteNullPointer()
-	} else {
-		if err := encoder.WritePointer(); err != nil {
-			return err
-		}
-		encoder.StartMap()
-		{
-			var keys0 []string
-			var values0 [][]uint8
-			for key0, value0 := range *s.Attachments {
-				keys0 = append(keys0, key0)
-				values0 = append(values0, value0)
-			}
-			if err := encoder.WritePointer(); err != nil {
-				return err
-			}
-			encoder.StartArray(uint32(len(keys0)), 64)
-			for _, elem1 := range keys0 {
-				if err := encoder.WritePointer(); err != nil {
-					return err
-				}
-				if err := encoder.WriteString(elem1); err != nil {
-					return err
-				}
-			}
-			if err := encoder.Finish(); err != nil {
-				return err
-			}
-			if err := encoder.WritePointer(); err != nil {
-				return err
-			}
-			encoder.StartArray(uint32(len(values0)), 64)
-			for _, elem1 := range values0 {
-				if err := encoder.WritePointer(); err != nil {
-					return err
-				}
-				encoder.StartArray(uint32(len(elem1)), 8)
-				for _, elem2 := range elem1 {
-					if err := encoder.WriteUint8(elem2); err != nil {
-						return err
-					}
-				}
-				if err := encoder.Finish(); err != nil {
-					return err
-				}
-			}
-			if err := encoder.Finish(); err != nil {
-				return err
-			}
-		}
-		if err := encoder.Finish(); err != nil {
-			return err
-		}
-	}
-	if err := encoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-var advertisement_Versions []bindings.DataHeader = []bindings.DataHeader{
-	bindings.DataHeader{48, 0},
-}
-
-func (s *Advertisement) Decode(decoder *bindings.Decoder) error {
-	header, err := decoder.StartStruct()
-	if err != nil {
-		return err
-	}
-	index := sort.Search(len(advertisement_Versions), func(i int) bool {
-		return advertisement_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
-	})
-	if index < len(advertisement_Versions) {
-		if advertisement_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
-			index--
-		}
-		expectedSize := advertisement_Versions[index].Size
-		if expectedSize != header.Size {
-			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
-				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
-			}
-		}
-	}
-	if header.ElementsOrVersion >= 0 {
-		pointer0, err := decoder.ReadPointer()
-		if err != nil {
-			return err
-		}
-		if pointer0 == 0 {
-			s.Id = nil
-		} else {
-			s.Id = new([16]uint8)
-			len0, err := decoder.StartArray(8)
-			if err != nil {
-				return err
-			}
-			if len0 != 16 {
-				return &bindings.ValidationError{bindings.UnexpectedArrayHeader,
-					fmt.Sprintf("invalid array length: expected %d, got %d", 16, len0),
-				}
-			}
-			for i0 := uint32(0); i0 < len0; i0++ {
-				value1, err := decoder.ReadUint8()
-				if err != nil {
-					return err
-				}
-				(*s.Id)[i0] = value1
-			}
-			if err := decoder.Finish(); err != nil {
-				return err
-			}
-		}
-	}
-	if header.ElementsOrVersion >= 0 {
-		pointer0, err := decoder.ReadPointer()
-		if err != nil {
-			return err
-		}
-		if pointer0 == 0 {
-			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
-		} else {
-			value0, err := decoder.ReadString()
-			if err != nil {
-				return err
-			}
-			s.InterfaceName = value0
-		}
-	}
-	if header.ElementsOrVersion >= 0 {
-		pointer0, err := decoder.ReadPointer()
-		if err != nil {
-			return err
-		}
-		if pointer0 == 0 {
-			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
-		} else {
-			len0, err := decoder.StartArray(64)
-			if err != nil {
-				return err
-			}
-			s.Addresses = make([]string, len0)
-			for i0 := uint32(0); i0 < len0; i0++ {
-				pointer1, err := decoder.ReadPointer()
-				if err != nil {
-					return err
-				}
-				if pointer1 == 0 {
-					return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
-				} else {
-					value1, err := decoder.ReadString()
-					if err != nil {
-						return err
-					}
-					s.Addresses[i0] = value1
-				}
-			}
-			if err := decoder.Finish(); err != nil {
-				return err
-			}
-		}
-	}
-	if header.ElementsOrVersion >= 0 {
-		pointer0, err := decoder.ReadPointer()
-		if err != nil {
-			return err
-		}
-		if pointer0 == 0 {
-			s.Attributes = nil
-		} else {
-			s.Attributes = new(map[string]string)
-			if err := decoder.StartMap(); err != nil {
-				return err
-			}
-			var keys0 []string
-			{
-				pointer1, err := decoder.ReadPointer()
-				if err != nil {
-					return err
-				}
-				if pointer1 == 0 {
-					return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
-				} else {
-					len1, err := decoder.StartArray(64)
-					if err != nil {
-						return err
-					}
-					keys0 = make([]string, len1)
-					for i1 := uint32(0); i1 < len1; i1++ {
-						pointer2, err := decoder.ReadPointer()
-						if err != nil {
-							return err
-						}
-						if pointer2 == 0 {
-							return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
-						} else {
-							value2, err := decoder.ReadString()
-							if err != nil {
-								return err
-							}
-							keys0[i1] = value2
-						}
-					}
-					if err := decoder.Finish(); err != nil {
-						return err
-					}
-				}
-			}
-			var values0 []string
-			{
-				pointer1, err := decoder.ReadPointer()
-				if err != nil {
-					return err
-				}
-				if pointer1 == 0 {
-					return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
-				} else {
-					len1, err := decoder.StartArray(64)
-					if err != nil {
-						return err
-					}
-					values0 = make([]string, len1)
-					for i1 := uint32(0); i1 < len1; i1++ {
-						pointer2, err := decoder.ReadPointer()
-						if err != nil {
-							return err
-						}
-						if pointer2 == 0 {
-							return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
-						} else {
-							value2, err := decoder.ReadString()
-							if err != nil {
-								return err
-							}
-							values0[i1] = value2
-						}
-					}
-					if err := decoder.Finish(); err != nil {
-						return err
-					}
-				}
-			}
-			if len(keys0) != len(values0) {
-				return &bindings.ValidationError{bindings.DifferentSizedArraysInMap,
-					fmt.Sprintf("Number of keys %d is different from number of values %d", len(keys0), len(values0)),
-				}
-			}
-			if err := decoder.Finish(); err != nil {
-				return err
-			}
-			len0 := len(keys0)
-			map0 := make(map[string]string)
-			for i0 := 0; i0 < len0; i0++ {
-				map0[keys0[i0]] = values0[i0]
-			}
-			(*s.Attributes) = map0
-		}
-	}
-	if header.ElementsOrVersion >= 0 {
-		pointer0, err := decoder.ReadPointer()
-		if err != nil {
-			return err
-		}
-		if pointer0 == 0 {
-			s.Attachments = nil
-		} else {
-			s.Attachments = new(map[string][]uint8)
-			if err := decoder.StartMap(); err != nil {
-				return err
-			}
-			var keys0 []string
-			{
-				pointer1, err := decoder.ReadPointer()
-				if err != nil {
-					return err
-				}
-				if pointer1 == 0 {
-					return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
-				} else {
-					len1, err := decoder.StartArray(64)
-					if err != nil {
-						return err
-					}
-					keys0 = make([]string, len1)
-					for i1 := uint32(0); i1 < len1; i1++ {
-						pointer2, err := decoder.ReadPointer()
-						if err != nil {
-							return err
-						}
-						if pointer2 == 0 {
-							return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
-						} else {
-							value2, err := decoder.ReadString()
-							if err != nil {
-								return err
-							}
-							keys0[i1] = value2
-						}
-					}
-					if err := decoder.Finish(); err != nil {
-						return err
-					}
-				}
-			}
-			var values0 [][]uint8
-			{
-				pointer1, err := decoder.ReadPointer()
-				if err != nil {
-					return err
-				}
-				if pointer1 == 0 {
-					return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
-				} else {
-					len1, err := decoder.StartArray(64)
-					if err != nil {
-						return err
-					}
-					values0 = make([][]uint8, len1)
-					for i1 := uint32(0); i1 < len1; i1++ {
-						pointer2, err := decoder.ReadPointer()
-						if err != nil {
-							return err
-						}
-						if pointer2 == 0 {
-							return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
-						} else {
-							len2, err := decoder.StartArray(8)
-							if err != nil {
-								return err
-							}
-							values0[i1] = make([]uint8, len2)
-							for i2 := uint32(0); i2 < len2; i2++ {
-								value3, err := decoder.ReadUint8()
-								if err != nil {
-									return err
-								}
-								values0[i1][i2] = value3
-							}
-							if err := decoder.Finish(); err != nil {
-								return err
-							}
-						}
-					}
-					if err := decoder.Finish(); err != nil {
-						return err
-					}
-				}
-			}
-			if len(keys0) != len(values0) {
-				return &bindings.ValidationError{bindings.DifferentSizedArraysInMap,
-					fmt.Sprintf("Number of keys %d is different from number of values %d", len(keys0), len(values0)),
-				}
-			}
-			if err := decoder.Finish(); err != nil {
-				return err
-			}
-			len0 := len(keys0)
-			map0 := make(map[string][]uint8)
-			for i0 := 0; i0 < len0; i0++ {
-				map0[keys0[i0]] = values0[i0]
-			}
-			(*s.Attachments) = map0
-		}
-	}
-	if err := decoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-type Error struct {
-	Id         string
-	ActionCode uint32
-	Msg        string
-}
-
-func (s *Error) Encode(encoder *bindings.Encoder) error {
-	encoder.StartStruct(24, 0)
-	if err := encoder.WritePointer(); err != nil {
-		return err
-	}
-	if err := encoder.WriteString(s.Id); err != nil {
-		return err
-	}
-	if err := encoder.WriteUint32(s.ActionCode); err != nil {
-		return err
-	}
-	if err := encoder.WritePointer(); err != nil {
-		return err
-	}
-	if err := encoder.WriteString(s.Msg); err != nil {
-		return err
-	}
-	if err := encoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-var error_Versions []bindings.DataHeader = []bindings.DataHeader{
-	bindings.DataHeader{32, 0},
-}
-
-func (s *Error) Decode(decoder *bindings.Decoder) error {
-	header, err := decoder.StartStruct()
-	if err != nil {
-		return err
-	}
-	index := sort.Search(len(error_Versions), func(i int) bool {
-		return error_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
-	})
-	if index < len(error_Versions) {
-		if error_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
-			index--
-		}
-		expectedSize := error_Versions[index].Size
-		if expectedSize != header.Size {
-			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
-				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
-			}
-		}
-	}
-	if header.ElementsOrVersion >= 0 {
-		pointer0, err := decoder.ReadPointer()
-		if err != nil {
-			return err
-		}
-		if pointer0 == 0 {
-			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
-		} else {
-			value0, err := decoder.ReadString()
-			if err != nil {
-				return err
-			}
-			s.Id = value0
-		}
-	}
-	if header.ElementsOrVersion >= 0 {
-		value0, err := decoder.ReadUint32()
-		if err != nil {
-			return err
-		}
-		s.ActionCode = value0
-	}
-	if header.ElementsOrVersion >= 0 {
-		pointer0, err := decoder.ReadPointer()
-		if err != nil {
-			return err
-		}
-		if pointer0 == 0 {
-			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
-		} else {
-			value0, err := decoder.ReadString()
-			if err != nil {
-				return err
-			}
-			s.Msg = value0
-		}
-	}
-	if err := decoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
diff --git a/go/src/vanadium/discovery/internal/apptest/apptest.go b/go/src/v.io/mojo/discovery/apptest/apptest.go
similarity index 100%
rename from go/src/vanadium/discovery/internal/apptest/apptest.go
rename to go/src/v.io/mojo/discovery/apptest/apptest.go
diff --git a/go/src/v.io/mojo/discovery/apptest/discovery_apptest.go b/go/src/v.io/mojo/discovery/apptest/discovery_apptest.go
new file mode 100644
index 0000000..8eb7325
--- /dev/null
+++ b/go/src/v.io/mojo/discovery/apptest/discovery_apptest.go
@@ -0,0 +1,334 @@
+// Copyright 2016 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build mojo
+
+package apptest
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+	"log"
+	"reflect"
+	"strings"
+	"testing"
+	"time"
+
+	"mojo/public/go/application"
+	"mojo/public/go/bindings"
+	"mojo/public/go/system"
+
+	mojom "mojom/v.io/discovery"
+
+	_ "v.io/x/ref/runtime/factories/generic"
+
+	"v.io/mojo/discovery/internal"
+)
+
+func newDiscovery(mctx application.Context) *mojom.Discovery_Proxy {
+	req, ptr := mojom.CreateMessagePipeForDiscovery()
+	mctx.ConnectToApplication("https://mojo.v.io/discovery.mojo").ConnectToService(&req)
+	return mojom.NewDiscoveryProxy(ptr, bindings.GetAsyncWaiter())
+}
+
+func AppTestBasic(t *testing.T, mctx application.Context) {
+	ads := []mojom.Advertisement{
+		{
+			Id:            &[internal.AdIdLen]uint8{1, 2, 3},
+			InterfaceName: "v.io/v23/a",
+			Addresses:     []string{"/h1:123/x"},
+			Attributes:    &map[string]string{"a1": "v"},
+			Attachments:   &map[string][]byte{"a2": []byte{1}},
+		},
+		{
+			InterfaceName: "v.io/v23/b",
+			Addresses:     []string{"/h1:123/y"},
+			Attributes:    &map[string]string{"b1": "w"},
+			Attachments:   &map[string][]byte{"b2": []byte{2}},
+		},
+	}
+
+	d1 := newDiscovery(mctx)
+	defer d1.Close_Proxy()
+
+	var stops []func()
+	for i, ad := range ads {
+		id, closer, e1, e2 := d1.Advertise(ad, nil)
+		if e1 != nil || e2 != nil {
+			t.Fatalf("ad[%d]: failed to advertise: %v, %v", i, e1, e2)
+		}
+		if id == nil {
+			t.Errorf("ad[%d]: got nil id", i)
+			continue
+		}
+		if ad.Id == nil {
+			ads[i].Id = id
+		} else if *id != *ad.Id {
+			t.Errorf("ad[%d]: got ad id %v, but wanted %v", i, *id, *ad.Id)
+		}
+
+		stop := func() {
+			p := mojom.NewCloserProxy(*closer, bindings.GetAsyncWaiter())
+			p.Close()
+			p.Close_Proxy()
+		}
+		stops = append(stops, stop)
+	}
+
+	// Make sure none of advertisements are discoverable by the same discovery instance.
+	if err := scanAndMatch(d1, ""); err != nil {
+		t.Error(err)
+	}
+
+	// Create a new discovery instance. All advertisements should be discovered with that.
+	d2 := newDiscovery(mctx)
+	defer d2.Close_Proxy()
+
+	if err := scanAndMatch(d2, `v.InterfaceName="v.io/v23/a"`, ads[0]); err != nil {
+		t.Error(err)
+	}
+	if err := scanAndMatch(d2, `v.InterfaceName="v.io/v23/b"`, ads[1]); err != nil {
+		t.Error(err)
+	}
+	if err := scanAndMatch(d2, ``, ads...); err != nil {
+		t.Error(err)
+	}
+
+	// Open a new scan channel and consume expected advertisements first.
+	scanCh, stop, err := scan(d2, `v.InterfaceName="v.io/v23/a"`)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer stop()
+
+	update := <-scanCh
+	if err := matchFound([]mojom.Update_Pointer{update}, ads[0]); err != nil {
+		t.Error(err)
+	}
+
+	// Make sure scan returns the lost advertisement when advertising is stopped.
+	stops[0]()
+
+	update = <-scanCh
+	if err := matchLost([]mojom.Update_Pointer{update}, ads[0]); err != nil {
+		t.Error(err)
+	}
+
+	// Also it shouldn't affect the other.
+	if err := scanAndMatch(d2, `v.InterfaceName="v.io/v23/b"`, ads[1]); err != nil {
+		t.Error(err)
+	}
+
+	// Stop advertising the remaining one; Shouldn't discover any advertisements.
+	stops[1]()
+	if err := scanAndMatch(d2, ``); err != nil {
+		t.Error(err)
+	}
+}
+
+type mockScanHandler struct {
+	ch chan mojom.Update_Pointer
+}
+
+func (h *mockScanHandler) OnUpdate(ptr mojom.Update_Pointer) error {
+	h.ch <- ptr
+	return nil
+}
+
+func scan(d mojom.Discovery, query string) (<-chan mojom.Update_Pointer, func(), error) {
+	ch := make(chan mojom.Update_Pointer)
+	handler := &mockScanHandler{ch}
+	req, ptr := mojom.CreateMessagePipeForScanHandler()
+	stub := mojom.NewScanHandlerStub(req, handler, bindings.GetAsyncWaiter())
+
+	closer, e1, e2 := d.Scan(query, ptr)
+	if e1 != nil {
+		close(ch)
+		return nil, nil, errors.New(e1.Msg)
+	}
+	if e2 != nil {
+		close(ch)
+		return nil, nil, e2
+	}
+
+	go func() {
+		for {
+			if err := stub.ServeRequest(); err != nil {
+				connErr, ok := err.(*bindings.ConnectionError)
+				if !ok || !connErr.Closed() {
+					log.Println(err)
+				}
+				break
+			}
+		}
+	}()
+
+	stop := func() {
+		p := mojom.NewCloserProxy(*closer, bindings.GetAsyncWaiter())
+		p.Close()
+		p.Close_Proxy()
+		stub.Close()
+		close(ch)
+	}
+	return ch, stop, nil
+}
+
+func scanAndMatch(d mojom.Discovery, query string, wants ...mojom.Advertisement) error {
+	const timeout = 10 * time.Second
+
+	var err error
+	for now := time.Now(); time.Since(now) < timeout; {
+		var updatePtrs []mojom.Update_Pointer
+		updatePtrs, err = doScan(d, query, len(wants))
+		if err != nil {
+			return err
+		}
+		err = matchFound(updatePtrs, wants...)
+		if err == nil {
+			return nil
+		}
+	}
+	return err
+}
+
+func doScan(d mojom.Discovery, query string, expectedUpdates int) ([]mojom.Update_Pointer, error) {
+	scanCh, stop, err := scan(d, query)
+	if err != nil {
+		return nil, err
+	}
+	defer func() {
+		stop()
+		for range scanCh {
+		}
+	}()
+
+	updatePtrs := make([]mojom.Update_Pointer, 0, expectedUpdates)
+	for {
+		var timer <-chan time.Time
+		if len(updatePtrs) >= expectedUpdates {
+			timer = time.After(5 * time.Millisecond)
+		}
+
+		select {
+		case ptr := <-scanCh:
+			updatePtrs = append(updatePtrs, ptr)
+		case <-timer:
+			return updatePtrs, nil
+		}
+	}
+}
+
+func matchFound(updatePtrs []mojom.Update_Pointer, wants ...mojom.Advertisement) error {
+	return match(updatePtrs, false, wants...)
+}
+
+func matchLost(updatePtrs []mojom.Update_Pointer, wants ...mojom.Advertisement) error {
+	return match(updatePtrs, true, wants...)
+}
+
+func match(updatePtrs []mojom.Update_Pointer, lost bool, wants ...mojom.Advertisement) error {
+	updateMap := make(map[[internal.AdIdLen]uint8]mojom.Update)
+	updates := make([]mojom.Update, 0)
+	for _, ptr := range updatePtrs {
+		update := mojom.NewUpdateProxy(ptr, bindings.GetAsyncWaiter())
+		defer update.Close_Proxy()
+
+		id, _ := update.GetId()
+		updateMap[id] = update
+		updates = append(updates, update)
+	}
+	for _, want := range wants {
+		update := updateMap[*want.Id]
+		if update == nil {
+			break
+		}
+		if got, _ := update.IsLost(); got != lost {
+			break
+		}
+		if !updateEqual(update, want) {
+			break
+		}
+		delete(updateMap, *want.Id)
+	}
+	if len(updateMap) == 0 {
+		return nil
+	}
+
+	return fmt.Errorf("Match failed; got %v, but wanted %v", updatesToDebugString(updates), adsToDebugString(wants))
+}
+
+func updateEqual(update mojom.Update, ad mojom.Advertisement) bool {
+	if got, _ := update.GetId(); got != *ad.Id {
+		return false
+	}
+	if got, _ := update.GetInterfaceName(); got != ad.InterfaceName {
+		return false
+	}
+	if got, _ := update.GetAddresses(); !reflect.DeepEqual(got, ad.Addresses) {
+		return false
+	}
+	if ad.Attributes != nil {
+		for k, v := range *ad.Attributes {
+			if got, _ := update.GetAttribute(k); got != v {
+				return false
+			}
+		}
+	}
+	if ad.Attachments != nil {
+		for k, v := range *ad.Attachments {
+			h, err := update.GetAttachment(k)
+			if err != nil {
+				return false
+			}
+			defer h.Close()
+			h.Wait(system.MOJO_HANDLE_SIGNAL_READABLE, system.MOJO_DEADLINE_INDEFINITE)
+			r, got := h.ReadData(system.MOJO_READ_DATA_FLAG_ALL_OR_NONE)
+			if r != system.MOJO_RESULT_OK {
+				return false
+			}
+			if !bytes.Equal(got, v) {
+				return false
+			}
+		}
+	}
+	if got, _ := update.GetAdvertisement(); !reflect.DeepEqual(got, ad) {
+		return false
+	}
+	return true
+}
+
+func adsToDebugString(ads []mojom.Advertisement) string {
+	var strs []string
+	for _, ad := range ads {
+		strs = append(strs, adToDebugString(ad))
+	}
+	return "[]" + strings.Join(strs, ", ") + "]"
+}
+
+func adToDebugString(ad mojom.Advertisement) string {
+	return "{" + strings.Join(dumpFields(ad), ", ") + "}"
+}
+
+func updatesToDebugString(updates []mojom.Update) string {
+	var strs []string
+	for _, u := range updates {
+		strs = append(strs, updateToDebugString(u))
+	}
+	return "[]" + strings.Join(strs, ", ") + "]"
+}
+
+func updateToDebugString(update mojom.Update) string {
+	lost, _ := update.IsLost()
+	ad, _ := update.GetAdvertisement()
+	return fmt.Sprintf("{%v, %v}", lost, strings.Join(dumpFields(ad), ", "))
+}
+
+func dumpFields(i interface{}) []string {
+	var fields []string
+	for rv, i := reflect.ValueOf(i), 0; i < rv.NumField(); i++ {
+		fields = append(fields, fmt.Sprint(rv.Field(i)))
+	}
+	return fields
+}
diff --git a/go/src/vanadium/discovery/internal/apptest/main/main.go b/go/src/v.io/mojo/discovery/apptest/main/main.go
similarity index 96%
rename from go/src/vanadium/discovery/internal/apptest/main/main.go
rename to go/src/v.io/mojo/discovery/apptest/main/main.go
index 005c1bc..fd67695 100644
--- a/go/src/vanadium/discovery/internal/apptest/main/main.go
+++ b/go/src/v.io/mojo/discovery/apptest/main/main.go
@@ -14,7 +14,7 @@
 	"mojo/public/go/application"
 	"mojo/public/go/system"
 
-	"vanadium/discovery/internal/apptest"
+	"v.io/mojo/discovery/apptest"
 )
 
 //#include "mojo/public/c/system/types.h"
diff --git a/go/src/vanadium/discovery/discovery.go b/go/src/v.io/mojo/discovery/discovery.go
similarity index 82%
rename from go/src/vanadium/discovery/discovery.go
rename to go/src/v.io/mojo/discovery/discovery.go
index e81e0b1..c924359 100644
--- a/go/src/vanadium/discovery/discovery.go
+++ b/go/src/v.io/mojo/discovery/discovery.go
@@ -7,24 +7,33 @@
 package main
 
 import (
+	"flag"
 	"sync"
 
 	"mojo/public/go/application"
 	"mojo/public/go/bindings"
 	"mojo/public/go/system"
-	mojom "mojom/vanadium/discovery"
+
+	mojom "mojom/v.io/discovery"
 
 	"v.io/v23"
 	"v.io/v23/context"
 
+	idiscovery "v.io/x/ref/lib/discovery"
+	fdiscovery "v.io/x/ref/lib/discovery/factory"
+	"v.io/x/ref/lib/discovery/plugins/mock"
 	_ "v.io/x/ref/runtime/factories/generic"
 
-	"vanadium/discovery/internal"
+	"v.io/mojo/discovery/internal"
 )
 
 //#include "mojo/public/c/system/types.h"
 import "C"
 
+var (
+	flagUseMock = flag.Bool("use-mock", false, "Use a mock plugin for mojo apptests.")
+)
+
 type delegate struct {
 	ctx      *context.T
 	shutdown v23.Shutdown
@@ -39,6 +48,11 @@
 	// vanadium service that will be used in the demos and each go library
 	// will be in its own process.
 	d.ctx, d.shutdown = v23.Init(mctx)
+
+	if *flagUseMock {
+		df, _ := idiscovery.NewFactory(d.ctx, mock.New())
+		fdiscovery.InjectFactory(df)
+	}
 }
 
 func (d *delegate) Create(request mojom.Discovery_Request) {
diff --git a/go/src/vanadium/discovery/internal/discovery.go b/go/src/v.io/mojo/discovery/internal/discovery.go
similarity index 93%
rename from go/src/vanadium/discovery/internal/discovery.go
rename to go/src/v.io/mojo/discovery/internal/discovery.go
index 7ef3cac..17f5056 100644
--- a/go/src/vanadium/discovery/internal/discovery.go
+++ b/go/src/v.io/mojo/discovery/internal/discovery.go
@@ -9,7 +9,7 @@
 
 	"mojo/public/go/bindings"
 
-	mojom "mojom/vanadium/discovery"
+	mojom "mojom/v.io/discovery"
 
 	"v.io/v23"
 	"v.io/v23/context"
@@ -39,8 +39,10 @@
 
 // mdiscovery is a thin wrapper around the Vanadium discovery.
 type mdiscovery struct {
-	ctx *context.T
-	d   discovery.T
+	ctx    *context.T
+	cancel func()
+
+	d discovery.T
 
 	mu    sync.Mutex
 	stubs map[*bindings.Stub]struct{} // GUARDED_BY(mu)
@@ -133,6 +135,7 @@
 	d.mu.Lock()
 	defer d.mu.Unlock()
 
+	d.cancel()
 	for stub := range d.stubs {
 		stub.Close()
 	}
@@ -156,9 +159,11 @@
 		return &ediscovery{err}
 	}
 
+	ctx, cancel := context.WithCancel(ctx)
 	return &mdiscovery{
-		ctx:   ctx,
-		d:     d,
-		stubs: make(map[*bindings.Stub]struct{}),
+		ctx:    ctx,
+		cancel: cancel,
+		d:      d,
+		stubs:  make(map[*bindings.Stub]struct{}),
 	}
 }
diff --git a/go/src/vanadium/discovery/internal/update.go b/go/src/v.io/mojo/discovery/internal/update.go
similarity index 97%
rename from go/src/vanadium/discovery/internal/update.go
rename to go/src/v.io/mojo/discovery/internal/update.go
index 1732562..f181446 100644
--- a/go/src/vanadium/discovery/internal/update.go
+++ b/go/src/v.io/mojo/discovery/internal/update.go
@@ -9,7 +9,7 @@
 
 	"mojo/public/go/system"
 
-	mojom "mojom/vanadium/discovery"
+	mojom "mojom/v.io/discovery"
 
 	"v.io/v23/context"
 	"v.io/v23/discovery"
diff --git a/go/src/vanadium/discovery/internal/update_test.go b/go/src/v.io/mojo/discovery/internal/update_test.go
similarity index 100%
rename from go/src/vanadium/discovery/internal/update_test.go
rename to go/src/v.io/mojo/discovery/internal/update_test.go
diff --git a/go/src/vanadium/discovery/internal/util.go b/go/src/v.io/mojo/discovery/internal/util.go
similarity index 97%
rename from go/src/vanadium/discovery/internal/util.go
rename to go/src/v.io/mojo/discovery/internal/util.go
index 785b102..b94ff67 100644
--- a/go/src/vanadium/discovery/internal/util.go
+++ b/go/src/v.io/mojo/discovery/internal/util.go
@@ -5,7 +5,7 @@
 package internal
 
 import (
-	mojom "mojom/vanadium/discovery"
+	mojom "mojom/v.io/discovery"
 
 	"v.io/v23/discovery"
 	"v.io/v23/security"
diff --git a/go/src/vanadium/discovery/internal/util_test.go b/go/src/v.io/mojo/discovery/internal/util_test.go
similarity index 100%
rename from go/src/vanadium/discovery/internal/util_test.go
rename to go/src/v.io/mojo/discovery/internal/util_test.go
diff --git a/go/src/vanadium/discovery/internal/apptest/discovery_apptest.go b/go/src/vanadium/discovery/internal/apptest/discovery_apptest.go
deleted file mode 100644
index 3c88b23..0000000
--- a/go/src/vanadium/discovery/internal/apptest/discovery_apptest.go
+++ /dev/null
@@ -1,286 +0,0 @@
-// Copyright 2016 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build mojo
-
-package apptest
-
-import (
-	"bytes"
-	"errors"
-	"fmt"
-	"log"
-	"reflect"
-	"testing"
-	"time"
-
-	"mojo/public/go/application"
-	"mojo/public/go/bindings"
-	"mojo/public/go/system"
-
-	"mojom/vanadium/discovery"
-
-	idiscovery "v.io/x/ref/lib/discovery"
-	dfactory "v.io/x/ref/lib/discovery/factory"
-	"v.io/x/ref/lib/discovery/plugins/mock"
-	_ "v.io/x/ref/runtime/factories/generic"
-	"v.io/x/ref/test"
-
-	"vanadium/discovery/internal"
-)
-
-func AppTestBasic(t *testing.T, mctx application.Context) {
-	ctx, shutdown := test.V23Init(mctx)
-	defer shutdown()
-
-	df, _ := idiscovery.NewFactory(ctx, mock.New())
-	dfactory.InjectFactory(df)
-
-	ads := []discovery.Advertisement{
-		{
-			Id:            &[internal.AdIdLen]uint8{1, 2, 3},
-			InterfaceName: "v.io/v23/a",
-			Addresses:     []string{"/h1:123/x"},
-			Attributes:    &map[string]string{"a1": "v1"},
-		},
-		{
-			InterfaceName: "v.io/v23/b",
-			Addresses:     []string{"/h1:123/y"},
-			Attributes:    &map[string]string{"b1": "v1"},
-		},
-	}
-
-	d1 := internal.NewDiscovery(ctx)
-	defer d1.Close()
-
-	var stops []func()
-	for i, ad := range ads {
-		id, closer, e1, e2 := d1.Advertise(ad, nil)
-		if e1 != nil || e2 != nil {
-			t.Fatalf("ad[%d]: failed to advertise: %v, %v", i, e1, e2)
-		}
-		if id == nil {
-			t.Errorf("ad[%d]: got nil id", i)
-			continue
-		}
-		if ad.Id == nil {
-			ads[i].Id = id
-		} else if *id != *ad.Id {
-			t.Errorf("ad[%d]: got ad id %v, but wanted %v", i, *id, *ad.Id)
-		}
-
-		stop := func() {
-			p := discovery.NewCloserProxy(*closer, bindings.GetAsyncWaiter())
-			p.Close()
-			p.Close_Proxy()
-		}
-		stops = append(stops, stop)
-	}
-
-	// Make sure none of advertisements are discoverable by the same discovery instance.
-	if err := scanAndMatch(d1, ""); err != nil {
-		t.Error(err)
-	}
-
-	// Create a new discovery instance. All advertisements should be discovered with that.
-	d2 := internal.NewDiscovery(ctx)
-	defer d2.Close()
-
-	if err := scanAndMatch(d2, `v.InterfaceName="v.io/v23/a"`, ads[0]); err != nil {
-		t.Error(err)
-	}
-
-	if err := scanAndMatch(d2, `v.InterfaceName="v.io/v23/b"`, ads[1]); err != nil {
-		t.Error(err)
-	}
-	if err := scanAndMatch(d2, ``, ads...); err != nil {
-		t.Error(err)
-	}
-
-	// Open a new scan channel and consume expected advertisements first.
-	scanCh, stop, err := scan(d2, `v.InterfaceName="v.io/v23/a"`)
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer stop()
-	update := <-scanCh
-	if !matchFound([]*discovery.Update_Proxy{update}, ads[0]) {
-		t.Errorf("unexpected scan: %v", update)
-	}
-
-	// Make sure scan returns the lost advertisement when advertising is stopped.
-	stops[0]()
-
-	update = <-scanCh
-	if !matchLost([]*discovery.Update_Proxy{update}, ads[0]) {
-		t.Errorf("unexpected scan: %v", update)
-	}
-
-	// Also it shouldn't affect the other.
-	if err := scanAndMatch(d2, `v.InterfaceName="v.io/v23/b"`, ads[1]); err != nil {
-		t.Error(err)
-	}
-
-	// Stop advertising the remaining one; Shouldn't discover any advertisements.
-	stops[1]()
-	if err := scanAndMatch(d2, ""); err != nil {
-		t.Error(err)
-	}
-}
-
-type mockScanHandler struct {
-	ch chan *discovery.Update_Proxy
-}
-
-func (h *mockScanHandler) OnUpdate(ptr discovery.Update_Pointer) error {
-	h.ch <- discovery.NewUpdateProxy(ptr, bindings.GetAsyncWaiter())
-	return nil
-}
-
-func scan(d discovery.Discovery, query string) (<-chan *discovery.Update_Proxy, func(), error) {
-	ch := make(chan *discovery.Update_Proxy)
-	handler := &mockScanHandler{ch}
-	req, ptr := discovery.CreateMessagePipeForScanHandler()
-	stub := discovery.NewScanHandlerStub(req, handler, bindings.GetAsyncWaiter())
-
-	closer, e1, e2 := d.Scan(query, ptr)
-	if e1 != nil {
-		close(ch)
-		return nil, nil, errors.New(e1.Msg)
-	}
-	if e2 != nil {
-		close(ch)
-		return nil, nil, e2
-	}
-
-	go func() {
-		for {
-			if err := stub.ServeRequest(); err != nil {
-				connErr, ok := err.(*bindings.ConnectionError)
-				if !ok || !connErr.Closed() {
-					log.Println(err)
-				}
-				break
-			}
-		}
-	}()
-
-	stop := func() {
-		p := discovery.NewCloserProxy(*closer, bindings.GetAsyncWaiter())
-		p.Close()
-		p.Close_Proxy()
-		close(ch)
-	}
-	return ch, stop, nil
-}
-
-func scanAndMatch(d discovery.Discovery, query string, wants ...discovery.Advertisement) error {
-	const timeout = 3 * time.Second
-
-	var updates []*discovery.Update_Proxy
-	for now := time.Now(); time.Since(now) < timeout; {
-		var err error
-		updates, err = doScan(d, query, len(wants))
-		if err != nil {
-			return err
-		}
-		if matchFound(updates, wants...) {
-			return nil
-		}
-	}
-	return fmt.Errorf("Match failed; got %v, but wanted %v", updates, wants)
-}
-
-func doScan(d discovery.Discovery, query string, expectedUpdates int) ([]*discovery.Update_Proxy, error) {
-	scanCh, stop, err := scan(d, query)
-	if err != nil {
-		return nil, err
-	}
-	defer stop()
-
-	updates := make([]*discovery.Update_Proxy, 0, expectedUpdates)
-	for {
-		timeout := 5 * time.Millisecond
-		if len(updates) < expectedUpdates {
-			// Increase the timeout if we do not receive enough updates
-			// to avoid flakiness in unit tests.
-			timeout = 1 * time.Second
-		}
-
-		select {
-		case update := <-scanCh:
-			updates = append(updates, update)
-		case <-time.After(timeout):
-			return updates, nil
-		}
-	}
-}
-
-func matchFound(updates []*discovery.Update_Proxy, wants ...discovery.Advertisement) bool {
-	return match(updates, false, wants...)
-}
-
-func matchLost(updates []*discovery.Update_Proxy, wants ...discovery.Advertisement) bool {
-	return match(updates, true, wants...)
-}
-
-func match(updates []*discovery.Update_Proxy, lost bool, wants ...discovery.Advertisement) bool {
-	updateMap := make(map[[internal.AdIdLen]uint8]discovery.Update)
-	for _, update := range updates {
-		defer update.Close_Proxy()
-		id, _ := update.GetId()
-		updateMap[id] = update
-	}
-
-	for _, want := range wants {
-		update := updateMap[*want.Id]
-		if update == nil {
-			return false
-		}
-		if !updateEqual(update, want) {
-			return false
-		}
-		delete(updateMap, *want.Id)
-	}
-	return len(updateMap) == 0
-}
-
-func updateEqual(update discovery.Update, ad discovery.Advertisement) bool {
-	if got, _ := update.GetId(); got != *ad.Id {
-		return false
-	}
-	if got, _ := update.GetInterfaceName(); got != ad.InterfaceName {
-		return false
-	}
-	if got, _ := update.GetAddresses(); !reflect.DeepEqual(got, ad.Addresses) {
-		return false
-	}
-	if ad.Attributes != nil {
-		for k, v := range *ad.Attributes {
-			if got, _ := update.GetAttribute(k); got != v {
-				return false
-			}
-		}
-	}
-	if ad.Attachments != nil {
-		for k, v := range *ad.Attachments {
-			h, err := update.GetAttachment(k)
-			if err != nil {
-				return false
-			}
-			defer h.Close()
-			r, got := h.ReadData(system.MOJO_READ_DATA_FLAG_NONE)
-			if r != system.MOJO_RESULT_OK {
-				return false
-			}
-			if !bytes.Equal(got, v) {
-				return false
-			}
-		}
-	}
-	if got, _ := update.GetAdvertisement(); !reflect.DeepEqual(got, ad) {
-		return false
-	}
-	return true
-}
diff --git a/java/Manifest.txt b/java/Manifest.txt
index f92559b..5a32d43 100644
--- a/java/Manifest.txt
+++ b/java/Manifest.txt
@@ -1,3 +1,2 @@
 Manifest-Version: 1.0
-Dex-Location: classes.dex
-Mojo-Class: io.v.mojo.discovery.VDiscoveryApp
+Mojo-Class: io.v.mojo.discovery.DiscoveryApp
diff --git a/java/app/build.gradle b/java/app/build.gradle
new file mode 100644
index 0000000..1a63fbf
--- /dev/null
+++ b/java/app/build.gradle
@@ -0,0 +1,76 @@
+buildscript {
+    repositories {
+        jcenter()
+    }
+
+    dependencies {
+        classpath 'com.android.tools.build:gradle:1.3.0'
+        classpath 'com.jakewharton.sdkmanager:gradle-plugin:0.12.0'
+    }
+}
+
+apply plugin: 'android-sdk-manager'
+apply plugin: 'com.android.application'
+
+android {
+    compileSdkVersion 23
+    buildToolsVersion "23.0.1"
+
+    compileOptions {
+        sourceCompatibility JavaVersion.VERSION_1_7
+        targetCompatibility JavaVersion.VERSION_1_7
+    }
+    packagingOptions {
+        exclude 'META-INF/LICENSE.txt'
+        exclude 'META-INF/NOTICE.txt'
+    }
+
+    defaultConfig {
+        applicationId "io.v.mojo.discovery"
+        minSdkVersion 23
+        targetSdkVersion 23
+        versionCode 1
+        versionName "1.0"
+        // Enabling multidex support.
+        multiDexEnabled true
+    }
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        }
+    }
+
+    sourceSets {
+        main {
+            java {
+                srcDir "$buildDir/generated-src"
+            }
+        }
+    }
+}
+
+repositories {
+    jcenter()
+}
+
+task copyMojomBindings(type: Copy) {
+    from zipTree("../../gen/mojom/v.io/discovery.mojom.srcjar")
+    into "$buildDir/generated-src"
+}
+
+android.applicationVariants.all { variant ->
+    variant.javaCompile.dependsOn copyMojomBindings
+}
+
+dependencies {
+    compile 'io.v:vanadium-android:1.11+'
+    compile 'com.android.support:multidex:1.0.0'
+
+    // Mojo system should not be included in binary.
+    provided project(':mojo:system')
+
+    compile project(':mojo:bindings')
+    compile project(':mojo:application')
+    compile project(':mojo:interfaces:application')
+}
diff --git a/java/app/proguard-rules.pro b/java/app/proguard-rules.pro
new file mode 100644
index 0000000..75fe971
--- /dev/null
+++ b/java/app/proguard-rules.pro
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /usr/local/google/home/bjornick/Android/Sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
diff --git a/java/src/main/AndroidManifest.xml b/java/app/src/main/AndroidManifest.xml
similarity index 100%
rename from java/src/main/AndroidManifest.xml
rename to java/app/src/main/AndroidManifest.xml
diff --git a/java/app/src/main/java/io/v/mojo/discovery/DiscoveryApp.java b/java/app/src/main/java/io/v/mojo/discovery/DiscoveryApp.java
new file mode 100644
index 0000000..83433d1
--- /dev/null
+++ b/java/app/src/main/java/io/v/mojo/discovery/DiscoveryApp.java
@@ -0,0 +1,84 @@
+// Copyright 2016 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package io.v.mojo.discovery;
+
+import android.content.Context;
+import android.util.Log;
+
+import org.chromium.mojo.application.ApplicationConnection;
+import org.chromium.mojo.application.ApplicationDelegate;
+import org.chromium.mojo.application.ApplicationRunner;
+import org.chromium.mojo.application.ServiceFactoryBinder;
+import org.chromium.mojo.bindings.InterfaceRequest;
+import org.chromium.mojo.system.Core;
+import org.chromium.mojo.system.MessagePipeHandle;
+import org.chromium.mojom.mojo.Shell;
+
+import io.v.android.v23.V;
+import io.v.v23.context.VContext;
+import io.v.v23.verror.VException;
+
+import io.v.impl.google.lib.discovery.FactoryUtil;
+
+/**
+ * Android mojo application providing the vanadium discovery service.
+ */
+public class DiscoveryApp implements ApplicationDelegate {
+    static final String TAG = "DiscoveryApp";
+
+    private final Core mCore;
+    private final VContext mContext;
+
+    DiscoveryApp(Core core, Context context) {
+        mCore = core;
+        mContext = V.init(context);
+    }
+
+    @Override
+    public void initialize(Shell shell, String[] args, String url) {
+        for (String arg : args) {
+            if (arg.matches("-{1,2}use-mock")) {
+                try {
+                    FactoryUtil.injectMockPlugin(mContext);
+                } catch (VException e) {
+                    Log.e(TAG, e.toString());
+                }
+                break;
+            }
+        }
+    }
+
+    @Override
+    public boolean configureIncomingConnection(ApplicationConnection applicationConnection) {
+        applicationConnection.addService(
+                new ServiceFactoryBinder<Discovery>() {
+                    @Override
+                    public void bind(InterfaceRequest<Discovery> request) {
+                        try {
+                            Discovery.MANAGER.bind(new DiscoveryImpl(mCore, mContext), request);
+                        } catch (VException e) {
+                            Log.e(TAG, e.toString());
+                            request.close();
+                        }
+                    }
+
+                    @Override
+                    public String getInterfaceName() {
+                        return Discovery.MANAGER.getName();
+                    }
+                });
+        return true;
+    }
+
+    @Override
+    public void quit() {
+        mContext.cancel();
+    }
+
+    public static void mojoMain(
+            Context context, Core core, MessagePipeHandle applicationRequestHandle) {
+        ApplicationRunner.run(new DiscoveryApp(core, context), core, applicationRequestHandle);
+    }
+}
diff --git a/java/app/src/main/java/io/v/mojo/discovery/DiscoveryImpl.java b/java/app/src/main/java/io/v/mojo/discovery/DiscoveryImpl.java
new file mode 100644
index 0000000..134ac89
--- /dev/null
+++ b/java/app/src/main/java/io/v/mojo/discovery/DiscoveryImpl.java
@@ -0,0 +1,150 @@
+// Copyright 2016 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package io.v.mojo.discovery;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.MoreExecutors;
+
+import java.util.List;
+
+import org.chromium.mojo.system.Core;
+import org.chromium.mojo.system.MojoException;
+import org.chromium.mojo.system.RunLoop;
+
+import io.v.android.v23.V;
+import io.v.v23.InputChannelCallback;
+import io.v.v23.InputChannels;
+import io.v.v23.context.VContext;
+import io.v.v23.security.BlessingPattern;
+import io.v.v23.verror.VException;
+
+class DiscoveryImpl implements Discovery {
+    private final Core mCore;
+    private final VContext mContext;
+    private final io.v.v23.discovery.Discovery mDiscovery;
+
+    DiscoveryImpl(Core core, VContext context) throws VException {
+        mCore = core;
+        mContext = context.withCancel();
+        mDiscovery = V.newDiscovery(mContext);
+    }
+
+    private static class CloserImpl implements Closer {
+        private final Core mCore;
+        private final VContext mContext;
+        private final ListenableFuture<Void> mDone;
+
+        CloserImpl(Core core, VContext context, ListenableFuture<Void> done) {
+            mCore = core;
+            mContext = context;
+            mDone = done;
+        }
+
+        @Override
+        public void close(final CloseResponse callback) {
+            // The bindings are not thread safe. We cannot call an interface
+            // or a callback in another thread automatically. So we need to
+            // them in the original thread using RunLoop.
+            final RunLoop runLoop = mCore.getCurrentRunLoop();
+
+            mContext.cancel();
+            mDone.addListener(
+                    new Runnable() {
+                        @Override
+                        public void run() {
+                            runLoop.postDelayedTask(
+                                    new Runnable() {
+                                        @Override
+                                        public void run() {
+                                            callback.call();
+                                        }
+                                    },
+                                    0);
+                        }
+                    },
+                    MoreExecutors.directExecutor());
+        }
+
+        @Override
+        public void close() {
+            mContext.cancel();
+        }
+
+        @Override
+        public void onConnectionError(MojoException e) {}
+    }
+
+    @Override
+    public void advertise(Advertisement ad, String[] visibility, AdvertiseResponse callback) {
+        try {
+            io.v.v23.discovery.Advertisement vAd = Util.m2vAd(ad);
+            List<BlessingPattern> vVisibility = Util.m2vVisibility(visibility);
+
+            VContext context = mContext.withCancel();
+            ListenableFuture<Void> done = mDiscovery.advertise(context, vAd, vVisibility);
+            callback.call(
+                    vAd.getId().toPrimitiveArray(), new CloserImpl(mCore, context, done), null);
+        } catch (VException e) {
+            callback.call(null, null, Util.v2mError(e));
+        }
+    }
+
+    @Override
+    public void scan(String query, final ScanHandler handler, final ScanResponse callback) {
+        try {
+            // The bindings are not thread safe. We cannot call an interface
+            // or a callback in another thread automatically. So we need to
+            // them in the original thread using RunLoop.
+            final RunLoop runLoop = mCore.getCurrentRunLoop();
+
+            final VContext context = mContext.withCancel();
+            ListenableFuture<Void> done =
+                    InputChannels.withCallback(
+                            mDiscovery.scan(context, query),
+                            new InputChannelCallback<io.v.v23.discovery.Update>() {
+                                @Override
+                                public ListenableFuture<Void> onNext(
+                                        final io.v.v23.discovery.Update update) {
+                                    runLoop.postDelayedTask(
+                                            new Runnable() {
+                                                @Override
+                                                public void run() {
+                                                    handler.onUpdate(
+                                                            new UpdateImpl(mCore, context, update));
+                                                }
+                                            },
+                                            0);
+                                    return null;
+                                }
+                            });
+            done.addListener(
+                    new Runnable() {
+                        @Override
+                        public void run() {
+                            runLoop.postDelayedTask(
+                                    new Runnable() {
+                                        @Override
+                                        public void run() {
+                                            handler.close();
+                                        }
+                                    },
+                                    0);
+                        }
+                    },
+                    MoreExecutors.directExecutor());
+            callback.call(new CloserImpl(mCore, context, done), null);
+        } catch (VException e) {
+            callback.call(null, Util.v2mError(e));
+        }
+    }
+
+    @Override
+    public void close() {
+        mContext.cancel();
+    }
+
+    @Override
+    public void onConnectionError(MojoException e) {}
+}
diff --git a/java/app/src/main/java/io/v/mojo/discovery/UpdateImpl.java b/java/app/src/main/java/io/v/mojo/discovery/UpdateImpl.java
new file mode 100644
index 0000000..eb96d53
--- /dev/null
+++ b/java/app/src/main/java/io/v/mojo/discovery/UpdateImpl.java
@@ -0,0 +1,111 @@
+// Copyright 2016 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package io.v.mojo.discovery;
+
+import android.util.Log;
+
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+
+import org.chromium.mojo.system.Core;
+import org.chromium.mojo.system.DataPipe;
+import org.chromium.mojo.system.DataPipe.ConsumerHandle;
+import org.chromium.mojo.system.DataPipe.ProducerHandle;
+import org.chromium.mojo.system.Pair;
+import org.chromium.mojo.system.MojoException;
+
+import io.v.v23.context.VContext;
+import io.v.v23.verror.VException;
+
+class UpdateImpl implements Update {
+    private static final DataPipe.WriteFlags WRITE_FLAG =
+            DataPipe.WriteFlags.none().setAllOrNone(true);
+
+    private final Core mCore;
+    private final VContext mContext;
+    private final io.v.v23.discovery.Update mUpdate;
+
+    UpdateImpl(Core core, VContext context, io.v.v23.discovery.Update update) {
+        mCore = core;
+        mContext = context;
+        mUpdate = update;
+    }
+
+    @Override
+    public void isLost(IsLostResponse callback) {
+        callback.call(new Boolean(mUpdate.isLost()));
+    }
+
+    @Override
+    public void getId(GetIdResponse callback) {
+        callback.call(mUpdate.getId().toPrimitiveArray());
+    }
+
+    @Override
+    public void getInterfaceName(GetInterfaceNameResponse callback) {
+        callback.call(mUpdate.getInterfaceName());
+    }
+
+    @Override
+    public void getAddresses(GetAddressesResponse callback) {
+        List<String> addresses = mUpdate.getAddresses();
+        callback.call(addresses.toArray(new String[addresses.size()]));
+    }
+
+    @Override
+    public void getAttribute(String name, GetAttributeResponse callback) {
+        callback.call(mUpdate.getAttribute(name));
+    }
+
+    @Override
+    public void getAttachment(String name, GetAttachmentResponse callback) {
+        Pair<DataPipe.ProducerHandle, DataPipe.ConsumerHandle> handles = mCore.createDataPipe(null);
+        callback.call(handles.second);
+
+        final DataPipe.ProducerHandle producer = handles.first;
+        try {
+            Futures.addCallback(
+                    mUpdate.getAttachment(mContext, name),
+                    new FutureCallback<byte[]>() {
+                        @Override
+                        public void onSuccess(byte[] attachment) {
+                            try {
+                                ByteBuffer buf = ByteBuffer.allocateDirect(attachment.length);
+                                buf.put(attachment);
+                                producer.writeData(buf, WRITE_FLAG);
+                            } catch (MojoException e) {
+                                Log.e(DiscoveryApp.TAG, e.toString());
+                            } finally {
+                                producer.close();
+                            }
+                        }
+
+                        @Override
+                        public void onFailure(Throwable t) {
+                            // TODO(jhahn): Any way to notify an error to the requester?
+                            Log.e(DiscoveryApp.TAG, t.toString());
+                            producer.close();
+                        }
+                    });
+        } catch (VException e) {
+            Log.e(DiscoveryApp.TAG, e.toString());
+            producer.close();
+        }
+    }
+
+    @Override
+    public void getAdvertisement(GetAdvertisementResponse callback) {
+        callback.call(Util.v2mAd(mUpdate.getAdvertisement()));
+    }
+
+    @Override
+    public void close() {}
+
+    @Override
+    public void onConnectionError(MojoException e) {}
+}
diff --git a/java/app/src/main/java/io/v/mojo/discovery/Util.java b/java/app/src/main/java/io/v/mojo/discovery/Util.java
new file mode 100644
index 0000000..5956513
--- /dev/null
+++ b/java/app/src/main/java/io/v/mojo/discovery/Util.java
@@ -0,0 +1,56 @@
+// Copyright 2016 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package io.v.mojo.discovery;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import io.v.v23.discovery.AdId;
+import io.v.v23.discovery.Attachments;
+import io.v.v23.discovery.Attributes;
+import io.v.v23.security.BlessingPattern;
+import io.v.v23.verror.VException;
+
+class Util {
+    static Error v2mError(VException e) {
+        Error err = new Error();
+        err.id = e.getID();
+        err.actionCode = e.getAction().getValue();
+        err.msg = e.toString();
+        return err;
+    }
+
+    static io.v.v23.discovery.Advertisement m2vAd(Advertisement ad) {
+        return new io.v.v23.discovery.Advertisement(
+                (ad.id == null) ? new AdId() : new AdId(ad.id),
+                ad.interfaceName,
+                Arrays.asList(ad.addresses),
+                (ad.attributes == null) ? new Attributes() : new Attributes(ad.attributes),
+                (ad.attachments == null) ? new Attachments() : new Attachments(ad.attachments));
+    }
+
+    static List<BlessingPattern> m2vVisibility(String[] visibility) {
+        if (visibility == null) {
+            return null;
+        }
+        List<BlessingPattern> patterns = new ArrayList<>(visibility.length);
+        for (String pattern : visibility) {
+            patterns.add(new BlessingPattern(pattern));
+        }
+        return patterns;
+    }
+
+    static Advertisement v2mAd(io.v.v23.discovery.Advertisement ad) {
+        Advertisement mAd = new Advertisement();
+        mAd.id = ad.getId().toPrimitiveArray();
+        mAd.interfaceName = ad.getInterfaceName();
+        List<String> addresses = ad.getAddresses();
+        mAd.addresses = addresses.toArray(new String[addresses.size()]);
+        mAd.attributes = ad.getAttributes();
+        mAd.attachments = ad.getAttachments();
+        return mAd;
+    }
+}
diff --git a/java/build.gradle b/java/build.gradle
index 30d92e7..efc5996 100644
--- a/java/build.gradle
+++ b/java/build.gradle
@@ -1,57 +1,61 @@
-buildscript {
-    repositories {
-        mavenCentral()
-    }
-
-    dependencies {
-        classpath 'com.android.tools.build:gradle:1.2.3'
-        classpath 'com.jakewharton.sdkmanager:gradle-plugin:0.12.0'
+allprojects {
+    plugins.withType(JavaPlugin).whenPluginAdded {
+        sourceCompatibility = 1.7
+        targetCompatibility = 1.7
     }
 }
 
-apply plugin: 'android-sdk-manager'
-apply plugin: 'com.android.application'
-apply plugin: 'wrapper'
-
-android {
-    compileSdkVersion 23
-    buildToolsVersion "23.0.1"
-
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_7
-        targetCompatibility JavaVersion.VERSION_1_7
+def build(String buildType) {
+    def check = task("check-${buildType}") << {
+        if (System.getenv('MOJO_SDK') == null) {
+            throw new GradleException('MOJO_SDK not set')
+        }
     }
-    packagingOptions {
-        exclude 'META-INF/LICENSE.txt'
-        exclude 'META-INF/NOTICE.txt'
-    }
+    def zip = task("zipMojo-${buildType}", type: Zip, dependsOn: [check, ':app:build']) {
+        destinationDir = file("${temporaryDir}/tmp")
+        archiveName = "${project.name}-${buildType}.zip"
 
-    defaultConfig {
-        applicationId "io.v.mojo.discovery"
-        minSdkVersion 22
-        targetSdkVersion 22
-        versionCode 1
-        versionName "1.0"
+        from('Manifest.txt') {
+            into('META-INF')
+            rename { fileName ->
+                fileName = 'MANIFEST.MF'
+            }
+        }
+
+        from(zipTree("${project(':app').buildDir}/outputs/apk/app-${buildType}.apk")) {
+            include 'classes*.dex'
+            include 'lib/armeabi-v7a/libv23.so'
+            into('.')
+            eachFile { file ->
+                file.path = file.name
+            }
+        }
     }
-    buildTypes {
-        release {
-            minifyEnabled false
-            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+    def gen = task("buildMojo-${buildType}", dependsOn: [zip]) << {
+        if (System.getenv('OUT_DIR') == null) {
+            throw new GradleException('OUT_DIR not set')
+        }
+
+        def dst = new File("${System.getenv('OUT_DIR')}/${project.name}.mojo")
+        dst.parentFile.mkdirs()
+        dst.withOutputStream { out ->
+            out << "#!mojo mojo:java_handler\n"
+            out << file(zip.archivePath).bytes
         }
     }
 }
-repositories {
-    mavenCentral()
-    jcenter()
+
+task buildMojo(dependsOn: build('release-unsigned'))
+task buildMojoDebug(dependsOn: build('debug'))
+
+configure(buildMojo) {
+    group = 'Mojo build'
+    description = 'Builds mojo binaries with release apk'
 }
 
-android.sourceSets.main.java.srcDirs += 'generated-src'
-
-dependencies {
-    compile 'io.v:vanadium-android:1.3'
-    compile files(System.getenv("MOJO_DIR") + "/src/out/android_Debug/gen/mojo/public/java/application.jar")
-    compile files(System.getenv("MOJO_DIR") + "/src/out/android_Debug/gen/mojo/public/interfaces/application/application_java.jar")
-    compile files(System.getenv("MOJO_DIR") + "/src/out/android_Debug/gen/mojo/public/java/bindings.jar")
-
-    provided files(System.getenv("MOJO_DIR") + "/src/out/android_Debug/gen/mojo/public/java/system.jar")
+configure(buildMojoDebug) {
+    group = 'Mojo build'
+    description = 'Builds mojo binaries with debug apk'
 }
+
+defaultTasks 'buildMojo'
diff --git a/java/generated-src/io/v/mojo/discovery/Advertisement.java b/java/generated-src/io/v/mojo/discovery/Advertisement.java
deleted file mode 100644
index e592867..0000000
--- a/java/generated-src/io/v/mojo/discovery/Advertisement.java
+++ /dev/null
@@ -1,241 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file is autogenerated by:
-//     mojo/public/tools/bindings/mojom_bindings_generator.py
-// For:
-//     mojom/vanadium/discovery.mojom
-//
-
-package io.v.mojo.discovery;
-
-public final class Advertisement extends org.chromium.mojo.bindings.Struct {
-
-    private static final int STRUCT_SIZE = 48;
-    private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(48, 0)};
-    private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
-
-    public static final int ID_LEN = (int) 16L;
-
-    public byte[] id;
-    public String interfaceName;
-    public String[] addresses;
-    public java.util.Map<String, String> attributes;
-    public java.util.Map<String, byte[]> attachments;
-
-    private Advertisement(int version) {
-        super(STRUCT_SIZE, version);
-    }
-
-    public Advertisement() {
-        this(0);
-    }
-
-    public static Advertisement deserialize(org.chromium.mojo.bindings.Message message) {
-        return decode(new org.chromium.mojo.bindings.Decoder(message));
-    }
-
-    @SuppressWarnings("unchecked")
-    public static Advertisement decode(org.chromium.mojo.bindings.Decoder decoder0) {
-        if (decoder0 == null) {
-            return null;
-        }
-        org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-        Advertisement result = new Advertisement(mainDataHeader.elementsOrVersion);
-        if (mainDataHeader.elementsOrVersion >= 0) {
-            result.id = decoder0.readBytes(8, org.chromium.mojo.bindings.BindingsHelper.ARRAY_NULLABLE, 16);
-        }
-        if (mainDataHeader.elementsOrVersion >= 0) {
-            result.interfaceName = decoder0.readString(16, false);
-        }
-        if (mainDataHeader.elementsOrVersion >= 0) {
-            org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(24, false);
-            {
-                org.chromium.mojo.bindings.DataHeader si1 = decoder1.readDataHeaderForPointerArray(org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
-                result.addresses = new String[si1.elementsOrVersion];
-                for (int i1 = 0; i1 < si1.elementsOrVersion; ++i1) {
-                    result.addresses[i1] = decoder1.readString(org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i1, false);
-                }
-            }
-        }
-        if (mainDataHeader.elementsOrVersion >= 0) {
-            org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(32, true);
-            if (decoder1 == null) {
-                result.attributes = null;
-            } else {
-                decoder1.readDataHeaderForMap();
-                String[] keys0;
-                String[] values0;
-                {
-                    org.chromium.mojo.bindings.Decoder decoder2 = decoder1.readPointer(org.chromium.mojo.bindings.DataHeader.HEADER_SIZE, false);
-                    {
-                        org.chromium.mojo.bindings.DataHeader si2 = decoder2.readDataHeaderForPointerArray(org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
-                        keys0 = new String[si2.elementsOrVersion];
-                        for (int i2 = 0; i2 < si2.elementsOrVersion; ++i2) {
-                            keys0[i2] = decoder2.readString(org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i2, false);
-                        }
-                    }
-                }
-                {
-                    org.chromium.mojo.bindings.Decoder decoder2 = decoder1.readPointer(org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE, false);
-                    {
-                        org.chromium.mojo.bindings.DataHeader si2 = decoder2.readDataHeaderForPointerArray(keys0.length);
-                        values0 = new String[si2.elementsOrVersion];
-                        for (int i2 = 0; i2 < si2.elementsOrVersion; ++i2) {
-                            values0[i2] = decoder2.readString(org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i2, false);
-                        }
-                    }
-                }
-                result.attributes = new java.util.HashMap<String, String>();
-                for (int index0 = 0; index0 < keys0.length; ++index0) {
-                    result.attributes.put(keys0[index0],  values0[index0]);
-                }
-            }
-        }
-        if (mainDataHeader.elementsOrVersion >= 0) {
-            org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(40, true);
-            if (decoder1 == null) {
-                result.attachments = null;
-            } else {
-                decoder1.readDataHeaderForMap();
-                String[] keys0;
-                byte[][] values0;
-                {
-                    org.chromium.mojo.bindings.Decoder decoder2 = decoder1.readPointer(org.chromium.mojo.bindings.DataHeader.HEADER_SIZE, false);
-                    {
-                        org.chromium.mojo.bindings.DataHeader si2 = decoder2.readDataHeaderForPointerArray(org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
-                        keys0 = new String[si2.elementsOrVersion];
-                        for (int i2 = 0; i2 < si2.elementsOrVersion; ++i2) {
-                            keys0[i2] = decoder2.readString(org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i2, false);
-                        }
-                    }
-                }
-                {
-                    org.chromium.mojo.bindings.Decoder decoder2 = decoder1.readPointer(org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE, false);
-                    {
-                        org.chromium.mojo.bindings.DataHeader si2 = decoder2.readDataHeaderForPointerArray(keys0.length);
-                        values0 = new byte[si2.elementsOrVersion][];
-                        for (int i2 = 0; i2 < si2.elementsOrVersion; ++i2) {
-                            values0[i2] = decoder2.readBytes(org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i2, org.chromium.mojo.bindings.BindingsHelper.NOTHING_NULLABLE, org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
-                        }
-                    }
-                }
-                result.attachments = new java.util.HashMap<String, byte[]>();
-                for (int index0 = 0; index0 < keys0.length; ++index0) {
-                    result.attachments.put(keys0[index0],  values0[index0]);
-                }
-            }
-        }
-        return result;
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
-        org.chromium.mojo.bindings.Encoder encoder0 = encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
-        encoder0.encode(id, 8, org.chromium.mojo.bindings.BindingsHelper.ARRAY_NULLABLE, 16);
-        encoder0.encode(interfaceName, 16, false);
-        if (addresses == null) {
-            encoder0.encodeNullPointer(24, false);
-        } else {
-            org.chromium.mojo.bindings.Encoder encoder1 = encoder0.encodePointerArray(addresses.length, 24, org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
-            for (int i0 = 0; i0 < addresses.length; ++i0) {
-                encoder1.encode(addresses[i0], org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i0, false);
-            }
-        }
-        if (attributes == null) {
-            encoder0.encodeNullPointer(32, true);
-        } else {
-            org.chromium.mojo.bindings.Encoder encoder1 = encoder0.encoderForMap(32);
-            int size0 = attributes.size();
-            String[] keys0 = new String[size0];
-            String[] values0 = new String[size0];
-            int index0 = 0;
-            for (java.util.Map.Entry<String, String> entry0 : attributes.entrySet()) {
-                keys0[index0] = entry0.getKey();
-                values0[index0] = entry0.getValue();
-                ++index0;
-            }
-            {
-                org.chromium.mojo.bindings.Encoder encoder2 = encoder1.encodePointerArray(keys0.length, org.chromium.mojo.bindings.DataHeader.HEADER_SIZE, org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
-                for (int i1 = 0; i1 < keys0.length; ++i1) {
-                    encoder2.encode(keys0[i1], org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i1, false);
-                }
-            }
-            {
-                org.chromium.mojo.bindings.Encoder encoder2 = encoder1.encodePointerArray(values0.length, org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE, org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
-                for (int i1 = 0; i1 < values0.length; ++i1) {
-                    encoder2.encode(values0[i1], org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i1, false);
-                }
-            }
-        }
-        if (attachments == null) {
-            encoder0.encodeNullPointer(40, true);
-        } else {
-            org.chromium.mojo.bindings.Encoder encoder1 = encoder0.encoderForMap(40);
-            int size0 = attachments.size();
-            String[] keys0 = new String[size0];
-            byte[][] values0 = new byte[size0][];
-            int index0 = 0;
-            for (java.util.Map.Entry<String, byte[]> entry0 : attachments.entrySet()) {
-                keys0[index0] = entry0.getKey();
-                values0[index0] = entry0.getValue();
-                ++index0;
-            }
-            {
-                org.chromium.mojo.bindings.Encoder encoder2 = encoder1.encodePointerArray(keys0.length, org.chromium.mojo.bindings.DataHeader.HEADER_SIZE, org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
-                for (int i1 = 0; i1 < keys0.length; ++i1) {
-                    encoder2.encode(keys0[i1], org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i1, false);
-                }
-            }
-            {
-                org.chromium.mojo.bindings.Encoder encoder2 = encoder1.encodePointerArray(values0.length, org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE, org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
-                for (int i1 = 0; i1 < values0.length; ++i1) {
-                    encoder2.encode(values0[i1], org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i1, org.chromium.mojo.bindings.BindingsHelper.NOTHING_NULLABLE, org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
-                }
-            }
-        }
-    }
-
-    /**
-     * @see Object#equals(Object)
-     */
-    @Override
-    public boolean equals(Object object) {
-        if (object == this)
-            return true;
-        if (object == null)
-            return false;
-        if (getClass() != object.getClass())
-            return false;
-        Advertisement other = (Advertisement) object;
-        if (!java.util.Arrays.equals(this.id, other.id))
-            return false;
-        if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.interfaceName, other.interfaceName))
-            return false;
-        if (!java.util.Arrays.deepEquals(this.addresses, other.addresses))
-            return false;
-        if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.attributes, other.attributes))
-            return false;
-        if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.attachments, other.attachments))
-            return false;
-        return true;
-    }
-
-    /**
-     * @see Object#hashCode()
-     */
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = prime + getClass().hashCode();
-        result = prime * result + java.util.Arrays.hashCode(id);
-        result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(interfaceName);
-        result = prime * result + java.util.Arrays.deepHashCode(addresses);
-        result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(attributes);
-        result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(attachments);
-        return result;
-    }
-}
-
diff --git a/java/generated-src/io/v/mojo/discovery/Closer.java b/java/generated-src/io/v/mojo/discovery/Closer.java
deleted file mode 100644
index 33d8818..0000000
--- a/java/generated-src/io/v/mojo/discovery/Closer.java
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file is autogenerated by:
-//     mojo/public/tools/bindings/mojom_bindings_generator.py
-// For:
-//     mojom/vanadium/discovery.mojom
-//
-
-package io.v.mojo.discovery;
-
-public interface Closer extends org.chromium.mojo.bindings.Interface {
-
-    public interface Proxy extends Closer, org.chromium.mojo.bindings.Interface.Proxy {
-    }
-
-    Manager<Closer, Closer.Proxy> MANAGER = Closer_Internal.MANAGER;
-
-    void close(CloseResponse callback);
-    interface CloseResponse extends org.chromium.mojo.bindings.Callbacks.Callback0 { }
-}
-
diff --git a/java/generated-src/io/v/mojo/discovery/Closer_Internal.java b/java/generated-src/io/v/mojo/discovery/Closer_Internal.java
deleted file mode 100644
index 005d2e8..0000000
--- a/java/generated-src/io/v/mojo/discovery/Closer_Internal.java
+++ /dev/null
@@ -1,290 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file is autogenerated by:
-//     mojo/public/tools/bindings/mojom_bindings_generator.py
-// For:
-//     mojom/vanadium/discovery.mojom
-//
-
-package io.v.mojo.discovery;
-
-class Closer_Internal {
-
-    public static final org.chromium.mojo.bindings.Interface.Manager<Closer, Closer.Proxy> MANAGER =
-            new org.chromium.mojo.bindings.Interface.Manager<Closer, Closer.Proxy>() {
-    
-        public int getVersion() {
-          return 0;
-        }
-    
-        public Proxy buildProxy(org.chromium.mojo.system.Core core,
-                                org.chromium.mojo.bindings.MessageReceiverWithResponder messageReceiver) {
-            return new Proxy(core, messageReceiver);
-        }
-    
-        public Stub buildStub(org.chromium.mojo.system.Core core, Closer impl) {
-            return new Stub(core, impl);
-        }
-    
-        public Closer[] buildArray(int size) {
-          return new Closer[size];
-        }
-    };
-
-    private static final int CLOSE_ORDINAL = 0;
-
-    static final class Proxy extends org.chromium.mojo.bindings.Interface.AbstractProxy implements Closer.Proxy {
-
-        Proxy(org.chromium.mojo.system.Core core,
-              org.chromium.mojo.bindings.MessageReceiverWithResponder messageReceiver) {
-            super(core, messageReceiver);
-        }
-
-        @Override
-        public void close(CloseResponse callback) {
-            CloserCloseParams _message = new CloserCloseParams();
-            getProxyHandler().getMessageReceiver().acceptWithResponder(
-                    _message.serializeWithHeader(
-                            getProxyHandler().getCore(),
-                            new org.chromium.mojo.bindings.MessageHeader(
-                                    CLOSE_ORDINAL,
-                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG,
-                                    0)),
-                    new CloserCloseResponseParamsForwardToCallback(callback));
-        }
-
-    }
-
-    static final class Stub extends org.chromium.mojo.bindings.Interface.Stub<Closer> {
-
-        Stub(org.chromium.mojo.system.Core core, Closer impl) {
-            super(core, impl);
-        }
-
-        @Override
-        public boolean accept(org.chromium.mojo.bindings.Message message) {
-            try {
-                org.chromium.mojo.bindings.ServiceMessage messageWithHeader =
-                        message.asServiceMessage();
-                org.chromium.mojo.bindings.MessageHeader header = messageWithHeader.getHeader();
-                if (!header.validateHeader(org.chromium.mojo.bindings.MessageHeader.NO_FLAG)) {
-                    return false;
-                }
-                switch(header.getType()) {
-                    case org.chromium.mojo.bindings.InterfaceControlMessagesConstants.RUN_OR_CLOSE_PIPE_MESSAGE_ID:
-                        return org.chromium.mojo.bindings.InterfaceControlMessagesHelper.handleRunOrClosePipe(
-                                Closer_Internal.MANAGER, messageWithHeader);
-                    default:
-                        return false;
-                }
-            } catch (org.chromium.mojo.bindings.DeserializationException e) {
-                System.err.println(e.toString());
-                return false;
-            }
-        }
-
-        @Override
-        public boolean acceptWithResponder(org.chromium.mojo.bindings.Message message, org.chromium.mojo.bindings.MessageReceiver receiver) {
-            try {
-                org.chromium.mojo.bindings.ServiceMessage messageWithHeader =
-                        message.asServiceMessage();
-                org.chromium.mojo.bindings.MessageHeader header = messageWithHeader.getHeader();
-                if (!header.validateHeader(org.chromium.mojo.bindings.MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG)) {
-                    return false;
-                }
-                switch(header.getType()) {
-                    case org.chromium.mojo.bindings.InterfaceControlMessagesConstants.RUN_MESSAGE_ID:
-                        return org.chromium.mojo.bindings.InterfaceControlMessagesHelper.handleRun(
-                                getCore(), Closer_Internal.MANAGER, messageWithHeader, receiver);
-                    case CLOSE_ORDINAL: {
-                        CloserCloseParams.deserialize(messageWithHeader.getPayload());
-                        getImpl().close(new CloserCloseResponseParamsProxyToResponder(getCore(), receiver, header.getRequestId()));
-                        return true;
-                    }
-                    default:
-                        return false;
-                }
-            } catch (org.chromium.mojo.bindings.DeserializationException e) {
-                System.err.println(e.toString());
-                return false;
-            }
-        }
-    }
-
-    static final class CloserCloseParams extends org.chromium.mojo.bindings.Struct {
-    
-        private static final int STRUCT_SIZE = 8;
-        private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(8, 0)};
-        private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
-    
-        private CloserCloseParams(int version) {
-            super(STRUCT_SIZE, version);
-        }
-    
-        public CloserCloseParams() {
-            this(0);
-        }
-    
-        public static CloserCloseParams deserialize(org.chromium.mojo.bindings.Message message) {
-            return decode(new org.chromium.mojo.bindings.Decoder(message));
-        }
-    
-        @SuppressWarnings("unchecked")
-        public static CloserCloseParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
-            if (decoder0 == null) {
-                return null;
-            }
-            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-            CloserCloseParams result = new CloserCloseParams(mainDataHeader.elementsOrVersion);
-            return result;
-        }
-    
-        @SuppressWarnings("unchecked")
-        @Override
-        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
-            encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
-        }
-    
-        /**
-         * @see Object#equals(Object)
-         */
-        @Override
-        public boolean equals(Object object) {
-            if (object == this)
-                return true;
-            if (object == null)
-                return false;
-            if (getClass() != object.getClass())
-                return false;
-            return true;
-        }
-    
-        /**
-         * @see Object#hashCode()
-         */
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = prime + getClass().hashCode();
-            return result;
-        }
-    }
-
-    static final class CloserCloseResponseParams extends org.chromium.mojo.bindings.Struct {
-    
-        private static final int STRUCT_SIZE = 8;
-        private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(8, 0)};
-        private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
-    
-        private CloserCloseResponseParams(int version) {
-            super(STRUCT_SIZE, version);
-        }
-    
-        public CloserCloseResponseParams() {
-            this(0);
-        }
-    
-        public static CloserCloseResponseParams deserialize(org.chromium.mojo.bindings.Message message) {
-            return decode(new org.chromium.mojo.bindings.Decoder(message));
-        }
-    
-        @SuppressWarnings("unchecked")
-        public static CloserCloseResponseParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
-            if (decoder0 == null) {
-                return null;
-            }
-            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-            CloserCloseResponseParams result = new CloserCloseResponseParams(mainDataHeader.elementsOrVersion);
-            return result;
-        }
-    
-        @SuppressWarnings("unchecked")
-        @Override
-        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
-            encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
-        }
-    
-        /**
-         * @see Object#equals(Object)
-         */
-        @Override
-        public boolean equals(Object object) {
-            if (object == this)
-                return true;
-            if (object == null)
-                return false;
-            if (getClass() != object.getClass())
-                return false;
-            return true;
-        }
-    
-        /**
-         * @see Object#hashCode()
-         */
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = prime + getClass().hashCode();
-            return result;
-        }
-    }
-
-    static class CloserCloseResponseParamsForwardToCallback extends org.chromium.mojo.bindings.SideEffectFreeCloseable
-            implements org.chromium.mojo.bindings.MessageReceiver {
-        private final Closer.CloseResponse mCallback;
-
-        CloserCloseResponseParamsForwardToCallback(Closer.CloseResponse callback) {
-            this.mCallback = callback;
-        }
-
-        @Override
-        public boolean accept(org.chromium.mojo.bindings.Message message) {
-            try {
-                org.chromium.mojo.bindings.ServiceMessage messageWithHeader =
-                        message.asServiceMessage();
-                org.chromium.mojo.bindings.MessageHeader header = messageWithHeader.getHeader();
-                if (!header.validateHeader(CLOSE_ORDINAL,
-                                           org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG)) {
-                    return false;
-                }
-                mCallback.call();
-                return true;
-            } catch (org.chromium.mojo.bindings.DeserializationException e) {
-                return false;
-            }
-        }
-    }
-
-    static class CloserCloseResponseParamsProxyToResponder implements Closer.CloseResponse {
-
-        private final org.chromium.mojo.system.Core mCore;
-        private final org.chromium.mojo.bindings.MessageReceiver mMessageReceiver;
-        private final long mRequestId;
-
-        CloserCloseResponseParamsProxyToResponder(
-                org.chromium.mojo.system.Core core,
-                org.chromium.mojo.bindings.MessageReceiver messageReceiver,
-                long requestId) {
-            mCore = core;
-            mMessageReceiver = messageReceiver;
-            mRequestId = requestId;
-        }
-
-        @Override
-        public void call() {
-            CloserCloseResponseParams _response = new CloserCloseResponseParams();
-            org.chromium.mojo.bindings.ServiceMessage _message =
-                    _response.serializeWithHeader(
-                            mCore,
-                            new org.chromium.mojo.bindings.MessageHeader(
-                                    CLOSE_ORDINAL,
-                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG,
-                                    mRequestId));
-            mMessageReceiver.accept(_message);
-        }
-    }
-
-}
-
diff --git a/java/generated-src/io/v/mojo/discovery/Discovery.java b/java/generated-src/io/v/mojo/discovery/Discovery.java
deleted file mode 100644
index 204ee07..0000000
--- a/java/generated-src/io/v/mojo/discovery/Discovery.java
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file is autogenerated by:
-//     mojo/public/tools/bindings/mojom_bindings_generator.py
-// For:
-//     mojom/vanadium/discovery.mojom
-//
-
-package io.v.mojo.discovery;
-
-public interface Discovery extends org.chromium.mojo.bindings.Interface {
-
-    public interface Proxy extends Discovery, org.chromium.mojo.bindings.Interface.Proxy {
-    }
-
-    NamedManager<Discovery, Discovery.Proxy> MANAGER = Discovery_Internal.MANAGER;
-
-    void advertise(Advertisement ad, String[] visibility, AdvertiseResponse callback);
-    interface AdvertiseResponse extends org.chromium.mojo.bindings.Callbacks.Callback3<byte[], Closer, Error> { }
-
-    void scan(String query, ScanHandler handler, ScanResponse callback);
-    interface ScanResponse extends org.chromium.mojo.bindings.Callbacks.Callback2<Closer, Error> { }
-}
-
diff --git a/java/generated-src/io/v/mojo/discovery/Discovery_Internal.java b/java/generated-src/io/v/mojo/discovery/Discovery_Internal.java
deleted file mode 100644
index 3b9d0e0..0000000
--- a/java/generated-src/io/v/mojo/discovery/Discovery_Internal.java
+++ /dev/null
@@ -1,598 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file is autogenerated by:
-//     mojo/public/tools/bindings/mojom_bindings_generator.py
-// For:
-//     mojom/vanadium/discovery.mojom
-//
-
-package io.v.mojo.discovery;
-
-class Discovery_Internal {
-
-    public static final org.chromium.mojo.bindings.Interface.NamedManager<Discovery, Discovery.Proxy> MANAGER =
-            new org.chromium.mojo.bindings.Interface.NamedManager<Discovery, Discovery.Proxy>() {
-    
-        public String getName() {
-            return "v23::discovery::Discovery";
-        }
-    
-        public int getVersion() {
-          return 0;
-        }
-    
-        public Proxy buildProxy(org.chromium.mojo.system.Core core,
-                                org.chromium.mojo.bindings.MessageReceiverWithResponder messageReceiver) {
-            return new Proxy(core, messageReceiver);
-        }
-    
-        public Stub buildStub(org.chromium.mojo.system.Core core, Discovery impl) {
-            return new Stub(core, impl);
-        }
-    
-        public Discovery[] buildArray(int size) {
-          return new Discovery[size];
-        }
-    };
-
-    private static final int ADVERTISE_ORDINAL = 0;
-    private static final int SCAN_ORDINAL = 1;
-
-    static final class Proxy extends org.chromium.mojo.bindings.Interface.AbstractProxy implements Discovery.Proxy {
-
-        Proxy(org.chromium.mojo.system.Core core,
-              org.chromium.mojo.bindings.MessageReceiverWithResponder messageReceiver) {
-            super(core, messageReceiver);
-        }
-
-        @Override
-        public void advertise(Advertisement ad, String[] visibility, AdvertiseResponse callback) {
-            DiscoveryAdvertiseParams _message = new DiscoveryAdvertiseParams();
-            _message.ad = ad;
-            _message.visibility = visibility;
-            getProxyHandler().getMessageReceiver().acceptWithResponder(
-                    _message.serializeWithHeader(
-                            getProxyHandler().getCore(),
-                            new org.chromium.mojo.bindings.MessageHeader(
-                                    ADVERTISE_ORDINAL,
-                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG,
-                                    0)),
-                    new DiscoveryAdvertiseResponseParamsForwardToCallback(callback));
-        }
-
-        @Override
-        public void scan(String query, ScanHandler handler, ScanResponse callback) {
-            DiscoveryScanParams _message = new DiscoveryScanParams();
-            _message.query = query;
-            _message.handler = handler;
-            getProxyHandler().getMessageReceiver().acceptWithResponder(
-                    _message.serializeWithHeader(
-                            getProxyHandler().getCore(),
-                            new org.chromium.mojo.bindings.MessageHeader(
-                                    SCAN_ORDINAL,
-                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG,
-                                    0)),
-                    new DiscoveryScanResponseParamsForwardToCallback(callback));
-        }
-
-    }
-
-    static final class Stub extends org.chromium.mojo.bindings.Interface.Stub<Discovery> {
-
-        Stub(org.chromium.mojo.system.Core core, Discovery impl) {
-            super(core, impl);
-        }
-
-        @Override
-        public boolean accept(org.chromium.mojo.bindings.Message message) {
-            try {
-                org.chromium.mojo.bindings.ServiceMessage messageWithHeader =
-                        message.asServiceMessage();
-                org.chromium.mojo.bindings.MessageHeader header = messageWithHeader.getHeader();
-                if (!header.validateHeader(org.chromium.mojo.bindings.MessageHeader.NO_FLAG)) {
-                    return false;
-                }
-                switch(header.getType()) {
-                    case org.chromium.mojo.bindings.InterfaceControlMessagesConstants.RUN_OR_CLOSE_PIPE_MESSAGE_ID:
-                        return org.chromium.mojo.bindings.InterfaceControlMessagesHelper.handleRunOrClosePipe(
-                                Discovery_Internal.MANAGER, messageWithHeader);
-                    default:
-                        return false;
-                }
-            } catch (org.chromium.mojo.bindings.DeserializationException e) {
-                System.err.println(e.toString());
-                return false;
-            }
-        }
-
-        @Override
-        public boolean acceptWithResponder(org.chromium.mojo.bindings.Message message, org.chromium.mojo.bindings.MessageReceiver receiver) {
-            try {
-                org.chromium.mojo.bindings.ServiceMessage messageWithHeader =
-                        message.asServiceMessage();
-                org.chromium.mojo.bindings.MessageHeader header = messageWithHeader.getHeader();
-                if (!header.validateHeader(org.chromium.mojo.bindings.MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG)) {
-                    return false;
-                }
-                switch(header.getType()) {
-                    case org.chromium.mojo.bindings.InterfaceControlMessagesConstants.RUN_MESSAGE_ID:
-                        return org.chromium.mojo.bindings.InterfaceControlMessagesHelper.handleRun(
-                                getCore(), Discovery_Internal.MANAGER, messageWithHeader, receiver);
-                    case ADVERTISE_ORDINAL: {
-                        DiscoveryAdvertiseParams data =
-                                DiscoveryAdvertiseParams.deserialize(messageWithHeader.getPayload());
-                        getImpl().advertise(data.ad, data.visibility, new DiscoveryAdvertiseResponseParamsProxyToResponder(getCore(), receiver, header.getRequestId()));
-                        return true;
-                    }
-                    case SCAN_ORDINAL: {
-                        DiscoveryScanParams data =
-                                DiscoveryScanParams.deserialize(messageWithHeader.getPayload());
-                        getImpl().scan(data.query, data.handler, new DiscoveryScanResponseParamsProxyToResponder(getCore(), receiver, header.getRequestId()));
-                        return true;
-                    }
-                    default:
-                        return false;
-                }
-            } catch (org.chromium.mojo.bindings.DeserializationException e) {
-                System.err.println(e.toString());
-                return false;
-            }
-        }
-    }
-
-    static final class DiscoveryAdvertiseParams extends org.chromium.mojo.bindings.Struct {
-    
-        private static final int STRUCT_SIZE = 24;
-        private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(24, 0)};
-        private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
-    
-        public Advertisement ad;
-        public String[] visibility;
-    
-        private DiscoveryAdvertiseParams(int version) {
-            super(STRUCT_SIZE, version);
-        }
-    
-        public DiscoveryAdvertiseParams() {
-            this(0);
-        }
-    
-        public static DiscoveryAdvertiseParams deserialize(org.chromium.mojo.bindings.Message message) {
-            return decode(new org.chromium.mojo.bindings.Decoder(message));
-        }
-    
-        @SuppressWarnings("unchecked")
-        public static DiscoveryAdvertiseParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
-            if (decoder0 == null) {
-                return null;
-            }
-            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-            DiscoveryAdvertiseParams result = new DiscoveryAdvertiseParams(mainDataHeader.elementsOrVersion);
-            if (mainDataHeader.elementsOrVersion >= 0) {
-                org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(8, false);
-                result.ad = Advertisement.decode(decoder1);
-            }
-            if (mainDataHeader.elementsOrVersion >= 0) {
-                org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(16, true);
-                if (decoder1 == null) {
-                    result.visibility = null;
-                } else {
-                    org.chromium.mojo.bindings.DataHeader si1 = decoder1.readDataHeaderForPointerArray(org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
-                    result.visibility = new String[si1.elementsOrVersion];
-                    for (int i1 = 0; i1 < si1.elementsOrVersion; ++i1) {
-                        result.visibility[i1] = decoder1.readString(org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i1, false);
-                    }
-                }
-            }
-            return result;
-        }
-    
-        @SuppressWarnings("unchecked")
-        @Override
-        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
-            org.chromium.mojo.bindings.Encoder encoder0 = encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
-            encoder0.encode(ad, 8, false);
-            if (visibility == null) {
-                encoder0.encodeNullPointer(16, true);
-            } else {
-                org.chromium.mojo.bindings.Encoder encoder1 = encoder0.encodePointerArray(visibility.length, 16, org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
-                for (int i0 = 0; i0 < visibility.length; ++i0) {
-                    encoder1.encode(visibility[i0], org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i0, false);
-                }
-            }
-        }
-    
-        /**
-         * @see Object#equals(Object)
-         */
-        @Override
-        public boolean equals(Object object) {
-            if (object == this)
-                return true;
-            if (object == null)
-                return false;
-            if (getClass() != object.getClass())
-                return false;
-            DiscoveryAdvertiseParams other = (DiscoveryAdvertiseParams) object;
-            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.ad, other.ad))
-                return false;
-            if (!java.util.Arrays.deepEquals(this.visibility, other.visibility))
-                return false;
-            return true;
-        }
-    
-        /**
-         * @see Object#hashCode()
-         */
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = prime + getClass().hashCode();
-            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(ad);
-            result = prime * result + java.util.Arrays.deepHashCode(visibility);
-            return result;
-        }
-    }
-
-    static final class DiscoveryAdvertiseResponseParams extends org.chromium.mojo.bindings.Struct {
-    
-        private static final int STRUCT_SIZE = 32;
-        private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(32, 0)};
-        private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
-    
-        public byte[] instanceId;
-        public Closer closer;
-        public Error err;
-    
-        private DiscoveryAdvertiseResponseParams(int version) {
-            super(STRUCT_SIZE, version);
-        }
-    
-        public DiscoveryAdvertiseResponseParams() {
-            this(0);
-        }
-    
-        public static DiscoveryAdvertiseResponseParams deserialize(org.chromium.mojo.bindings.Message message) {
-            return decode(new org.chromium.mojo.bindings.Decoder(message));
-        }
-    
-        @SuppressWarnings("unchecked")
-        public static DiscoveryAdvertiseResponseParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
-            if (decoder0 == null) {
-                return null;
-            }
-            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-            DiscoveryAdvertiseResponseParams result = new DiscoveryAdvertiseResponseParams(mainDataHeader.elementsOrVersion);
-            if (mainDataHeader.elementsOrVersion >= 0) {
-                result.instanceId = decoder0.readBytes(8, org.chromium.mojo.bindings.BindingsHelper.ARRAY_NULLABLE, 16);
-            }
-            if (mainDataHeader.elementsOrVersion >= 0) {
-                result.closer = decoder0.readServiceInterface(16, true, Closer.MANAGER);
-            }
-            if (mainDataHeader.elementsOrVersion >= 0) {
-                org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(24, true);
-                result.err = Error.decode(decoder1);
-            }
-            return result;
-        }
-    
-        @SuppressWarnings("unchecked")
-        @Override
-        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
-            org.chromium.mojo.bindings.Encoder encoder0 = encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
-            encoder0.encode(instanceId, 8, org.chromium.mojo.bindings.BindingsHelper.ARRAY_NULLABLE, 16);
-            encoder0.encode(closer, 16, true, Closer.MANAGER);
-            encoder0.encode(err, 24, true);
-        }
-    
-        /**
-         * @see Object#equals(Object)
-         */
-        @Override
-        public boolean equals(Object object) {
-            if (object == this)
-                return true;
-            if (object == null)
-                return false;
-            if (getClass() != object.getClass())
-                return false;
-            DiscoveryAdvertiseResponseParams other = (DiscoveryAdvertiseResponseParams) object;
-            if (!java.util.Arrays.equals(this.instanceId, other.instanceId))
-                return false;
-            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.closer, other.closer))
-                return false;
-            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.err, other.err))
-                return false;
-            return true;
-        }
-    
-        /**
-         * @see Object#hashCode()
-         */
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = prime + getClass().hashCode();
-            result = prime * result + java.util.Arrays.hashCode(instanceId);
-            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(closer);
-            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(err);
-            return result;
-        }
-    }
-
-    static class DiscoveryAdvertiseResponseParamsForwardToCallback extends org.chromium.mojo.bindings.SideEffectFreeCloseable
-            implements org.chromium.mojo.bindings.MessageReceiver {
-        private final Discovery.AdvertiseResponse mCallback;
-
-        DiscoveryAdvertiseResponseParamsForwardToCallback(Discovery.AdvertiseResponse callback) {
-            this.mCallback = callback;
-        }
-
-        @Override
-        public boolean accept(org.chromium.mojo.bindings.Message message) {
-            try {
-                org.chromium.mojo.bindings.ServiceMessage messageWithHeader =
-                        message.asServiceMessage();
-                org.chromium.mojo.bindings.MessageHeader header = messageWithHeader.getHeader();
-                if (!header.validateHeader(ADVERTISE_ORDINAL,
-                                           org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG)) {
-                    return false;
-                }
-                DiscoveryAdvertiseResponseParams response = DiscoveryAdvertiseResponseParams.deserialize(messageWithHeader.getPayload());
-                mCallback.call(response.instanceId, response.closer, response.err);
-                return true;
-            } catch (org.chromium.mojo.bindings.DeserializationException e) {
-                return false;
-            }
-        }
-    }
-
-    static class DiscoveryAdvertiseResponseParamsProxyToResponder implements Discovery.AdvertiseResponse {
-
-        private final org.chromium.mojo.system.Core mCore;
-        private final org.chromium.mojo.bindings.MessageReceiver mMessageReceiver;
-        private final long mRequestId;
-
-        DiscoveryAdvertiseResponseParamsProxyToResponder(
-                org.chromium.mojo.system.Core core,
-                org.chromium.mojo.bindings.MessageReceiver messageReceiver,
-                long requestId) {
-            mCore = core;
-            mMessageReceiver = messageReceiver;
-            mRequestId = requestId;
-        }
-
-        @Override
-        public void call(byte[] instanceId, Closer closer, Error err) {
-            DiscoveryAdvertiseResponseParams _response = new DiscoveryAdvertiseResponseParams();
-            _response.instanceId = instanceId;
-            _response.closer = closer;
-            _response.err = err;
-            org.chromium.mojo.bindings.ServiceMessage _message =
-                    _response.serializeWithHeader(
-                            mCore,
-                            new org.chromium.mojo.bindings.MessageHeader(
-                                    ADVERTISE_ORDINAL,
-                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG,
-                                    mRequestId));
-            mMessageReceiver.accept(_message);
-        }
-    }
-
-    static final class DiscoveryScanParams extends org.chromium.mojo.bindings.Struct {
-    
-        private static final int STRUCT_SIZE = 24;
-        private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(24, 0)};
-        private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
-    
-        public String query;
-        public ScanHandler handler;
-    
-        private DiscoveryScanParams(int version) {
-            super(STRUCT_SIZE, version);
-        }
-    
-        public DiscoveryScanParams() {
-            this(0);
-        }
-    
-        public static DiscoveryScanParams deserialize(org.chromium.mojo.bindings.Message message) {
-            return decode(new org.chromium.mojo.bindings.Decoder(message));
-        }
-    
-        @SuppressWarnings("unchecked")
-        public static DiscoveryScanParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
-            if (decoder0 == null) {
-                return null;
-            }
-            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-            DiscoveryScanParams result = new DiscoveryScanParams(mainDataHeader.elementsOrVersion);
-            if (mainDataHeader.elementsOrVersion >= 0) {
-                result.query = decoder0.readString(8, false);
-            }
-            if (mainDataHeader.elementsOrVersion >= 0) {
-                result.handler = decoder0.readServiceInterface(16, false, ScanHandler.MANAGER);
-            }
-            return result;
-        }
-    
-        @SuppressWarnings("unchecked")
-        @Override
-        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
-            org.chromium.mojo.bindings.Encoder encoder0 = encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
-            encoder0.encode(query, 8, false);
-            encoder0.encode(handler, 16, false, ScanHandler.MANAGER);
-        }
-    
-        /**
-         * @see Object#equals(Object)
-         */
-        @Override
-        public boolean equals(Object object) {
-            if (object == this)
-                return true;
-            if (object == null)
-                return false;
-            if (getClass() != object.getClass())
-                return false;
-            DiscoveryScanParams other = (DiscoveryScanParams) object;
-            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.query, other.query))
-                return false;
-            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.handler, other.handler))
-                return false;
-            return true;
-        }
-    
-        /**
-         * @see Object#hashCode()
-         */
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = prime + getClass().hashCode();
-            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(query);
-            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(handler);
-            return result;
-        }
-    }
-
-    static final class DiscoveryScanResponseParams extends org.chromium.mojo.bindings.Struct {
-    
-        private static final int STRUCT_SIZE = 24;
-        private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(24, 0)};
-        private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
-    
-        public Closer closer;
-        public Error err;
-    
-        private DiscoveryScanResponseParams(int version) {
-            super(STRUCT_SIZE, version);
-        }
-    
-        public DiscoveryScanResponseParams() {
-            this(0);
-        }
-    
-        public static DiscoveryScanResponseParams deserialize(org.chromium.mojo.bindings.Message message) {
-            return decode(new org.chromium.mojo.bindings.Decoder(message));
-        }
-    
-        @SuppressWarnings("unchecked")
-        public static DiscoveryScanResponseParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
-            if (decoder0 == null) {
-                return null;
-            }
-            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-            DiscoveryScanResponseParams result = new DiscoveryScanResponseParams(mainDataHeader.elementsOrVersion);
-            if (mainDataHeader.elementsOrVersion >= 0) {
-                result.closer = decoder0.readServiceInterface(8, true, Closer.MANAGER);
-            }
-            if (mainDataHeader.elementsOrVersion >= 0) {
-                org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(16, true);
-                result.err = Error.decode(decoder1);
-            }
-            return result;
-        }
-    
-        @SuppressWarnings("unchecked")
-        @Override
-        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
-            org.chromium.mojo.bindings.Encoder encoder0 = encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
-            encoder0.encode(closer, 8, true, Closer.MANAGER);
-            encoder0.encode(err, 16, true);
-        }
-    
-        /**
-         * @see Object#equals(Object)
-         */
-        @Override
-        public boolean equals(Object object) {
-            if (object == this)
-                return true;
-            if (object == null)
-                return false;
-            if (getClass() != object.getClass())
-                return false;
-            DiscoveryScanResponseParams other = (DiscoveryScanResponseParams) object;
-            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.closer, other.closer))
-                return false;
-            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.err, other.err))
-                return false;
-            return true;
-        }
-    
-        /**
-         * @see Object#hashCode()
-         */
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = prime + getClass().hashCode();
-            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(closer);
-            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(err);
-            return result;
-        }
-    }
-
-    static class DiscoveryScanResponseParamsForwardToCallback extends org.chromium.mojo.bindings.SideEffectFreeCloseable
-            implements org.chromium.mojo.bindings.MessageReceiver {
-        private final Discovery.ScanResponse mCallback;
-
-        DiscoveryScanResponseParamsForwardToCallback(Discovery.ScanResponse callback) {
-            this.mCallback = callback;
-        }
-
-        @Override
-        public boolean accept(org.chromium.mojo.bindings.Message message) {
-            try {
-                org.chromium.mojo.bindings.ServiceMessage messageWithHeader =
-                        message.asServiceMessage();
-                org.chromium.mojo.bindings.MessageHeader header = messageWithHeader.getHeader();
-                if (!header.validateHeader(SCAN_ORDINAL,
-                                           org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG)) {
-                    return false;
-                }
-                DiscoveryScanResponseParams response = DiscoveryScanResponseParams.deserialize(messageWithHeader.getPayload());
-                mCallback.call(response.closer, response.err);
-                return true;
-            } catch (org.chromium.mojo.bindings.DeserializationException e) {
-                return false;
-            }
-        }
-    }
-
-    static class DiscoveryScanResponseParamsProxyToResponder implements Discovery.ScanResponse {
-
-        private final org.chromium.mojo.system.Core mCore;
-        private final org.chromium.mojo.bindings.MessageReceiver mMessageReceiver;
-        private final long mRequestId;
-
-        DiscoveryScanResponseParamsProxyToResponder(
-                org.chromium.mojo.system.Core core,
-                org.chromium.mojo.bindings.MessageReceiver messageReceiver,
-                long requestId) {
-            mCore = core;
-            mMessageReceiver = messageReceiver;
-            mRequestId = requestId;
-        }
-
-        @Override
-        public void call(Closer closer, Error err) {
-            DiscoveryScanResponseParams _response = new DiscoveryScanResponseParams();
-            _response.closer = closer;
-            _response.err = err;
-            org.chromium.mojo.bindings.ServiceMessage _message =
-                    _response.serializeWithHeader(
-                            mCore,
-                            new org.chromium.mojo.bindings.MessageHeader(
-                                    SCAN_ORDINAL,
-                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG,
-                                    mRequestId));
-            mMessageReceiver.accept(_message);
-        }
-    }
-
-}
-
diff --git a/java/generated-src/io/v/mojo/discovery/Error.java b/java/generated-src/io/v/mojo/discovery/Error.java
deleted file mode 100644
index d13f62b..0000000
--- a/java/generated-src/io/v/mojo/discovery/Error.java
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file is autogenerated by:
-//     mojo/public/tools/bindings/mojom_bindings_generator.py
-// For:
-//     mojom/vanadium/discovery.mojom
-//
-
-package io.v.mojo.discovery;
-
-public final class Error extends org.chromium.mojo.bindings.Struct {
-
-    private static final int STRUCT_SIZE = 32;
-    private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(32, 0)};
-    private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
-
-    public String id;
-    public int actionCode;
-    public String msg;
-
-    private Error(int version) {
-        super(STRUCT_SIZE, version);
-    }
-
-    public Error() {
-        this(0);
-    }
-
-    public static Error deserialize(org.chromium.mojo.bindings.Message message) {
-        return decode(new org.chromium.mojo.bindings.Decoder(message));
-    }
-
-    @SuppressWarnings("unchecked")
-    public static Error decode(org.chromium.mojo.bindings.Decoder decoder0) {
-        if (decoder0 == null) {
-            return null;
-        }
-        org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-        Error result = new Error(mainDataHeader.elementsOrVersion);
-        if (mainDataHeader.elementsOrVersion >= 0) {
-            result.id = decoder0.readString(8, false);
-        }
-        if (mainDataHeader.elementsOrVersion >= 0) {
-            result.actionCode = decoder0.readInt(16);
-        }
-        if (mainDataHeader.elementsOrVersion >= 0) {
-            result.msg = decoder0.readString(24, false);
-        }
-        return result;
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
-        org.chromium.mojo.bindings.Encoder encoder0 = encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
-        encoder0.encode(id, 8, false);
-        encoder0.encode(actionCode, 16);
-        encoder0.encode(msg, 24, false);
-    }
-
-    /**
-     * @see Object#equals(Object)
-     */
-    @Override
-    public boolean equals(Object object) {
-        if (object == this)
-            return true;
-        if (object == null)
-            return false;
-        if (getClass() != object.getClass())
-            return false;
-        Error other = (Error) object;
-        if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.id, other.id))
-            return false;
-        if (this.actionCode != other.actionCode)
-            return false;
-        if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.msg, other.msg))
-            return false;
-        return true;
-    }
-
-    /**
-     * @see Object#hashCode()
-     */
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = prime + getClass().hashCode();
-        result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(id);
-        result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(actionCode);
-        result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(msg);
-        return result;
-    }
-}
-
diff --git a/java/generated-src/io/v/mojo/discovery/ScanHandler.java b/java/generated-src/io/v/mojo/discovery/ScanHandler.java
deleted file mode 100644
index 6513d59..0000000
--- a/java/generated-src/io/v/mojo/discovery/ScanHandler.java
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file is autogenerated by:
-//     mojo/public/tools/bindings/mojom_bindings_generator.py
-// For:
-//     mojom/vanadium/discovery.mojom
-//
-
-package io.v.mojo.discovery;
-
-public interface ScanHandler extends org.chromium.mojo.bindings.Interface {
-
-    public interface Proxy extends ScanHandler, org.chromium.mojo.bindings.Interface.Proxy {
-    }
-
-    Manager<ScanHandler, ScanHandler.Proxy> MANAGER = ScanHandler_Internal.MANAGER;
-
-    void onUpdate(Update update);
-}
-
diff --git a/java/generated-src/io/v/mojo/discovery/ScanHandler_Internal.java b/java/generated-src/io/v/mojo/discovery/ScanHandler_Internal.java
deleted file mode 100644
index f29db38..0000000
--- a/java/generated-src/io/v/mojo/discovery/ScanHandler_Internal.java
+++ /dev/null
@@ -1,184 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file is autogenerated by:
-//     mojo/public/tools/bindings/mojom_bindings_generator.py
-// For:
-//     mojom/vanadium/discovery.mojom
-//
-
-package io.v.mojo.discovery;
-
-class ScanHandler_Internal {
-
-    public static final org.chromium.mojo.bindings.Interface.Manager<ScanHandler, ScanHandler.Proxy> MANAGER =
-            new org.chromium.mojo.bindings.Interface.Manager<ScanHandler, ScanHandler.Proxy>() {
-    
-        public int getVersion() {
-          return 0;
-        }
-    
-        public Proxy buildProxy(org.chromium.mojo.system.Core core,
-                                org.chromium.mojo.bindings.MessageReceiverWithResponder messageReceiver) {
-            return new Proxy(core, messageReceiver);
-        }
-    
-        public Stub buildStub(org.chromium.mojo.system.Core core, ScanHandler impl) {
-            return new Stub(core, impl);
-        }
-    
-        public ScanHandler[] buildArray(int size) {
-          return new ScanHandler[size];
-        }
-    };
-
-    private static final int ON_UPDATE_ORDINAL = 0;
-
-    static final class Proxy extends org.chromium.mojo.bindings.Interface.AbstractProxy implements ScanHandler.Proxy {
-
-        Proxy(org.chromium.mojo.system.Core core,
-              org.chromium.mojo.bindings.MessageReceiverWithResponder messageReceiver) {
-            super(core, messageReceiver);
-        }
-
-        @Override
-        public void onUpdate(Update update) {
-            ScanHandlerOnUpdateParams _message = new ScanHandlerOnUpdateParams();
-            _message.update = update;
-            getProxyHandler().getMessageReceiver().accept(
-                    _message.serializeWithHeader(
-                            getProxyHandler().getCore(),
-                            new org.chromium.mojo.bindings.MessageHeader(ON_UPDATE_ORDINAL)));
-        }
-
-    }
-
-    static final class Stub extends org.chromium.mojo.bindings.Interface.Stub<ScanHandler> {
-
-        Stub(org.chromium.mojo.system.Core core, ScanHandler impl) {
-            super(core, impl);
-        }
-
-        @Override
-        public boolean accept(org.chromium.mojo.bindings.Message message) {
-            try {
-                org.chromium.mojo.bindings.ServiceMessage messageWithHeader =
-                        message.asServiceMessage();
-                org.chromium.mojo.bindings.MessageHeader header = messageWithHeader.getHeader();
-                if (!header.validateHeader(org.chromium.mojo.bindings.MessageHeader.NO_FLAG)) {
-                    return false;
-                }
-                switch(header.getType()) {
-                    case org.chromium.mojo.bindings.InterfaceControlMessagesConstants.RUN_OR_CLOSE_PIPE_MESSAGE_ID:
-                        return org.chromium.mojo.bindings.InterfaceControlMessagesHelper.handleRunOrClosePipe(
-                                ScanHandler_Internal.MANAGER, messageWithHeader);
-                    case ON_UPDATE_ORDINAL: {
-                        ScanHandlerOnUpdateParams data =
-                                ScanHandlerOnUpdateParams.deserialize(messageWithHeader.getPayload());
-                        getImpl().onUpdate(data.update);
-                        return true;
-                    }
-                    default:
-                        return false;
-                }
-            } catch (org.chromium.mojo.bindings.DeserializationException e) {
-                System.err.println(e.toString());
-                return false;
-            }
-        }
-
-        @Override
-        public boolean acceptWithResponder(org.chromium.mojo.bindings.Message message, org.chromium.mojo.bindings.MessageReceiver receiver) {
-            try {
-                org.chromium.mojo.bindings.ServiceMessage messageWithHeader =
-                        message.asServiceMessage();
-                org.chromium.mojo.bindings.MessageHeader header = messageWithHeader.getHeader();
-                if (!header.validateHeader(org.chromium.mojo.bindings.MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG)) {
-                    return false;
-                }
-                switch(header.getType()) {
-                    case org.chromium.mojo.bindings.InterfaceControlMessagesConstants.RUN_MESSAGE_ID:
-                        return org.chromium.mojo.bindings.InterfaceControlMessagesHelper.handleRun(
-                                getCore(), ScanHandler_Internal.MANAGER, messageWithHeader, receiver);
-                    default:
-                        return false;
-                }
-            } catch (org.chromium.mojo.bindings.DeserializationException e) {
-                System.err.println(e.toString());
-                return false;
-            }
-        }
-    }
-
-    static final class ScanHandlerOnUpdateParams extends org.chromium.mojo.bindings.Struct {
-    
-        private static final int STRUCT_SIZE = 16;
-        private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(16, 0)};
-        private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
-    
-        public Update update;
-    
-        private ScanHandlerOnUpdateParams(int version) {
-            super(STRUCT_SIZE, version);
-        }
-    
-        public ScanHandlerOnUpdateParams() {
-            this(0);
-        }
-    
-        public static ScanHandlerOnUpdateParams deserialize(org.chromium.mojo.bindings.Message message) {
-            return decode(new org.chromium.mojo.bindings.Decoder(message));
-        }
-    
-        @SuppressWarnings("unchecked")
-        public static ScanHandlerOnUpdateParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
-            if (decoder0 == null) {
-                return null;
-            }
-            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-            ScanHandlerOnUpdateParams result = new ScanHandlerOnUpdateParams(mainDataHeader.elementsOrVersion);
-            if (mainDataHeader.elementsOrVersion >= 0) {
-                result.update = decoder0.readServiceInterface(8, false, Update.MANAGER);
-            }
-            return result;
-        }
-    
-        @SuppressWarnings("unchecked")
-        @Override
-        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
-            org.chromium.mojo.bindings.Encoder encoder0 = encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
-            encoder0.encode(update, 8, false, Update.MANAGER);
-        }
-    
-        /**
-         * @see Object#equals(Object)
-         */
-        @Override
-        public boolean equals(Object object) {
-            if (object == this)
-                return true;
-            if (object == null)
-                return false;
-            if (getClass() != object.getClass())
-                return false;
-            ScanHandlerOnUpdateParams other = (ScanHandlerOnUpdateParams) object;
-            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.update, other.update))
-                return false;
-            return true;
-        }
-    
-        /**
-         * @see Object#hashCode()
-         */
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = prime + getClass().hashCode();
-            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(update);
-            return result;
-        }
-    }
-
-}
-
diff --git a/java/generated-src/io/v/mojo/discovery/Update.java b/java/generated-src/io/v/mojo/discovery/Update.java
deleted file mode 100644
index 5cde12c..0000000
--- a/java/generated-src/io/v/mojo/discovery/Update.java
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file is autogenerated by:
-//     mojo/public/tools/bindings/mojom_bindings_generator.py
-// For:
-//     mojom/vanadium/discovery.mojom
-//
-
-package io.v.mojo.discovery;
-
-public interface Update extends org.chromium.mojo.bindings.Interface {
-
-    public interface Proxy extends Update, org.chromium.mojo.bindings.Interface.Proxy {
-    }
-
-    Manager<Update, Update.Proxy> MANAGER = Update_Internal.MANAGER;
-
-    void isLost(IsLostResponse callback);
-    interface IsLostResponse extends org.chromium.mojo.bindings.Callbacks.Callback1<Boolean> { }
-
-    void getId(GetIdResponse callback);
-    interface GetIdResponse extends org.chromium.mojo.bindings.Callbacks.Callback1<byte[]> { }
-
-    void getInterfaceName(GetInterfaceNameResponse callback);
-    interface GetInterfaceNameResponse extends org.chromium.mojo.bindings.Callbacks.Callback1<String> { }
-
-    void getAddresses(GetAddressesResponse callback);
-    interface GetAddressesResponse extends org.chromium.mojo.bindings.Callbacks.Callback1<String[]> { }
-
-    void getAttribute(String name, GetAttributeResponse callback);
-    interface GetAttributeResponse extends org.chromium.mojo.bindings.Callbacks.Callback1<String> { }
-
-    void getAttachment(String name, GetAttachmentResponse callback);
-    interface GetAttachmentResponse extends org.chromium.mojo.bindings.Callbacks.Callback1<org.chromium.mojo.system.DataPipe.ConsumerHandle> { }
-
-    void getAdvertisement(GetAdvertisementResponse callback);
-    interface GetAdvertisementResponse extends org.chromium.mojo.bindings.Callbacks.Callback1<Advertisement> { }
-}
-
diff --git a/java/generated-src/io/v/mojo/discovery/Update_Internal.java b/java/generated-src/io/v/mojo/discovery/Update_Internal.java
deleted file mode 100644
index 506a9f9..0000000
--- a/java/generated-src/io/v/mojo/discovery/Update_Internal.java
+++ /dev/null
@@ -1,1566 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file is autogenerated by:
-//     mojo/public/tools/bindings/mojom_bindings_generator.py
-// For:
-//     mojom/vanadium/discovery.mojom
-//
-
-package io.v.mojo.discovery;
-
-class Update_Internal {
-
-    public static final org.chromium.mojo.bindings.Interface.Manager<Update, Update.Proxy> MANAGER =
-            new org.chromium.mojo.bindings.Interface.Manager<Update, Update.Proxy>() {
-    
-        public int getVersion() {
-          return 0;
-        }
-    
-        public Proxy buildProxy(org.chromium.mojo.system.Core core,
-                                org.chromium.mojo.bindings.MessageReceiverWithResponder messageReceiver) {
-            return new Proxy(core, messageReceiver);
-        }
-    
-        public Stub buildStub(org.chromium.mojo.system.Core core, Update impl) {
-            return new Stub(core, impl);
-        }
-    
-        public Update[] buildArray(int size) {
-          return new Update[size];
-        }
-    };
-
-    private static final int IS_LOST_ORDINAL = 0;
-    private static final int GET_ID_ORDINAL = 1;
-    private static final int GET_INTERFACE_NAME_ORDINAL = 2;
-    private static final int GET_ADDRESSES_ORDINAL = 3;
-    private static final int GET_ATTRIBUTE_ORDINAL = 4;
-    private static final int GET_ATTACHMENT_ORDINAL = 5;
-    private static final int GET_ADVERTISEMENT_ORDINAL = 6;
-
-    static final class Proxy extends org.chromium.mojo.bindings.Interface.AbstractProxy implements Update.Proxy {
-
-        Proxy(org.chromium.mojo.system.Core core,
-              org.chromium.mojo.bindings.MessageReceiverWithResponder messageReceiver) {
-            super(core, messageReceiver);
-        }
-
-        @Override
-        public void isLost(IsLostResponse callback) {
-            UpdateIsLostParams _message = new UpdateIsLostParams();
-            getProxyHandler().getMessageReceiver().acceptWithResponder(
-                    _message.serializeWithHeader(
-                            getProxyHandler().getCore(),
-                            new org.chromium.mojo.bindings.MessageHeader(
-                                    IS_LOST_ORDINAL,
-                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG,
-                                    0)),
-                    new UpdateIsLostResponseParamsForwardToCallback(callback));
-        }
-
-        @Override
-        public void getId(GetIdResponse callback) {
-            UpdateGetIdParams _message = new UpdateGetIdParams();
-            getProxyHandler().getMessageReceiver().acceptWithResponder(
-                    _message.serializeWithHeader(
-                            getProxyHandler().getCore(),
-                            new org.chromium.mojo.bindings.MessageHeader(
-                                    GET_ID_ORDINAL,
-                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG,
-                                    0)),
-                    new UpdateGetIdResponseParamsForwardToCallback(callback));
-        }
-
-        @Override
-        public void getInterfaceName(GetInterfaceNameResponse callback) {
-            UpdateGetInterfaceNameParams _message = new UpdateGetInterfaceNameParams();
-            getProxyHandler().getMessageReceiver().acceptWithResponder(
-                    _message.serializeWithHeader(
-                            getProxyHandler().getCore(),
-                            new org.chromium.mojo.bindings.MessageHeader(
-                                    GET_INTERFACE_NAME_ORDINAL,
-                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG,
-                                    0)),
-                    new UpdateGetInterfaceNameResponseParamsForwardToCallback(callback));
-        }
-
-        @Override
-        public void getAddresses(GetAddressesResponse callback) {
-            UpdateGetAddressesParams _message = new UpdateGetAddressesParams();
-            getProxyHandler().getMessageReceiver().acceptWithResponder(
-                    _message.serializeWithHeader(
-                            getProxyHandler().getCore(),
-                            new org.chromium.mojo.bindings.MessageHeader(
-                                    GET_ADDRESSES_ORDINAL,
-                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG,
-                                    0)),
-                    new UpdateGetAddressesResponseParamsForwardToCallback(callback));
-        }
-
-        @Override
-        public void getAttribute(String name, GetAttributeResponse callback) {
-            UpdateGetAttributeParams _message = new UpdateGetAttributeParams();
-            _message.name = name;
-            getProxyHandler().getMessageReceiver().acceptWithResponder(
-                    _message.serializeWithHeader(
-                            getProxyHandler().getCore(),
-                            new org.chromium.mojo.bindings.MessageHeader(
-                                    GET_ATTRIBUTE_ORDINAL,
-                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG,
-                                    0)),
-                    new UpdateGetAttributeResponseParamsForwardToCallback(callback));
-        }
-
-        @Override
-        public void getAttachment(String name, GetAttachmentResponse callback) {
-            UpdateGetAttachmentParams _message = new UpdateGetAttachmentParams();
-            _message.name = name;
-            getProxyHandler().getMessageReceiver().acceptWithResponder(
-                    _message.serializeWithHeader(
-                            getProxyHandler().getCore(),
-                            new org.chromium.mojo.bindings.MessageHeader(
-                                    GET_ATTACHMENT_ORDINAL,
-                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG,
-                                    0)),
-                    new UpdateGetAttachmentResponseParamsForwardToCallback(callback));
-        }
-
-        @Override
-        public void getAdvertisement(GetAdvertisementResponse callback) {
-            UpdateGetAdvertisementParams _message = new UpdateGetAdvertisementParams();
-            getProxyHandler().getMessageReceiver().acceptWithResponder(
-                    _message.serializeWithHeader(
-                            getProxyHandler().getCore(),
-                            new org.chromium.mojo.bindings.MessageHeader(
-                                    GET_ADVERTISEMENT_ORDINAL,
-                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG,
-                                    0)),
-                    new UpdateGetAdvertisementResponseParamsForwardToCallback(callback));
-        }
-
-    }
-
-    static final class Stub extends org.chromium.mojo.bindings.Interface.Stub<Update> {
-
-        Stub(org.chromium.mojo.system.Core core, Update impl) {
-            super(core, impl);
-        }
-
-        @Override
-        public boolean accept(org.chromium.mojo.bindings.Message message) {
-            try {
-                org.chromium.mojo.bindings.ServiceMessage messageWithHeader =
-                        message.asServiceMessage();
-                org.chromium.mojo.bindings.MessageHeader header = messageWithHeader.getHeader();
-                if (!header.validateHeader(org.chromium.mojo.bindings.MessageHeader.NO_FLAG)) {
-                    return false;
-                }
-                switch(header.getType()) {
-                    case org.chromium.mojo.bindings.InterfaceControlMessagesConstants.RUN_OR_CLOSE_PIPE_MESSAGE_ID:
-                        return org.chromium.mojo.bindings.InterfaceControlMessagesHelper.handleRunOrClosePipe(
-                                Update_Internal.MANAGER, messageWithHeader);
-                    default:
-                        return false;
-                }
-            } catch (org.chromium.mojo.bindings.DeserializationException e) {
-                System.err.println(e.toString());
-                return false;
-            }
-        }
-
-        @Override
-        public boolean acceptWithResponder(org.chromium.mojo.bindings.Message message, org.chromium.mojo.bindings.MessageReceiver receiver) {
-            try {
-                org.chromium.mojo.bindings.ServiceMessage messageWithHeader =
-                        message.asServiceMessage();
-                org.chromium.mojo.bindings.MessageHeader header = messageWithHeader.getHeader();
-                if (!header.validateHeader(org.chromium.mojo.bindings.MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG)) {
-                    return false;
-                }
-                switch(header.getType()) {
-                    case org.chromium.mojo.bindings.InterfaceControlMessagesConstants.RUN_MESSAGE_ID:
-                        return org.chromium.mojo.bindings.InterfaceControlMessagesHelper.handleRun(
-                                getCore(), Update_Internal.MANAGER, messageWithHeader, receiver);
-                    case IS_LOST_ORDINAL: {
-                        UpdateIsLostParams.deserialize(messageWithHeader.getPayload());
-                        getImpl().isLost(new UpdateIsLostResponseParamsProxyToResponder(getCore(), receiver, header.getRequestId()));
-                        return true;
-                    }
-                    case GET_ID_ORDINAL: {
-                        UpdateGetIdParams.deserialize(messageWithHeader.getPayload());
-                        getImpl().getId(new UpdateGetIdResponseParamsProxyToResponder(getCore(), receiver, header.getRequestId()));
-                        return true;
-                    }
-                    case GET_INTERFACE_NAME_ORDINAL: {
-                        UpdateGetInterfaceNameParams.deserialize(messageWithHeader.getPayload());
-                        getImpl().getInterfaceName(new UpdateGetInterfaceNameResponseParamsProxyToResponder(getCore(), receiver, header.getRequestId()));
-                        return true;
-                    }
-                    case GET_ADDRESSES_ORDINAL: {
-                        UpdateGetAddressesParams.deserialize(messageWithHeader.getPayload());
-                        getImpl().getAddresses(new UpdateGetAddressesResponseParamsProxyToResponder(getCore(), receiver, header.getRequestId()));
-                        return true;
-                    }
-                    case GET_ATTRIBUTE_ORDINAL: {
-                        UpdateGetAttributeParams data =
-                                UpdateGetAttributeParams.deserialize(messageWithHeader.getPayload());
-                        getImpl().getAttribute(data.name, new UpdateGetAttributeResponseParamsProxyToResponder(getCore(), receiver, header.getRequestId()));
-                        return true;
-                    }
-                    case GET_ATTACHMENT_ORDINAL: {
-                        UpdateGetAttachmentParams data =
-                                UpdateGetAttachmentParams.deserialize(messageWithHeader.getPayload());
-                        getImpl().getAttachment(data.name, new UpdateGetAttachmentResponseParamsProxyToResponder(getCore(), receiver, header.getRequestId()));
-                        return true;
-                    }
-                    case GET_ADVERTISEMENT_ORDINAL: {
-                        UpdateGetAdvertisementParams.deserialize(messageWithHeader.getPayload());
-                        getImpl().getAdvertisement(new UpdateGetAdvertisementResponseParamsProxyToResponder(getCore(), receiver, header.getRequestId()));
-                        return true;
-                    }
-                    default:
-                        return false;
-                }
-            } catch (org.chromium.mojo.bindings.DeserializationException e) {
-                System.err.println(e.toString());
-                return false;
-            }
-        }
-    }
-
-    static final class UpdateIsLostParams extends org.chromium.mojo.bindings.Struct {
-    
-        private static final int STRUCT_SIZE = 8;
-        private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(8, 0)};
-        private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
-    
-        private UpdateIsLostParams(int version) {
-            super(STRUCT_SIZE, version);
-        }
-    
-        public UpdateIsLostParams() {
-            this(0);
-        }
-    
-        public static UpdateIsLostParams deserialize(org.chromium.mojo.bindings.Message message) {
-            return decode(new org.chromium.mojo.bindings.Decoder(message));
-        }
-    
-        @SuppressWarnings("unchecked")
-        public static UpdateIsLostParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
-            if (decoder0 == null) {
-                return null;
-            }
-            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-            UpdateIsLostParams result = new UpdateIsLostParams(mainDataHeader.elementsOrVersion);
-            return result;
-        }
-    
-        @SuppressWarnings("unchecked")
-        @Override
-        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
-            encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
-        }
-    
-        /**
-         * @see Object#equals(Object)
-         */
-        @Override
-        public boolean equals(Object object) {
-            if (object == this)
-                return true;
-            if (object == null)
-                return false;
-            if (getClass() != object.getClass())
-                return false;
-            return true;
-        }
-    
-        /**
-         * @see Object#hashCode()
-         */
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = prime + getClass().hashCode();
-            return result;
-        }
-    }
-
-    static final class UpdateIsLostResponseParams extends org.chromium.mojo.bindings.Struct {
-    
-        private static final int STRUCT_SIZE = 16;
-        private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(16, 0)};
-        private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
-    
-        public boolean lost;
-    
-        private UpdateIsLostResponseParams(int version) {
-            super(STRUCT_SIZE, version);
-        }
-    
-        public UpdateIsLostResponseParams() {
-            this(0);
-        }
-    
-        public static UpdateIsLostResponseParams deserialize(org.chromium.mojo.bindings.Message message) {
-            return decode(new org.chromium.mojo.bindings.Decoder(message));
-        }
-    
-        @SuppressWarnings("unchecked")
-        public static UpdateIsLostResponseParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
-            if (decoder0 == null) {
-                return null;
-            }
-            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-            UpdateIsLostResponseParams result = new UpdateIsLostResponseParams(mainDataHeader.elementsOrVersion);
-            if (mainDataHeader.elementsOrVersion >= 0) {
-                result.lost = decoder0.readBoolean(8, 0);
-            }
-            return result;
-        }
-    
-        @SuppressWarnings("unchecked")
-        @Override
-        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
-            org.chromium.mojo.bindings.Encoder encoder0 = encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
-            encoder0.encode(lost, 8, 0);
-        }
-    
-        /**
-         * @see Object#equals(Object)
-         */
-        @Override
-        public boolean equals(Object object) {
-            if (object == this)
-                return true;
-            if (object == null)
-                return false;
-            if (getClass() != object.getClass())
-                return false;
-            UpdateIsLostResponseParams other = (UpdateIsLostResponseParams) object;
-            if (this.lost != other.lost)
-                return false;
-            return true;
-        }
-    
-        /**
-         * @see Object#hashCode()
-         */
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = prime + getClass().hashCode();
-            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(lost);
-            return result;
-        }
-    }
-
-    static class UpdateIsLostResponseParamsForwardToCallback extends org.chromium.mojo.bindings.SideEffectFreeCloseable
-            implements org.chromium.mojo.bindings.MessageReceiver {
-        private final Update.IsLostResponse mCallback;
-
-        UpdateIsLostResponseParamsForwardToCallback(Update.IsLostResponse callback) {
-            this.mCallback = callback;
-        }
-
-        @Override
-        public boolean accept(org.chromium.mojo.bindings.Message message) {
-            try {
-                org.chromium.mojo.bindings.ServiceMessage messageWithHeader =
-                        message.asServiceMessage();
-                org.chromium.mojo.bindings.MessageHeader header = messageWithHeader.getHeader();
-                if (!header.validateHeader(IS_LOST_ORDINAL,
-                                           org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG)) {
-                    return false;
-                }
-                UpdateIsLostResponseParams response = UpdateIsLostResponseParams.deserialize(messageWithHeader.getPayload());
-                mCallback.call(response.lost);
-                return true;
-            } catch (org.chromium.mojo.bindings.DeserializationException e) {
-                return false;
-            }
-        }
-    }
-
-    static class UpdateIsLostResponseParamsProxyToResponder implements Update.IsLostResponse {
-
-        private final org.chromium.mojo.system.Core mCore;
-        private final org.chromium.mojo.bindings.MessageReceiver mMessageReceiver;
-        private final long mRequestId;
-
-        UpdateIsLostResponseParamsProxyToResponder(
-                org.chromium.mojo.system.Core core,
-                org.chromium.mojo.bindings.MessageReceiver messageReceiver,
-                long requestId) {
-            mCore = core;
-            mMessageReceiver = messageReceiver;
-            mRequestId = requestId;
-        }
-
-        @Override
-        public void call(Boolean lost) {
-            UpdateIsLostResponseParams _response = new UpdateIsLostResponseParams();
-            _response.lost = lost;
-            org.chromium.mojo.bindings.ServiceMessage _message =
-                    _response.serializeWithHeader(
-                            mCore,
-                            new org.chromium.mojo.bindings.MessageHeader(
-                                    IS_LOST_ORDINAL,
-                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG,
-                                    mRequestId));
-            mMessageReceiver.accept(_message);
-        }
-    }
-
-    static final class UpdateGetIdParams extends org.chromium.mojo.bindings.Struct {
-    
-        private static final int STRUCT_SIZE = 8;
-        private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(8, 0)};
-        private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
-    
-        private UpdateGetIdParams(int version) {
-            super(STRUCT_SIZE, version);
-        }
-    
-        public UpdateGetIdParams() {
-            this(0);
-        }
-    
-        public static UpdateGetIdParams deserialize(org.chromium.mojo.bindings.Message message) {
-            return decode(new org.chromium.mojo.bindings.Decoder(message));
-        }
-    
-        @SuppressWarnings("unchecked")
-        public static UpdateGetIdParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
-            if (decoder0 == null) {
-                return null;
-            }
-            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-            UpdateGetIdParams result = new UpdateGetIdParams(mainDataHeader.elementsOrVersion);
-            return result;
-        }
-    
-        @SuppressWarnings("unchecked")
-        @Override
-        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
-            encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
-        }
-    
-        /**
-         * @see Object#equals(Object)
-         */
-        @Override
-        public boolean equals(Object object) {
-            if (object == this)
-                return true;
-            if (object == null)
-                return false;
-            if (getClass() != object.getClass())
-                return false;
-            return true;
-        }
-    
-        /**
-         * @see Object#hashCode()
-         */
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = prime + getClass().hashCode();
-            return result;
-        }
-    }
-
-    static final class UpdateGetIdResponseParams extends org.chromium.mojo.bindings.Struct {
-    
-        private static final int STRUCT_SIZE = 16;
-        private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(16, 0)};
-        private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
-    
-        public byte[] id;
-    
-        private UpdateGetIdResponseParams(int version) {
-            super(STRUCT_SIZE, version);
-        }
-    
-        public UpdateGetIdResponseParams() {
-            this(0);
-        }
-    
-        public static UpdateGetIdResponseParams deserialize(org.chromium.mojo.bindings.Message message) {
-            return decode(new org.chromium.mojo.bindings.Decoder(message));
-        }
-    
-        @SuppressWarnings("unchecked")
-        public static UpdateGetIdResponseParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
-            if (decoder0 == null) {
-                return null;
-            }
-            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-            UpdateGetIdResponseParams result = new UpdateGetIdResponseParams(mainDataHeader.elementsOrVersion);
-            if (mainDataHeader.elementsOrVersion >= 0) {
-                result.id = decoder0.readBytes(8, org.chromium.mojo.bindings.BindingsHelper.NOTHING_NULLABLE, 16);
-            }
-            return result;
-        }
-    
-        @SuppressWarnings("unchecked")
-        @Override
-        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
-            org.chromium.mojo.bindings.Encoder encoder0 = encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
-            encoder0.encode(id, 8, org.chromium.mojo.bindings.BindingsHelper.NOTHING_NULLABLE, 16);
-        }
-    
-        /**
-         * @see Object#equals(Object)
-         */
-        @Override
-        public boolean equals(Object object) {
-            if (object == this)
-                return true;
-            if (object == null)
-                return false;
-            if (getClass() != object.getClass())
-                return false;
-            UpdateGetIdResponseParams other = (UpdateGetIdResponseParams) object;
-            if (!java.util.Arrays.equals(this.id, other.id))
-                return false;
-            return true;
-        }
-    
-        /**
-         * @see Object#hashCode()
-         */
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = prime + getClass().hashCode();
-            result = prime * result + java.util.Arrays.hashCode(id);
-            return result;
-        }
-    }
-
-    static class UpdateGetIdResponseParamsForwardToCallback extends org.chromium.mojo.bindings.SideEffectFreeCloseable
-            implements org.chromium.mojo.bindings.MessageReceiver {
-        private final Update.GetIdResponse mCallback;
-
-        UpdateGetIdResponseParamsForwardToCallback(Update.GetIdResponse callback) {
-            this.mCallback = callback;
-        }
-
-        @Override
-        public boolean accept(org.chromium.mojo.bindings.Message message) {
-            try {
-                org.chromium.mojo.bindings.ServiceMessage messageWithHeader =
-                        message.asServiceMessage();
-                org.chromium.mojo.bindings.MessageHeader header = messageWithHeader.getHeader();
-                if (!header.validateHeader(GET_ID_ORDINAL,
-                                           org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG)) {
-                    return false;
-                }
-                UpdateGetIdResponseParams response = UpdateGetIdResponseParams.deserialize(messageWithHeader.getPayload());
-                mCallback.call(response.id);
-                return true;
-            } catch (org.chromium.mojo.bindings.DeserializationException e) {
-                return false;
-            }
-        }
-    }
-
-    static class UpdateGetIdResponseParamsProxyToResponder implements Update.GetIdResponse {
-
-        private final org.chromium.mojo.system.Core mCore;
-        private final org.chromium.mojo.bindings.MessageReceiver mMessageReceiver;
-        private final long mRequestId;
-
-        UpdateGetIdResponseParamsProxyToResponder(
-                org.chromium.mojo.system.Core core,
-                org.chromium.mojo.bindings.MessageReceiver messageReceiver,
-                long requestId) {
-            mCore = core;
-            mMessageReceiver = messageReceiver;
-            mRequestId = requestId;
-        }
-
-        @Override
-        public void call(byte[] id) {
-            UpdateGetIdResponseParams _response = new UpdateGetIdResponseParams();
-            _response.id = id;
-            org.chromium.mojo.bindings.ServiceMessage _message =
-                    _response.serializeWithHeader(
-                            mCore,
-                            new org.chromium.mojo.bindings.MessageHeader(
-                                    GET_ID_ORDINAL,
-                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG,
-                                    mRequestId));
-            mMessageReceiver.accept(_message);
-        }
-    }
-
-    static final class UpdateGetInterfaceNameParams extends org.chromium.mojo.bindings.Struct {
-    
-        private static final int STRUCT_SIZE = 8;
-        private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(8, 0)};
-        private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
-    
-        private UpdateGetInterfaceNameParams(int version) {
-            super(STRUCT_SIZE, version);
-        }
-    
-        public UpdateGetInterfaceNameParams() {
-            this(0);
-        }
-    
-        public static UpdateGetInterfaceNameParams deserialize(org.chromium.mojo.bindings.Message message) {
-            return decode(new org.chromium.mojo.bindings.Decoder(message));
-        }
-    
-        @SuppressWarnings("unchecked")
-        public static UpdateGetInterfaceNameParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
-            if (decoder0 == null) {
-                return null;
-            }
-            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-            UpdateGetInterfaceNameParams result = new UpdateGetInterfaceNameParams(mainDataHeader.elementsOrVersion);
-            return result;
-        }
-    
-        @SuppressWarnings("unchecked")
-        @Override
-        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
-            encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
-        }
-    
-        /**
-         * @see Object#equals(Object)
-         */
-        @Override
-        public boolean equals(Object object) {
-            if (object == this)
-                return true;
-            if (object == null)
-                return false;
-            if (getClass() != object.getClass())
-                return false;
-            return true;
-        }
-    
-        /**
-         * @see Object#hashCode()
-         */
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = prime + getClass().hashCode();
-            return result;
-        }
-    }
-
-    static final class UpdateGetInterfaceNameResponseParams extends org.chromium.mojo.bindings.Struct {
-    
-        private static final int STRUCT_SIZE = 16;
-        private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(16, 0)};
-        private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
-    
-        public String interfaceName;
-    
-        private UpdateGetInterfaceNameResponseParams(int version) {
-            super(STRUCT_SIZE, version);
-        }
-    
-        public UpdateGetInterfaceNameResponseParams() {
-            this(0);
-        }
-    
-        public static UpdateGetInterfaceNameResponseParams deserialize(org.chromium.mojo.bindings.Message message) {
-            return decode(new org.chromium.mojo.bindings.Decoder(message));
-        }
-    
-        @SuppressWarnings("unchecked")
-        public static UpdateGetInterfaceNameResponseParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
-            if (decoder0 == null) {
-                return null;
-            }
-            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-            UpdateGetInterfaceNameResponseParams result = new UpdateGetInterfaceNameResponseParams(mainDataHeader.elementsOrVersion);
-            if (mainDataHeader.elementsOrVersion >= 0) {
-                result.interfaceName = decoder0.readString(8, false);
-            }
-            return result;
-        }
-    
-        @SuppressWarnings("unchecked")
-        @Override
-        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
-            org.chromium.mojo.bindings.Encoder encoder0 = encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
-            encoder0.encode(interfaceName, 8, false);
-        }
-    
-        /**
-         * @see Object#equals(Object)
-         */
-        @Override
-        public boolean equals(Object object) {
-            if (object == this)
-                return true;
-            if (object == null)
-                return false;
-            if (getClass() != object.getClass())
-                return false;
-            UpdateGetInterfaceNameResponseParams other = (UpdateGetInterfaceNameResponseParams) object;
-            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.interfaceName, other.interfaceName))
-                return false;
-            return true;
-        }
-    
-        /**
-         * @see Object#hashCode()
-         */
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = prime + getClass().hashCode();
-            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(interfaceName);
-            return result;
-        }
-    }
-
-    static class UpdateGetInterfaceNameResponseParamsForwardToCallback extends org.chromium.mojo.bindings.SideEffectFreeCloseable
-            implements org.chromium.mojo.bindings.MessageReceiver {
-        private final Update.GetInterfaceNameResponse mCallback;
-
-        UpdateGetInterfaceNameResponseParamsForwardToCallback(Update.GetInterfaceNameResponse callback) {
-            this.mCallback = callback;
-        }
-
-        @Override
-        public boolean accept(org.chromium.mojo.bindings.Message message) {
-            try {
-                org.chromium.mojo.bindings.ServiceMessage messageWithHeader =
-                        message.asServiceMessage();
-                org.chromium.mojo.bindings.MessageHeader header = messageWithHeader.getHeader();
-                if (!header.validateHeader(GET_INTERFACE_NAME_ORDINAL,
-                                           org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG)) {
-                    return false;
-                }
-                UpdateGetInterfaceNameResponseParams response = UpdateGetInterfaceNameResponseParams.deserialize(messageWithHeader.getPayload());
-                mCallback.call(response.interfaceName);
-                return true;
-            } catch (org.chromium.mojo.bindings.DeserializationException e) {
-                return false;
-            }
-        }
-    }
-
-    static class UpdateGetInterfaceNameResponseParamsProxyToResponder implements Update.GetInterfaceNameResponse {
-
-        private final org.chromium.mojo.system.Core mCore;
-        private final org.chromium.mojo.bindings.MessageReceiver mMessageReceiver;
-        private final long mRequestId;
-
-        UpdateGetInterfaceNameResponseParamsProxyToResponder(
-                org.chromium.mojo.system.Core core,
-                org.chromium.mojo.bindings.MessageReceiver messageReceiver,
-                long requestId) {
-            mCore = core;
-            mMessageReceiver = messageReceiver;
-            mRequestId = requestId;
-        }
-
-        @Override
-        public void call(String interfaceName) {
-            UpdateGetInterfaceNameResponseParams _response = new UpdateGetInterfaceNameResponseParams();
-            _response.interfaceName = interfaceName;
-            org.chromium.mojo.bindings.ServiceMessage _message =
-                    _response.serializeWithHeader(
-                            mCore,
-                            new org.chromium.mojo.bindings.MessageHeader(
-                                    GET_INTERFACE_NAME_ORDINAL,
-                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG,
-                                    mRequestId));
-            mMessageReceiver.accept(_message);
-        }
-    }
-
-    static final class UpdateGetAddressesParams extends org.chromium.mojo.bindings.Struct {
-    
-        private static final int STRUCT_SIZE = 8;
-        private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(8, 0)};
-        private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
-    
-        private UpdateGetAddressesParams(int version) {
-            super(STRUCT_SIZE, version);
-        }
-    
-        public UpdateGetAddressesParams() {
-            this(0);
-        }
-    
-        public static UpdateGetAddressesParams deserialize(org.chromium.mojo.bindings.Message message) {
-            return decode(new org.chromium.mojo.bindings.Decoder(message));
-        }
-    
-        @SuppressWarnings("unchecked")
-        public static UpdateGetAddressesParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
-            if (decoder0 == null) {
-                return null;
-            }
-            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-            UpdateGetAddressesParams result = new UpdateGetAddressesParams(mainDataHeader.elementsOrVersion);
-            return result;
-        }
-    
-        @SuppressWarnings("unchecked")
-        @Override
-        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
-            encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
-        }
-    
-        /**
-         * @see Object#equals(Object)
-         */
-        @Override
-        public boolean equals(Object object) {
-            if (object == this)
-                return true;
-            if (object == null)
-                return false;
-            if (getClass() != object.getClass())
-                return false;
-            return true;
-        }
-    
-        /**
-         * @see Object#hashCode()
-         */
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = prime + getClass().hashCode();
-            return result;
-        }
-    }
-
-    static final class UpdateGetAddressesResponseParams extends org.chromium.mojo.bindings.Struct {
-    
-        private static final int STRUCT_SIZE = 16;
-        private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(16, 0)};
-        private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
-    
-        public String[] addresses;
-    
-        private UpdateGetAddressesResponseParams(int version) {
-            super(STRUCT_SIZE, version);
-        }
-    
-        public UpdateGetAddressesResponseParams() {
-            this(0);
-        }
-    
-        public static UpdateGetAddressesResponseParams deserialize(org.chromium.mojo.bindings.Message message) {
-            return decode(new org.chromium.mojo.bindings.Decoder(message));
-        }
-    
-        @SuppressWarnings("unchecked")
-        public static UpdateGetAddressesResponseParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
-            if (decoder0 == null) {
-                return null;
-            }
-            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-            UpdateGetAddressesResponseParams result = new UpdateGetAddressesResponseParams(mainDataHeader.elementsOrVersion);
-            if (mainDataHeader.elementsOrVersion >= 0) {
-                org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(8, false);
-                {
-                    org.chromium.mojo.bindings.DataHeader si1 = decoder1.readDataHeaderForPointerArray(org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
-                    result.addresses = new String[si1.elementsOrVersion];
-                    for (int i1 = 0; i1 < si1.elementsOrVersion; ++i1) {
-                        result.addresses[i1] = decoder1.readString(org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i1, false);
-                    }
-                }
-            }
-            return result;
-        }
-    
-        @SuppressWarnings("unchecked")
-        @Override
-        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
-            org.chromium.mojo.bindings.Encoder encoder0 = encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
-            if (addresses == null) {
-                encoder0.encodeNullPointer(8, false);
-            } else {
-                org.chromium.mojo.bindings.Encoder encoder1 = encoder0.encodePointerArray(addresses.length, 8, org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
-                for (int i0 = 0; i0 < addresses.length; ++i0) {
-                    encoder1.encode(addresses[i0], org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i0, false);
-                }
-            }
-        }
-    
-        /**
-         * @see Object#equals(Object)
-         */
-        @Override
-        public boolean equals(Object object) {
-            if (object == this)
-                return true;
-            if (object == null)
-                return false;
-            if (getClass() != object.getClass())
-                return false;
-            UpdateGetAddressesResponseParams other = (UpdateGetAddressesResponseParams) object;
-            if (!java.util.Arrays.deepEquals(this.addresses, other.addresses))
-                return false;
-            return true;
-        }
-    
-        /**
-         * @see Object#hashCode()
-         */
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = prime + getClass().hashCode();
-            result = prime * result + java.util.Arrays.deepHashCode(addresses);
-            return result;
-        }
-    }
-
-    static class UpdateGetAddressesResponseParamsForwardToCallback extends org.chromium.mojo.bindings.SideEffectFreeCloseable
-            implements org.chromium.mojo.bindings.MessageReceiver {
-        private final Update.GetAddressesResponse mCallback;
-
-        UpdateGetAddressesResponseParamsForwardToCallback(Update.GetAddressesResponse callback) {
-            this.mCallback = callback;
-        }
-
-        @Override
-        public boolean accept(org.chromium.mojo.bindings.Message message) {
-            try {
-                org.chromium.mojo.bindings.ServiceMessage messageWithHeader =
-                        message.asServiceMessage();
-                org.chromium.mojo.bindings.MessageHeader header = messageWithHeader.getHeader();
-                if (!header.validateHeader(GET_ADDRESSES_ORDINAL,
-                                           org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG)) {
-                    return false;
-                }
-                UpdateGetAddressesResponseParams response = UpdateGetAddressesResponseParams.deserialize(messageWithHeader.getPayload());
-                mCallback.call(response.addresses);
-                return true;
-            } catch (org.chromium.mojo.bindings.DeserializationException e) {
-                return false;
-            }
-        }
-    }
-
-    static class UpdateGetAddressesResponseParamsProxyToResponder implements Update.GetAddressesResponse {
-
-        private final org.chromium.mojo.system.Core mCore;
-        private final org.chromium.mojo.bindings.MessageReceiver mMessageReceiver;
-        private final long mRequestId;
-
-        UpdateGetAddressesResponseParamsProxyToResponder(
-                org.chromium.mojo.system.Core core,
-                org.chromium.mojo.bindings.MessageReceiver messageReceiver,
-                long requestId) {
-            mCore = core;
-            mMessageReceiver = messageReceiver;
-            mRequestId = requestId;
-        }
-
-        @Override
-        public void call(String[] addresses) {
-            UpdateGetAddressesResponseParams _response = new UpdateGetAddressesResponseParams();
-            _response.addresses = addresses;
-            org.chromium.mojo.bindings.ServiceMessage _message =
-                    _response.serializeWithHeader(
-                            mCore,
-                            new org.chromium.mojo.bindings.MessageHeader(
-                                    GET_ADDRESSES_ORDINAL,
-                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG,
-                                    mRequestId));
-            mMessageReceiver.accept(_message);
-        }
-    }
-
-    static final class UpdateGetAttributeParams extends org.chromium.mojo.bindings.Struct {
-    
-        private static final int STRUCT_SIZE = 16;
-        private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(16, 0)};
-        private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
-    
-        public String name;
-    
-        private UpdateGetAttributeParams(int version) {
-            super(STRUCT_SIZE, version);
-        }
-    
-        public UpdateGetAttributeParams() {
-            this(0);
-        }
-    
-        public static UpdateGetAttributeParams deserialize(org.chromium.mojo.bindings.Message message) {
-            return decode(new org.chromium.mojo.bindings.Decoder(message));
-        }
-    
-        @SuppressWarnings("unchecked")
-        public static UpdateGetAttributeParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
-            if (decoder0 == null) {
-                return null;
-            }
-            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-            UpdateGetAttributeParams result = new UpdateGetAttributeParams(mainDataHeader.elementsOrVersion);
-            if (mainDataHeader.elementsOrVersion >= 0) {
-                result.name = decoder0.readString(8, false);
-            }
-            return result;
-        }
-    
-        @SuppressWarnings("unchecked")
-        @Override
-        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
-            org.chromium.mojo.bindings.Encoder encoder0 = encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
-            encoder0.encode(name, 8, false);
-        }
-    
-        /**
-         * @see Object#equals(Object)
-         */
-        @Override
-        public boolean equals(Object object) {
-            if (object == this)
-                return true;
-            if (object == null)
-                return false;
-            if (getClass() != object.getClass())
-                return false;
-            UpdateGetAttributeParams other = (UpdateGetAttributeParams) object;
-            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.name, other.name))
-                return false;
-            return true;
-        }
-    
-        /**
-         * @see Object#hashCode()
-         */
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = prime + getClass().hashCode();
-            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(name);
-            return result;
-        }
-    }
-
-    static final class UpdateGetAttributeResponseParams extends org.chromium.mojo.bindings.Struct {
-    
-        private static final int STRUCT_SIZE = 16;
-        private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(16, 0)};
-        private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
-    
-        public String attribute;
-    
-        private UpdateGetAttributeResponseParams(int version) {
-            super(STRUCT_SIZE, version);
-        }
-    
-        public UpdateGetAttributeResponseParams() {
-            this(0);
-        }
-    
-        public static UpdateGetAttributeResponseParams deserialize(org.chromium.mojo.bindings.Message message) {
-            return decode(new org.chromium.mojo.bindings.Decoder(message));
-        }
-    
-        @SuppressWarnings("unchecked")
-        public static UpdateGetAttributeResponseParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
-            if (decoder0 == null) {
-                return null;
-            }
-            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-            UpdateGetAttributeResponseParams result = new UpdateGetAttributeResponseParams(mainDataHeader.elementsOrVersion);
-            if (mainDataHeader.elementsOrVersion >= 0) {
-                result.attribute = decoder0.readString(8, false);
-            }
-            return result;
-        }
-    
-        @SuppressWarnings("unchecked")
-        @Override
-        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
-            org.chromium.mojo.bindings.Encoder encoder0 = encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
-            encoder0.encode(attribute, 8, false);
-        }
-    
-        /**
-         * @see Object#equals(Object)
-         */
-        @Override
-        public boolean equals(Object object) {
-            if (object == this)
-                return true;
-            if (object == null)
-                return false;
-            if (getClass() != object.getClass())
-                return false;
-            UpdateGetAttributeResponseParams other = (UpdateGetAttributeResponseParams) object;
-            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.attribute, other.attribute))
-                return false;
-            return true;
-        }
-    
-        /**
-         * @see Object#hashCode()
-         */
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = prime + getClass().hashCode();
-            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(attribute);
-            return result;
-        }
-    }
-
-    static class UpdateGetAttributeResponseParamsForwardToCallback extends org.chromium.mojo.bindings.SideEffectFreeCloseable
-            implements org.chromium.mojo.bindings.MessageReceiver {
-        private final Update.GetAttributeResponse mCallback;
-
-        UpdateGetAttributeResponseParamsForwardToCallback(Update.GetAttributeResponse callback) {
-            this.mCallback = callback;
-        }
-
-        @Override
-        public boolean accept(org.chromium.mojo.bindings.Message message) {
-            try {
-                org.chromium.mojo.bindings.ServiceMessage messageWithHeader =
-                        message.asServiceMessage();
-                org.chromium.mojo.bindings.MessageHeader header = messageWithHeader.getHeader();
-                if (!header.validateHeader(GET_ATTRIBUTE_ORDINAL,
-                                           org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG)) {
-                    return false;
-                }
-                UpdateGetAttributeResponseParams response = UpdateGetAttributeResponseParams.deserialize(messageWithHeader.getPayload());
-                mCallback.call(response.attribute);
-                return true;
-            } catch (org.chromium.mojo.bindings.DeserializationException e) {
-                return false;
-            }
-        }
-    }
-
-    static class UpdateGetAttributeResponseParamsProxyToResponder implements Update.GetAttributeResponse {
-
-        private final org.chromium.mojo.system.Core mCore;
-        private final org.chromium.mojo.bindings.MessageReceiver mMessageReceiver;
-        private final long mRequestId;
-
-        UpdateGetAttributeResponseParamsProxyToResponder(
-                org.chromium.mojo.system.Core core,
-                org.chromium.mojo.bindings.MessageReceiver messageReceiver,
-                long requestId) {
-            mCore = core;
-            mMessageReceiver = messageReceiver;
-            mRequestId = requestId;
-        }
-
-        @Override
-        public void call(String attribute) {
-            UpdateGetAttributeResponseParams _response = new UpdateGetAttributeResponseParams();
-            _response.attribute = attribute;
-            org.chromium.mojo.bindings.ServiceMessage _message =
-                    _response.serializeWithHeader(
-                            mCore,
-                            new org.chromium.mojo.bindings.MessageHeader(
-                                    GET_ATTRIBUTE_ORDINAL,
-                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG,
-                                    mRequestId));
-            mMessageReceiver.accept(_message);
-        }
-    }
-
-    static final class UpdateGetAttachmentParams extends org.chromium.mojo.bindings.Struct {
-    
-        private static final int STRUCT_SIZE = 16;
-        private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(16, 0)};
-        private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
-    
-        public String name;
-    
-        private UpdateGetAttachmentParams(int version) {
-            super(STRUCT_SIZE, version);
-        }
-    
-        public UpdateGetAttachmentParams() {
-            this(0);
-        }
-    
-        public static UpdateGetAttachmentParams deserialize(org.chromium.mojo.bindings.Message message) {
-            return decode(new org.chromium.mojo.bindings.Decoder(message));
-        }
-    
-        @SuppressWarnings("unchecked")
-        public static UpdateGetAttachmentParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
-            if (decoder0 == null) {
-                return null;
-            }
-            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-            UpdateGetAttachmentParams result = new UpdateGetAttachmentParams(mainDataHeader.elementsOrVersion);
-            if (mainDataHeader.elementsOrVersion >= 0) {
-                result.name = decoder0.readString(8, false);
-            }
-            return result;
-        }
-    
-        @SuppressWarnings("unchecked")
-        @Override
-        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
-            org.chromium.mojo.bindings.Encoder encoder0 = encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
-            encoder0.encode(name, 8, false);
-        }
-    
-        /**
-         * @see Object#equals(Object)
-         */
-        @Override
-        public boolean equals(Object object) {
-            if (object == this)
-                return true;
-            if (object == null)
-                return false;
-            if (getClass() != object.getClass())
-                return false;
-            UpdateGetAttachmentParams other = (UpdateGetAttachmentParams) object;
-            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.name, other.name))
-                return false;
-            return true;
-        }
-    
-        /**
-         * @see Object#hashCode()
-         */
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = prime + getClass().hashCode();
-            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(name);
-            return result;
-        }
-    }
-
-    static final class UpdateGetAttachmentResponseParams extends org.chromium.mojo.bindings.Struct {
-    
-        private static final int STRUCT_SIZE = 16;
-        private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(16, 0)};
-        private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
-    
-        public org.chromium.mojo.system.DataPipe.ConsumerHandle data;
-    
-        private UpdateGetAttachmentResponseParams(int version) {
-            super(STRUCT_SIZE, version);
-            data = org.chromium.mojo.system.InvalidHandle.INSTANCE;
-        }
-    
-        public UpdateGetAttachmentResponseParams() {
-            this(0);
-        }
-    
-        public static UpdateGetAttachmentResponseParams deserialize(org.chromium.mojo.bindings.Message message) {
-            return decode(new org.chromium.mojo.bindings.Decoder(message));
-        }
-    
-        @SuppressWarnings("unchecked")
-        public static UpdateGetAttachmentResponseParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
-            if (decoder0 == null) {
-                return null;
-            }
-            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-            UpdateGetAttachmentResponseParams result = new UpdateGetAttachmentResponseParams(mainDataHeader.elementsOrVersion);
-            if (mainDataHeader.elementsOrVersion >= 0) {
-                result.data = decoder0.readConsumerHandle(8, false);
-            }
-            return result;
-        }
-    
-        @SuppressWarnings("unchecked")
-        @Override
-        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
-            org.chromium.mojo.bindings.Encoder encoder0 = encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
-            encoder0.encode(data, 8, false);
-        }
-    
-        /**
-         * @see Object#equals(Object)
-         */
-        @Override
-        public boolean equals(Object object) {
-            if (object == this)
-                return true;
-            if (object == null)
-                return false;
-            if (getClass() != object.getClass())
-                return false;
-            UpdateGetAttachmentResponseParams other = (UpdateGetAttachmentResponseParams) object;
-            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.data, other.data))
-                return false;
-            return true;
-        }
-    
-        /**
-         * @see Object#hashCode()
-         */
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = prime + getClass().hashCode();
-            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(data);
-            return result;
-        }
-    }
-
-    static class UpdateGetAttachmentResponseParamsForwardToCallback extends org.chromium.mojo.bindings.SideEffectFreeCloseable
-            implements org.chromium.mojo.bindings.MessageReceiver {
-        private final Update.GetAttachmentResponse mCallback;
-
-        UpdateGetAttachmentResponseParamsForwardToCallback(Update.GetAttachmentResponse callback) {
-            this.mCallback = callback;
-        }
-
-        @Override
-        public boolean accept(org.chromium.mojo.bindings.Message message) {
-            try {
-                org.chromium.mojo.bindings.ServiceMessage messageWithHeader =
-                        message.asServiceMessage();
-                org.chromium.mojo.bindings.MessageHeader header = messageWithHeader.getHeader();
-                if (!header.validateHeader(GET_ATTACHMENT_ORDINAL,
-                                           org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG)) {
-                    return false;
-                }
-                UpdateGetAttachmentResponseParams response = UpdateGetAttachmentResponseParams.deserialize(messageWithHeader.getPayload());
-                mCallback.call(response.data);
-                return true;
-            } catch (org.chromium.mojo.bindings.DeserializationException e) {
-                return false;
-            }
-        }
-    }
-
-    static class UpdateGetAttachmentResponseParamsProxyToResponder implements Update.GetAttachmentResponse {
-
-        private final org.chromium.mojo.system.Core mCore;
-        private final org.chromium.mojo.bindings.MessageReceiver mMessageReceiver;
-        private final long mRequestId;
-
-        UpdateGetAttachmentResponseParamsProxyToResponder(
-                org.chromium.mojo.system.Core core,
-                org.chromium.mojo.bindings.MessageReceiver messageReceiver,
-                long requestId) {
-            mCore = core;
-            mMessageReceiver = messageReceiver;
-            mRequestId = requestId;
-        }
-
-        @Override
-        public void call(org.chromium.mojo.system.DataPipe.ConsumerHandle data) {
-            UpdateGetAttachmentResponseParams _response = new UpdateGetAttachmentResponseParams();
-            _response.data = data;
-            org.chromium.mojo.bindings.ServiceMessage _message =
-                    _response.serializeWithHeader(
-                            mCore,
-                            new org.chromium.mojo.bindings.MessageHeader(
-                                    GET_ATTACHMENT_ORDINAL,
-                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG,
-                                    mRequestId));
-            mMessageReceiver.accept(_message);
-        }
-    }
-
-    static final class UpdateGetAdvertisementParams extends org.chromium.mojo.bindings.Struct {
-    
-        private static final int STRUCT_SIZE = 8;
-        private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(8, 0)};
-        private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
-    
-        private UpdateGetAdvertisementParams(int version) {
-            super(STRUCT_SIZE, version);
-        }
-    
-        public UpdateGetAdvertisementParams() {
-            this(0);
-        }
-    
-        public static UpdateGetAdvertisementParams deserialize(org.chromium.mojo.bindings.Message message) {
-            return decode(new org.chromium.mojo.bindings.Decoder(message));
-        }
-    
-        @SuppressWarnings("unchecked")
-        public static UpdateGetAdvertisementParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
-            if (decoder0 == null) {
-                return null;
-            }
-            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-            UpdateGetAdvertisementParams result = new UpdateGetAdvertisementParams(mainDataHeader.elementsOrVersion);
-            return result;
-        }
-    
-        @SuppressWarnings("unchecked")
-        @Override
-        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
-            encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
-        }
-    
-        /**
-         * @see Object#equals(Object)
-         */
-        @Override
-        public boolean equals(Object object) {
-            if (object == this)
-                return true;
-            if (object == null)
-                return false;
-            if (getClass() != object.getClass())
-                return false;
-            return true;
-        }
-    
-        /**
-         * @see Object#hashCode()
-         */
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = prime + getClass().hashCode();
-            return result;
-        }
-    }
-
-    static final class UpdateGetAdvertisementResponseParams extends org.chromium.mojo.bindings.Struct {
-    
-        private static final int STRUCT_SIZE = 16;
-        private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(16, 0)};
-        private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
-    
-        public Advertisement ad;
-    
-        private UpdateGetAdvertisementResponseParams(int version) {
-            super(STRUCT_SIZE, version);
-        }
-    
-        public UpdateGetAdvertisementResponseParams() {
-            this(0);
-        }
-    
-        public static UpdateGetAdvertisementResponseParams deserialize(org.chromium.mojo.bindings.Message message) {
-            return decode(new org.chromium.mojo.bindings.Decoder(message));
-        }
-    
-        @SuppressWarnings("unchecked")
-        public static UpdateGetAdvertisementResponseParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
-            if (decoder0 == null) {
-                return null;
-            }
-            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-            UpdateGetAdvertisementResponseParams result = new UpdateGetAdvertisementResponseParams(mainDataHeader.elementsOrVersion);
-            if (mainDataHeader.elementsOrVersion >= 0) {
-                org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(8, false);
-                result.ad = Advertisement.decode(decoder1);
-            }
-            return result;
-        }
-    
-        @SuppressWarnings("unchecked")
-        @Override
-        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
-            org.chromium.mojo.bindings.Encoder encoder0 = encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
-            encoder0.encode(ad, 8, false);
-        }
-    
-        /**
-         * @see Object#equals(Object)
-         */
-        @Override
-        public boolean equals(Object object) {
-            if (object == this)
-                return true;
-            if (object == null)
-                return false;
-            if (getClass() != object.getClass())
-                return false;
-            UpdateGetAdvertisementResponseParams other = (UpdateGetAdvertisementResponseParams) object;
-            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.ad, other.ad))
-                return false;
-            return true;
-        }
-    
-        /**
-         * @see Object#hashCode()
-         */
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = prime + getClass().hashCode();
-            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(ad);
-            return result;
-        }
-    }
-
-    static class UpdateGetAdvertisementResponseParamsForwardToCallback extends org.chromium.mojo.bindings.SideEffectFreeCloseable
-            implements org.chromium.mojo.bindings.MessageReceiver {
-        private final Update.GetAdvertisementResponse mCallback;
-
-        UpdateGetAdvertisementResponseParamsForwardToCallback(Update.GetAdvertisementResponse callback) {
-            this.mCallback = callback;
-        }
-
-        @Override
-        public boolean accept(org.chromium.mojo.bindings.Message message) {
-            try {
-                org.chromium.mojo.bindings.ServiceMessage messageWithHeader =
-                        message.asServiceMessage();
-                org.chromium.mojo.bindings.MessageHeader header = messageWithHeader.getHeader();
-                if (!header.validateHeader(GET_ADVERTISEMENT_ORDINAL,
-                                           org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG)) {
-                    return false;
-                }
-                UpdateGetAdvertisementResponseParams response = UpdateGetAdvertisementResponseParams.deserialize(messageWithHeader.getPayload());
-                mCallback.call(response.ad);
-                return true;
-            } catch (org.chromium.mojo.bindings.DeserializationException e) {
-                return false;
-            }
-        }
-    }
-
-    static class UpdateGetAdvertisementResponseParamsProxyToResponder implements Update.GetAdvertisementResponse {
-
-        private final org.chromium.mojo.system.Core mCore;
-        private final org.chromium.mojo.bindings.MessageReceiver mMessageReceiver;
-        private final long mRequestId;
-
-        UpdateGetAdvertisementResponseParamsProxyToResponder(
-                org.chromium.mojo.system.Core core,
-                org.chromium.mojo.bindings.MessageReceiver messageReceiver,
-                long requestId) {
-            mCore = core;
-            mMessageReceiver = messageReceiver;
-            mRequestId = requestId;
-        }
-
-        @Override
-        public void call(Advertisement ad) {
-            UpdateGetAdvertisementResponseParams _response = new UpdateGetAdvertisementResponseParams();
-            _response.ad = ad;
-            org.chromium.mojo.bindings.ServiceMessage _message =
-                    _response.serializeWithHeader(
-                            mCore,
-                            new org.chromium.mojo.bindings.MessageHeader(
-                                    GET_ADVERTISEMENT_ORDINAL,
-                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG,
-                                    mRequestId));
-            mMessageReceiver.accept(_message);
-        }
-    }
-
-}
-
diff --git a/java/gradle/wrapper/gradle-wrapper.jar b/java/gradle/wrapper/gradle-wrapper.jar
index 085a1cd..f1e5290 100644
--- a/java/gradle/wrapper/gradle-wrapper.jar
+++ b/java/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/java/gradle/wrapper/gradle-wrapper.properties b/java/gradle/wrapper/gradle-wrapper.properties
index 4483a73..d72ca1a 100644
--- a/java/gradle/wrapper/gradle-wrapper.properties
+++ b/java/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Fri Nov 20 15:21:22 PST 2015
+#Tue Mar 08 09:50:35 PST 2016
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2-all.zip
diff --git a/java/gradlew b/java/gradlew
index 91a7e26..9d82f78 100755
--- a/java/gradlew
+++ b/java/gradlew
@@ -42,11 +42,6 @@
     ;;
 esac
 
-# For Cygwin, ensure paths are in UNIX format before anything is touched.
-if $cygwin ; then
-    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
-fi
-
 # Attempt to set APP_HOME
 # Resolve links: $0 may be a link
 PRG="$0"
@@ -61,9 +56,9 @@
     fi
 done
 SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >&-
+cd "`dirname \"$PRG\"`/" >/dev/null
 APP_HOME="`pwd -P`"
-cd "$SAVED" >&-
+cd "$SAVED" >/dev/null
 
 CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
 
@@ -114,6 +109,7 @@
 if $cygwin ; then
     APP_HOME=`cygpath --path --mixed "$APP_HOME"`
     CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
 
     # We build the pattern for arguments to be converted via cygpath
     ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
diff --git a/java/settings.gradle b/java/settings.gradle
new file mode 100644
index 0000000..19c8fae
--- /dev/null
+++ b/java/settings.gradle
@@ -0,0 +1,7 @@
+rootProject.name='discovery'
+include ':mojo:system', ':mojo:bindings', ':mojo:application', ':mojo:interfaces:application', ':app'
+project(':mojo:system').projectDir = new File(settingsDir, '../../shared/java/mojo/system/')
+project(':mojo:bindings').projectDir = new File(settingsDir, '../../shared/java/mojo/bindings/')
+project(':mojo:application').projectDir = new File(settingsDir, '../../shared/java/mojo/application/')
+project(':mojo:interfaces:application').projectDir = new File(settingsDir, '../../shared/java/mojo/interfaces/application/')
+
diff --git a/java/src/main/java/io/v/mojo/discovery/DiscoveryImpl.java b/java/src/main/java/io/v/mojo/discovery/DiscoveryImpl.java
deleted file mode 100644
index c0b8a45..0000000
--- a/java/src/main/java/io/v/mojo/discovery/DiscoveryImpl.java
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright 2015 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package io.v.mojo.discovery;
-
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-
-import io.v.v23.InputChannelCallback;
-import org.chromium.mojo.system.MojoException;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import io.v.v23.InputChannels;
-import io.v.v23.context.VContext;
-import io.v.v23.discovery.Attachments;
-import io.v.v23.discovery.Attributes;
-import io.v.v23.discovery.VDiscovery;
-import io.v.v23.rpc.Callback;
-import io.v.v23.security.BlessingPattern;
-import io.v.v23.verror.VException;
-
-class DiscoveryImpl implements Discovery {
-    private final VDiscovery discovery;
-    private final VContext rootCtx;
-
-    private final Map<Integer, VContext> contextMap  = new HashMap<>();
-    private final Map<String, VContext> advertiserContextMap = new HashMap<>();
-
-    private final AtomicInteger nextScanner = new AtomicInteger(0);
-
-    public DiscoveryImpl(VDiscovery discovery, VContext rootCtx) {
-        this.discovery = discovery;
-        this.rootCtx = rootCtx;
-    }
-    @Override
-    public void startScan(String query, final ScanHandler scanHandler, StartScanResponse callback) {
-        synchronized (this) {
-            System.out.println("Got a scan call");
-            int handle = nextScanner.getAndAdd(1);
-            VContext ctx = rootCtx.withCancel();
-            contextMap.put(handle, ctx);
-            ListenableFuture<Void> done = InputChannels.withCallback(discovery.scan(ctx, query),
-                    new InputChannelCallback<io.v.v23.discovery.Update>() {
-                        @Override
-                        public ListenableFuture<Void> onNext(io.v.v23.discovery.Update update) {
-                            if (update instanceof io.v.v23.discovery.Update.Found) {
-                                io.v.v23.discovery.Update.Found found = (io.v.v23.discovery.Update.Found) update;
-                                Service mService = toMojoService(found.getElem().getService());
-                                ScanUpdate mUpdate = new ScanUpdate();
-                                mUpdate.service = mService;
-                                mUpdate.updateType = UpdateType.FOUND;
-                                scanHandler.update(mUpdate);
-                            } else {
-                                io.v.v23.discovery.Update.Lost lost = (io.v.v23.discovery.Update.Lost) update;
-                                Service mService = toMojoService(lost.getElem().getService());
-                                ScanUpdate mUpdate = new ScanUpdate();
-                                mUpdate.service = mService;
-                                mUpdate.updateType = UpdateType.LOST;
-                                scanHandler.update(mUpdate);
-                            }
-
-                            return Futures.immediateFuture(null);
-                        }
-
-                    });
-            System.out.println("Returning a scan call");
-            callback.call(handle, null);
-        }
-    }
-
-    @Override
-    public void stopScan(int h, StopScanResponse response) {
-        synchronized (this) {
-            VContext ctx = contextMap.get(h);
-            if (ctx != null) {
-                contextMap.remove(h);
-                ctx.cancel();
-            }
-            response.call(null);
-        }
-    }
-
-    private static Service toMojoService(io.v.v23.discovery.Service vService) {
-      Service mService = new Service();
-      mService.instanceId = vService.getInstanceId();
-      mService.instanceName = vService.getInstanceName();
-      mService.interfaceName = vService.getInterfaceName();
-      mService.addrs = new String[vService.getAddrs().size()];
-      mService.addrs = vService.getAddrs().toArray(mService.addrs);
-      mService.attrs = vService.getAttrs();
-      return mService;
-    }
-
-    @Override
-    public void startAdvertising(Service service, String[] visibility, final StartAdvertisingResponse callback) {
-        synchronized (this) {
-            final VContext ctx = rootCtx.withCancel();
-            Attributes attrs = null;
-            final io.v.v23.discovery.Service vService = new io.v.v23.discovery.Service(
-                    service.instanceId, service.instanceName, service.interfaceName,
-                    new Attributes(service.attrs), Arrays.asList(service.addrs), new Attachments());
-            if (service.attrs == null) {
-                vService.setAttrs(new Attributes(new HashMap<String, String>()));
-            }
-            List<BlessingPattern> patterns;
-            if (visibility != null) {
-                patterns = new ArrayList<>(visibility.length);
-                for (String pattern : visibility) {
-                    patterns.add(new BlessingPattern(pattern));
-                }
-            } else {
-                patterns = new ArrayList<>(0);
-            }
-            ListenableFuture<ListenableFuture<Void>> done = discovery.advertise(ctx, vService, patterns);
-            Futures.addCallback(done, new FutureCallback<ListenableFuture<Void>>() {
-                @Override
-                public void onSuccess(ListenableFuture<Void> result) {
-                    String instanceId = vService.getInstanceId();
-                    callback.call(instanceId, null);
-                    advertiserContextMap.put(instanceId, ctx);
-                }
-
-                @Override
-                public void onFailure(Throwable t) {
-                    System.out.println("Failed with " + t.toString());
-                    Error e = new Error();
-                    e.msg = t.toString();
-                    e.id = "unknown";
-                    callback.call("", e);
-                }
-            });
-        }
-    }
-
-    @Override
-    public void stopAdvertising(String instanceId, StopAdvertisingResponse response) {
-        synchronized (this) {
-            VContext ctx = advertiserContextMap.get(instanceId);
-            if (ctx != null) {
-                advertiserContextMap.remove(instanceId);
-                ctx.cancel();
-            }
-            response.call(null);
-        }
-    }
-
-    @Override
-    public void close() {}
-
-    @Override
-    public void onConnectionError(MojoException e) {}
-}
diff --git a/java/src/main/java/io/v/mojo/discovery/VDiscoveryApp.java b/java/src/main/java/io/v/mojo/discovery/VDiscoveryApp.java
deleted file mode 100644
index 4ca5eaf..0000000
--- a/java/src/main/java/io/v/mojo/discovery/VDiscoveryApp.java
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2015 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package io.v.mojo.discovery;
-
-import android.content.Context;
-
-import org.chromium.mojo.application.ApplicationConnection;
-import org.chromium.mojo.application.ApplicationDelegate;
-import org.chromium.mojo.application.ApplicationRunner;
-import org.chromium.mojo.application.ServiceFactoryBinder;
-import org.chromium.mojo.bindings.InterfaceRequest;
-import org.chromium.mojo.system.Core;
-import org.chromium.mojo.system.MessagePipeHandle;
-import org.chromium.mojom.mojo.Shell;
-
-import io.v.android.v23.V;
-import io.v.v23.context.VContext;
-
-/**
- * A mojo app that eposes  the v23 discovery api through the i.v.mojo.discovery interface.
- */
-public class VDiscoveryApp implements ApplicationDelegate {
-
-    private final VContext rootCtx;
-
-    VDiscoveryApp(Context context) {
-        rootCtx = V.init(context);
-    }
-
-    @Override
-    public void initialize(Shell shell, String[] strings, String s) {}
-
-    @Override
-    public boolean configureIncomingConnection(ApplicationConnection applicationConnection) {
-        applicationConnection.addService(new ServiceFactoryBinder<Discovery>() {
-            @Override
-            public void bind(InterfaceRequest<Discovery> request) {
-                Discovery.MANAGER.bind(new DiscoveryImpl(V.getDiscovery(rootCtx), rootCtx),
-                        request);
-            }
-
-            @Override
-            public String getInterfaceName() {
-                return Discovery.MANAGER.getName();
-            }
-        });
-        return true;
-    }
-
-    @Override
-    public void quit() {
-        rootCtx.cancel();
-    }
-
-    public static void mojoMain(Context context, Core core,
-                                MessagePipeHandle applicationRequestHandle) {
-        ApplicationRunner.run(new VDiscoveryApp(context), core, applicationRequestHandle);
-    }
-}
diff --git a/java/src/main/res/values/strings.xml b/java/src/main/res/values/strings.xml
deleted file mode 100644
index 928385f..0000000
--- a/java/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<resources>
-    <string name="app_name">Location</string>
-</resources>
\ No newline at end of file
diff --git a/lib/gen/dart-gen/mojom/lib/discovery/discovery.mojom.dart b/lib/gen/dart-gen/mojom/lib/discovery/discovery.mojom.dart
index 128c2b8..827cac0 100644
--- a/lib/gen/dart-gen/mojom/lib/discovery/discovery.mojom.dart
+++ b/lib/gen/dart-gen/mojom/lib/discovery/discovery.mojom.dart
@@ -260,8 +260,6 @@
 }
 
 
-
-
 class Error extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(32, 0)
@@ -362,8 +360,6 @@
 }
 
 
-
-
 class _DiscoveryAdvertiseParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(24, 0)
@@ -468,8 +464,6 @@
 }
 
 
-
-
 class DiscoveryAdvertiseResponseParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(32, 0)
@@ -568,8 +562,6 @@
 }
 
 
-
-
 class _DiscoveryScanParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(24, 0)
@@ -654,8 +646,6 @@
 }
 
 
-
-
 class DiscoveryScanResponseParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(24, 0)
@@ -741,8 +731,6 @@
 }
 
 
-
-
 class _CloserCloseParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(8, 0)
@@ -801,8 +789,6 @@
 }
 
 
-
-
 class CloserCloseResponseParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(8, 0)
@@ -861,8 +847,6 @@
 }
 
 
-
-
 class _ScanHandlerOnUpdateParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(16, 0)
@@ -934,8 +918,6 @@
 }
 
 
-
-
 class _UpdateIsLostParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(8, 0)
@@ -994,8 +976,6 @@
 }
 
 
-
-
 class UpdateIsLostResponseParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(16, 0)
@@ -1068,8 +1048,6 @@
 }
 
 
-
-
 class _UpdateGetIdParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(8, 0)
@@ -1128,8 +1106,6 @@
 }
 
 
-
-
 class UpdateGetIdResponseParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(16, 0)
@@ -1202,8 +1178,6 @@
 }
 
 
-
-
 class _UpdateGetInterfaceNameParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(8, 0)
@@ -1262,8 +1236,6 @@
 }
 
 
-
-
 class UpdateGetInterfaceNameResponseParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(16, 0)
@@ -1336,8 +1308,6 @@
 }
 
 
-
-
 class _UpdateGetAddressesParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(8, 0)
@@ -1396,8 +1366,6 @@
 }
 
 
-
-
 class UpdateGetAddressesResponseParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(16, 0)
@@ -1485,8 +1453,6 @@
 }
 
 
-
-
 class _UpdateGetAttributeParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(16, 0)
@@ -1559,8 +1525,6 @@
 }
 
 
-
-
 class UpdateGetAttributeResponseParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(16, 0)
@@ -1633,8 +1597,6 @@
 }
 
 
-
-
 class _UpdateGetAttachmentParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(16, 0)
@@ -1707,8 +1669,6 @@
 }
 
 
-
-
 class UpdateGetAttachmentResponseParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(16, 0)
@@ -1780,8 +1740,6 @@
 }
 
 
-
-
 class _UpdateGetAdvertisementParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(8, 0)
@@ -1840,8 +1798,6 @@
 }
 
 
-
-
 class UpdateGetAdvertisementResponseParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(16, 0)
@@ -1914,14 +1870,9 @@
   }
 }
 
-
-
-
 const int _Discovery_advertiseName = 0;
 const int _Discovery_scanName = 1;
 
-
-
 class _DiscoveryServiceDescription implements service_describer.ServiceDescription {
   dynamic getTopLevelInterface([Function responseFactory]) =>
       responseFactory(null);
@@ -2216,8 +2167,6 @@
 
 const int _Closer_closeName = 0;
 
-
-
 class _CloserServiceDescription implements service_describer.ServiceDescription {
   dynamic getTopLevelInterface([Function responseFactory]) =>
       responseFactory(null);
@@ -2446,8 +2395,6 @@
 
 const int _ScanHandler_onUpdateName = 0;
 
-
-
 class _ScanHandlerServiceDescription implements service_describer.ServiceDescription {
   dynamic getTopLevelInterface([Function responseFactory]) =>
       responseFactory(null);
@@ -2644,8 +2591,6 @@
 const int _Update_getAttachmentName = 5;
 const int _Update_getAdvertisementName = 6;
 
-
-
 class _UpdateServiceDescription implements service_describer.ServiceDescription {
   dynamic getTopLevelInterface([Function responseFactory]) =>
       responseFactory(null);
diff --git a/mojoapptests b/mojoapptests
index bb0da47..294af61 100644
--- a/mojoapptests
+++ b/mojoapptests
@@ -3,13 +3,15 @@
 
 tests = [
   {
-    "test": "https://mojo.v.io/discovery_apptests.mojo",
+    "test": "https://test.v.io/discovery_apptests.mojo",
     "test-args": [],
-    "shell-args": [],
+    "shell-args": ["--args-for=https://mojo.v.io/discovery.mojo --use-mock"],
+    "timeout": 120,
   },
   {
     "test": "https://dart.test.mojo.v.io/discovery_apptests.dart",
     "type": "dart",
-    "dart_strict_mode": True
+    "dart_strict_mode": True,
+    "shell-args": ["--args-for=https://mojo.v.io/discovery.mojo --use-mock"],
   }
 ]
diff --git a/mojoconfig b/mojoconfig
index 1240d0c..8739ee2 100644
--- a/mojoconfig
+++ b/mojoconfig
@@ -4,16 +4,25 @@
   'dev_servers': [
     {
       'host': 'https://mojo.v.io/',
-      'port': 32000,
+      'port': 31843,
       'mappings': [
         ('', [
-          '@{DISCOVERY_BUILD_DIR}',
+          '@{BUILD_DIR}',
+        ]),
+      ],
+    },
+    {
+      'host': 'https://test.v.io/',
+      'port': 31844,
+      'mappings': [
+        ('', [
+          '@{TEST_BUILD_DIR}',
         ]),
       ],
     },
     {
       'host': 'https://dart.test.mojo.v.io/',
-      'port': 32001,
+      'port': 31845,
       'mappings': [
         ('', [
           '@{DISCOVERY_DIR}/test',
diff --git a/mojom/vanadium/discovery.mojom b/mojom/v.io/discovery.mojom
similarity index 100%
rename from mojom/vanadium/discovery.mojom
rename to mojom/v.io/discovery.mojom
