diff --git a/Makefile b/Makefile
index 02700ca..5175e8a 100644
--- a/Makefile
+++ b/Makefile
@@ -10,15 +10,19 @@
 	DISCOVERY_BUILD_DIR := $(CURDIR)/gen/mojo/linux_amd64
 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)
+	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)
 
-define CGO_TEST
-	jiri go --profiles=$(MOJO_PROFILE),base test -v $1
-endef
-
 V23_GO_FILES := $(shell find $(JIRI_ROOT) -name "*.go")
 PYTHONPATH := $(MOJO_SDK)/src/mojo/public/third_party:$(PYTHONPATH)
 
@@ -91,7 +95,7 @@
 	rm -f lib/gen/mojom/$(notdir $@)
 
 discovery-test: $(V23_GO_FILES) go/src/mojom/vanadium/discovery/discovery.mojom.go | mojo-env-check
-	$(call CGO_TEST,vanadium/discovery/internal)
+	$(call MOGO_TEST,-v vanadium/discovery/internal/...)
 
 clean:
 	rm -rf gen
diff --git a/go/src/examples/advertiser/advertiser.go b/go/src/examples/advertiser/advertiser.go
index 0d41e53..d360991 100644
--- a/go/src/examples/advertiser/advertiser.go
+++ b/go/src/examples/advertiser/advertiser.go
@@ -25,21 +25,26 @@
 	req, ptr := discovery.CreateMessagePipeForDiscovery()
 	ctx.ConnectToApplication("https://mojo.v.io/discovery.mojo").ConnectToService(&req)
 
-	service := discovery.Service{
+	ad := discovery.Advertisement{
 		InterfaceName: "v.io/discovery.T",
-		Addrs:         []string{"localhost:1000", "localhost:2000"},
-		Attrs:         &map[string]string{"foo": "bar"},
+		Addresses:     []string{"localhost:1000"},
+		Attributes:    &map[string]string{"foo": "abc"},
+		Attachments:   &map[string][]byte{"bar": []byte{1, 2, 3}},
 	}
-	proxy := discovery.NewDiscoveryProxy(ptr, bindings.GetAsyncWaiter())
-	instanceId, e1, e2 := proxy.StartAdvertising(service, nil)
+	dProxy := discovery.NewDiscoveryProxy(ptr, bindings.GetAsyncWaiter())
+	id, closerPtr, e1, e2 := dProxy.Advertise(ad, nil)
 	if e1 != nil || e2 != nil {
-		log.Println("Error occurred", e1, e2)
+		log.Printf("Failed to advertise: %v, %v", e1, e2)
 		return
 	}
+	log.Printf("Advertising %x...", *id)
 
 	d.stop = func() {
-		proxy.StopAdvertising(instanceId)
-		proxy.Close_Proxy()
+		cProxy := discovery.NewCloserProxy(*closerPtr, bindings.GetAsyncWaiter())
+		cProxy.Close()
+		cProxy.Close_Proxy()
+
+		dProxy.Close_Proxy()
 	}
 }
 
diff --git a/go/src/examples/scanner/scanner.go b/go/src/examples/scanner/scanner.go
index d380ce4..15d6a7f 100644
--- a/go/src/examples/scanner/scanner.go
+++ b/go/src/examples/scanner/scanner.go
@@ -19,15 +19,23 @@
 
 type scanHandler struct{}
 
-func (*scanHandler) Update(update discovery.ScanUpdate) error {
-	var tag string
-	switch update.UpdateType {
-	case discovery.UpdateType_Found:
-		tag = "Found"
-	case discovery.UpdateType_Lost:
+func (*scanHandler) OnUpdate(ptr discovery.Update_Pointer) error {
+	uProxy := discovery.NewUpdateProxy(ptr, bindings.GetAsyncWaiter())
+	defer uProxy.Close_Proxy()
+
+	tag := "Found"
+	if lost, _ := uProxy.IsLost(); lost {
 		tag = "Lost"
 	}
-	log.Printf("%s service: %v", tag, update.Service)
+	id, _ := uProxy.GetId()
+	interfaceName, _ := uProxy.GetInterfaceName()
+	addresses, _ := uProxy.GetAddresses()
+	attribute, _ := uProxy.GetAttribute("foo")
+	attachmentHandle, _ := uProxy.GetAttachment("bar")
+	_, attachment := attachmentHandle.ReadData(system.MOJO_READ_DATA_FLAG_NONE)
+	attachmentHandle.Close()
+
+	log.Printf("%s %x: {InterfaceName: %q, Addresses: %q, Attribute[\"foo\"]: %q, Attachment[\"bar\"]: 0x%x}", tag, id, interfaceName, addresses, attribute, attachment)
 	return nil
 }
 
@@ -42,20 +50,15 @@
 	scanHandlerReq, scanHandlerPtr := discovery.CreateMessagePipeForScanHandler()
 	scanHandlerStub := discovery.NewScanHandlerStub(scanHandlerReq, &scanHandler{}, bindings.GetAsyncWaiter())
 
-	proxy := discovery.NewDiscoveryProxy(ptr, bindings.GetAsyncWaiter())
-	scanId, e1, e2 := proxy.StartScan(`v.InterfaceName="v.io/discovery.T"`, scanHandlerPtr)
+	dProxy := discovery.NewDiscoveryProxy(ptr, bindings.GetAsyncWaiter())
+	closerPtr, e1, e2 := dProxy.Scan(`v.InterfaceName="v.io/discovery.T"`, scanHandlerPtr)
 	if e1 != nil || e2 != nil {
-		log.Println("Error occurred", e1, e2)
+		log.Printf("Failed to scan: %v, %v", e1, e2)
 		scanHandlerStub.Close()
+		dProxy.Close_Proxy()
 		return
 	}
 
-	d.stop = func() {
-		proxy.StopScan(scanId)
-		scanHandlerStub.Close()
-		proxy.Close_Proxy()
-	}
-
 	go func() {
 		for {
 			if err := scanHandlerStub.ServeRequest(); err != nil {
@@ -67,6 +70,15 @@
 			}
 		}
 	}()
+
+	d.stop = func() {
+		cProxy := discovery.NewCloserProxy(*closerPtr, bindings.GetAsyncWaiter())
+		cProxy.Close()
+		cProxy.Close_Proxy()
+
+		scanHandlerStub.Close()
+		dProxy.Close_Proxy()
+	}
 }
 
 func (*delegate) AcceptConnection(connection *application.Connection) {
diff --git a/go/src/mojom/vanadium/discovery/discovery.mojom.go b/go/src/mojom/vanadium/discovery/discovery.mojom.go
index 3d65012..f4da926 100644
--- a/go/src/mojom/vanadium/discovery/discovery.mojom.go
+++ b/go/src/mojom/vanadium/discovery/discovery.mojom.go
@@ -19,18 +19,9 @@
 	sort "sort"
 )
 
-type UpdateType int32
-
-const (
-	UpdateType_Found = 1
-	UpdateType_Lost  = UpdateType_Found + 1
-)
-
 type Discovery interface {
-	StartAdvertising(inService Service, inVisibility *[]string) (outInstanceId string, outErr *Error, err error)
-	StopAdvertising(inInstanceId string) (outErr *Error, err error)
-	StartScan(inQuery string, inHandler ScanHandler_Pointer) (outScanId uint32, outErr *Error, err error)
-	StopScan(inScanId uint32) (outErr *Error, err error)
+	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"
@@ -75,10 +66,8 @@
 	return Discovery_Request(r), Discovery_Pointer(p)
 }
 
-const discovery_StartAdvertising_Name uint32 = 0
-const discovery_StopAdvertising_Name uint32 = 1
-const discovery_StartScan_Name uint32 = 2
-const discovery_StopScan_Name uint32 = 3
+const discovery_Advertise_Name uint32 = 0
+const discovery_Scan_Name uint32 = 1
 
 type Discovery_Proxy struct {
 	router *bindings.Router
@@ -96,17 +85,17 @@
 	p.router.Close()
 }
 
-type discovery_StartAdvertising_Params struct {
-	inService    Service
+type discovery_Advertise_Params struct {
+	inAd         Advertisement
 	inVisibility *[]string
 }
 
-func (s *discovery_StartAdvertising_Params) Encode(encoder *bindings.Encoder) error {
+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.inService.Encode(encoder); err != nil {
+	if err := s.inAd.Encode(encoder); err != nil {
 		return err
 	}
 	if s.inVisibility == nil {
@@ -134,23 +123,23 @@
 	return nil
 }
 
-var discovery_StartAdvertising_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
+var discovery_Advertise_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
 	bindings.DataHeader{24, 0},
 }
 
-func (s *discovery_StartAdvertising_Params) Decode(decoder *bindings.Decoder) error {
+func (s *discovery_Advertise_Params) Decode(decoder *bindings.Decoder) error {
 	header, err := decoder.StartStruct()
 	if err != nil {
 		return err
 	}
-	index := sort.Search(len(discovery_StartAdvertising_Params_Versions), func(i int) bool {
-		return discovery_StartAdvertising_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
+	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_StartAdvertising_Params_Versions) {
-		if discovery_StartAdvertising_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
+	if index < len(discovery_Advertise_Params_Versions) {
+		if discovery_Advertise_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
 			index--
 		}
-		expectedSize := discovery_StartAdvertising_Params_Versions[index].Size
+		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),
@@ -165,7 +154,7 @@
 		if pointer0 == 0 {
 			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
 		} else {
-			if err := s.inService.Decode(decoder); err != nil {
+			if err := s.inAd.Decode(decoder); err != nil {
 				return err
 			}
 		}
@@ -210,18 +199,36 @@
 	return nil
 }
 
-type discovery_StartAdvertising_ResponseParams struct {
-	outInstanceId string
+type discovery_Advertise_ResponseParams struct {
+	outInstanceId *[16]uint8
+	outCloser     *Closer_Pointer
 	outErr        *Error
 }
 
-func (s *discovery_StartAdvertising_ResponseParams) Encode(encoder *bindings.Encoder) error {
-	encoder.StartStruct(16, 0)
-	if err := encoder.WritePointer(); err != nil {
-		return err
+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 err := encoder.WriteString(s.outInstanceId); 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()
@@ -239,23 +246,23 @@
 	return nil
 }
 
-var discovery_StartAdvertising_ResponseParams_Versions []bindings.DataHeader = []bindings.DataHeader{
-	bindings.DataHeader{24, 0},
+var discovery_Advertise_ResponseParams_Versions []bindings.DataHeader = []bindings.DataHeader{
+	bindings.DataHeader{32, 0},
 }
 
-func (s *discovery_StartAdvertising_ResponseParams) Decode(decoder *bindings.Decoder) error {
+func (s *discovery_Advertise_ResponseParams) Decode(decoder *bindings.Decoder) error {
 	header, err := decoder.StartStruct()
 	if err != nil {
 		return err
 	}
-	index := sort.Search(len(discovery_StartAdvertising_ResponseParams_Versions), func(i int) bool {
-		return discovery_StartAdvertising_ResponseParams_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
+	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_StartAdvertising_ResponseParams_Versions) {
-		if discovery_StartAdvertising_ResponseParams_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
+	if index < len(discovery_Advertise_ResponseParams_Versions) {
+		if discovery_Advertise_ResponseParams_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
 			index--
 		}
-		expectedSize := discovery_StartAdvertising_ResponseParams_Versions[index].Size
+		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),
@@ -268,13 +275,40 @@
 			return err
 		}
 		if pointer0 == 0 {
-			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
+			s.outInstanceId = nil
 		} else {
-			value0, err := decoder.ReadString()
+			s.outInstanceId = new([16]uint8)
+			len0, err := decoder.StartArray(8)
 			if err != nil {
 				return err
 			}
-			s.outInstanceId = value0
+			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 {
@@ -297,13 +331,13 @@
 	return nil
 }
 
-func (p *Discovery_Proxy) StartAdvertising(inService Service, inVisibility *[]string) (outInstanceId string, outErr *Error, err error) {
-	payload := &discovery_StartAdvertising_Params{
-		inService,
+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_StartAdvertising_Name,
+		Type:      discovery_Advertise_Name,
 		Flags:     bindings.MessageExpectsResponseFlag,
 		RequestId: p.ids.Count(),
 	}
@@ -324,196 +358,29 @@
 		}
 		return
 	}
-	if got, want := readResult.Message.Header.Type, discovery_StartAdvertising_Name; got != want {
+	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_StartAdvertising_ResponseParams
+	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_StopAdvertising_Params struct {
-	inInstanceId string
-}
-
-func (s *discovery_StopAdvertising_Params) Encode(encoder *bindings.Encoder) error {
-	encoder.StartStruct(8, 0)
-	if err := encoder.WritePointer(); err != nil {
-		return err
-	}
-	if err := encoder.WriteString(s.inInstanceId); err != nil {
-		return err
-	}
-	if err := encoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-var discovery_StopAdvertising_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
-	bindings.DataHeader{16, 0},
-}
-
-func (s *discovery_StopAdvertising_Params) Decode(decoder *bindings.Decoder) error {
-	header, err := decoder.StartStruct()
-	if err != nil {
-		return err
-	}
-	index := sort.Search(len(discovery_StopAdvertising_Params_Versions), func(i int) bool {
-		return discovery_StopAdvertising_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
-	})
-	if index < len(discovery_StopAdvertising_Params_Versions) {
-		if discovery_StopAdvertising_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
-			index--
-		}
-		expectedSize := discovery_StopAdvertising_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.inInstanceId = value0
-		}
-	}
-	if err := decoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-type discovery_StopAdvertising_ResponseParams struct {
-	outErr *Error
-}
-
-func (s *discovery_StopAdvertising_ResponseParams) Encode(encoder *bindings.Encoder) error {
-	encoder.StartStruct(8, 0)
-	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_StopAdvertising_ResponseParams_Versions []bindings.DataHeader = []bindings.DataHeader{
-	bindings.DataHeader{16, 0},
-}
-
-func (s *discovery_StopAdvertising_ResponseParams) Decode(decoder *bindings.Decoder) error {
-	header, err := decoder.StartStruct()
-	if err != nil {
-		return err
-	}
-	index := sort.Search(len(discovery_StopAdvertising_ResponseParams_Versions), func(i int) bool {
-		return discovery_StopAdvertising_ResponseParams_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
-	})
-	if index < len(discovery_StopAdvertising_ResponseParams_Versions) {
-		if discovery_StopAdvertising_ResponseParams_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
-			index--
-		}
-		expectedSize := discovery_StopAdvertising_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.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) StopAdvertising(inInstanceId string) (outErr *Error, err error) {
-	payload := &discovery_StopAdvertising_Params{
-		inInstanceId,
-	}
-	header := bindings.MessageHeader{
-		Type:      discovery_StopAdvertising_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_StopAdvertising_Name; got != want {
-		err = &bindings.ValidationError{bindings.MessageHeaderUnknownMethod,
-			fmt.Sprintf("invalid method in response: expected %v, got %v", want, got),
-		}
-		return
-	}
-	var response discovery_StopAdvertising_ResponseParams
-	if err = readResult.Message.DecodePayload(&response); err != nil {
-		p.Close_Proxy()
-		return
-	}
-	outErr = response.outErr
-	return
-}
-
-type discovery_StartScan_Params struct {
+type discovery_Scan_Params struct {
 	inQuery   string
 	inHandler ScanHandler_Pointer
 }
 
-func (s *discovery_StartScan_Params) Encode(encoder *bindings.Encoder) error {
+func (s *discovery_Scan_Params) Encode(encoder *bindings.Encoder) error {
 	encoder.StartStruct(16, 0)
 	if err := encoder.WritePointer(); err != nil {
 		return err
@@ -530,23 +397,23 @@
 	return nil
 }
 
-var discovery_StartScan_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
+var discovery_Scan_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
 	bindings.DataHeader{24, 0},
 }
 
-func (s *discovery_StartScan_Params) Decode(decoder *bindings.Decoder) error {
+func (s *discovery_Scan_Params) Decode(decoder *bindings.Decoder) error {
 	header, err := decoder.StartStruct()
 	if err != nil {
 		return err
 	}
-	index := sort.Search(len(discovery_StartScan_Params_Versions), func(i int) bool {
-		return discovery_StartScan_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
+	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_StartScan_Params_Versions) {
-		if discovery_StartScan_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
+	if index < len(discovery_Scan_Params_Versions) {
+		if discovery_Scan_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
 			index--
 		}
-		expectedSize := discovery_StartScan_Params_Versions[index].Size
+		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),
@@ -586,15 +453,19 @@
 	return nil
 }
 
-type discovery_StartScan_ResponseParams struct {
-	outScanId uint32
+type discovery_Scan_ResponseParams struct {
+	outCloser *Closer_Pointer
 	outErr    *Error
 }
 
-func (s *discovery_StartScan_ResponseParams) Encode(encoder *bindings.Encoder) error {
+func (s *discovery_Scan_ResponseParams) Encode(encoder *bindings.Encoder) error {
 	encoder.StartStruct(16, 0)
-	if err := encoder.WriteUint32(s.outScanId); 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()
@@ -612,23 +483,23 @@
 	return nil
 }
 
-var discovery_StartScan_ResponseParams_Versions []bindings.DataHeader = []bindings.DataHeader{
+var discovery_Scan_ResponseParams_Versions []bindings.DataHeader = []bindings.DataHeader{
 	bindings.DataHeader{24, 0},
 }
 
-func (s *discovery_StartScan_ResponseParams) Decode(decoder *bindings.Decoder) error {
+func (s *discovery_Scan_ResponseParams) Decode(decoder *bindings.Decoder) error {
 	header, err := decoder.StartStruct()
 	if err != nil {
 		return err
 	}
-	index := sort.Search(len(discovery_StartScan_ResponseParams_Versions), func(i int) bool {
-		return discovery_StartScan_ResponseParams_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
+	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_StartScan_ResponseParams_Versions) {
-		if discovery_StartScan_ResponseParams_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
+	if index < len(discovery_Scan_ResponseParams_Versions) {
+		if discovery_Scan_ResponseParams_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
 			index--
 		}
-		expectedSize := discovery_StartScan_ResponseParams_Versions[index].Size
+		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),
@@ -636,11 +507,16 @@
 		}
 	}
 	if header.ElementsOrVersion >= 0 {
-		value0, err := decoder.ReadUint32()
+		handle0, err := decoder.ReadInterface()
 		if err != nil {
 			return err
 		}
-		s.outScanId = value0
+		if handle0.IsValid() {
+			handleOwner := bindings.NewMessagePipeHandleOwner(handle0)
+			s.outCloser = &Closer_Pointer{handleOwner}
+		} else {
+			s.outCloser = nil
+		}
 	}
 	if header.ElementsOrVersion >= 0 {
 		pointer0, err := decoder.ReadPointer()
@@ -662,13 +538,13 @@
 	return nil
 }
 
-func (p *Discovery_Proxy) StartScan(inQuery string, inHandler ScanHandler_Pointer) (outScanId uint32, outErr *Error, err error) {
-	payload := &discovery_StartScan_Params{
+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_StartScan_Name,
+		Type:      discovery_Scan_Name,
 		Flags:     bindings.MessageExpectsResponseFlag,
 		RequestId: p.ids.Count(),
 	}
@@ -689,175 +565,18 @@
 		}
 		return
 	}
-	if got, want := readResult.Message.Header.Type, discovery_StartScan_Name; got != want {
+	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_StartScan_ResponseParams
+	var response discovery_Scan_ResponseParams
 	if err = readResult.Message.DecodePayload(&response); err != nil {
 		p.Close_Proxy()
 		return
 	}
-	outScanId = response.outScanId
-	outErr = response.outErr
-	return
-}
-
-type discovery_StopScan_Params struct {
-	inScanId uint32
-}
-
-func (s *discovery_StopScan_Params) Encode(encoder *bindings.Encoder) error {
-	encoder.StartStruct(8, 0)
-	if err := encoder.WriteUint32(s.inScanId); err != nil {
-		return err
-	}
-	if err := encoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-var discovery_StopScan_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
-	bindings.DataHeader{16, 0},
-}
-
-func (s *discovery_StopScan_Params) Decode(decoder *bindings.Decoder) error {
-	header, err := decoder.StartStruct()
-	if err != nil {
-		return err
-	}
-	index := sort.Search(len(discovery_StopScan_Params_Versions), func(i int) bool {
-		return discovery_StopScan_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
-	})
-	if index < len(discovery_StopScan_Params_Versions) {
-		if discovery_StopScan_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
-			index--
-		}
-		expectedSize := discovery_StopScan_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 {
-		value0, err := decoder.ReadUint32()
-		if err != nil {
-			return err
-		}
-		s.inScanId = value0
-	}
-	if err := decoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-type discovery_StopScan_ResponseParams struct {
-	outErr *Error
-}
-
-func (s *discovery_StopScan_ResponseParams) Encode(encoder *bindings.Encoder) error {
-	encoder.StartStruct(8, 0)
-	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_StopScan_ResponseParams_Versions []bindings.DataHeader = []bindings.DataHeader{
-	bindings.DataHeader{16, 0},
-}
-
-func (s *discovery_StopScan_ResponseParams) Decode(decoder *bindings.Decoder) error {
-	header, err := decoder.StartStruct()
-	if err != nil {
-		return err
-	}
-	index := sort.Search(len(discovery_StopScan_ResponseParams_Versions), func(i int) bool {
-		return discovery_StopScan_ResponseParams_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
-	})
-	if index < len(discovery_StopScan_ResponseParams_Versions) {
-		if discovery_StopScan_ResponseParams_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
-			index--
-		}
-		expectedSize := discovery_StopScan_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.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) StopScan(inScanId uint32) (outErr *Error, err error) {
-	payload := &discovery_StopScan_Params{
-		inScanId,
-	}
-	header := bindings.MessageHeader{
-		Type:      discovery_StopScan_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_StopScan_Name; got != want {
-		err = &bindings.ValidationError{bindings.MessageHeaderUnknownMethod,
-			fmt.Sprintf("invalid method in response: expected %v, got %v", want, got),
-		}
-		return
-	}
-	var response discovery_StopScan_ResponseParams
-	if err = readResult.Message.DecodePayload(&response); err != nil {
-		p.Close_Proxy()
-		return
-	}
+	outCloser = response.outCloser
 	outErr = response.outErr
 	return
 }
@@ -897,23 +616,23 @@
 
 func (s *discovery_Stub) Accept(message *bindings.Message) (err error) {
 	switch message.Header.Type {
-	case discovery_StartAdvertising_Name:
+	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_StartAdvertising_Params
+		var request discovery_Advertise_Params
 		if err := message.DecodePayload(&request); err != nil {
 			return err
 		}
-		var response discovery_StartAdvertising_ResponseParams
-		response.outInstanceId, response.outErr, err = s.impl.StartAdvertising(request.inService, request.inVisibility)
+		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_StartAdvertising_Name,
+			Type:      discovery_Advertise_Name,
 			Flags:     bindings.MessageIsResponseFlag,
 			RequestId: message.Header.RequestId,
 		}
@@ -922,23 +641,23 @@
 			return err
 		}
 		return s.connector.WriteMessage(message)
-	case discovery_StopAdvertising_Name:
+	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_StopAdvertising_Params
+		var request discovery_Scan_Params
 		if err := message.DecodePayload(&request); err != nil {
 			return err
 		}
-		var response discovery_StopAdvertising_ResponseParams
-		response.outErr, err = s.impl.StopAdvertising(request.inInstanceId)
+		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_StopAdvertising_Name,
+			Type:      discovery_Scan_Name,
 			Flags:     bindings.MessageIsResponseFlag,
 			RequestId: message.Header.RequestId,
 		}
@@ -947,48 +666,235 @@
 			return err
 		}
 		return s.connector.WriteMessage(message)
-	case discovery_StartScan_Name:
+	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)
+}
+
+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 discovery_StartScan_Params
+		var request closer_Close_Params
 		if err := message.DecodePayload(&request); err != nil {
 			return err
 		}
-		var response discovery_StartScan_ResponseParams
-		response.outScanId, response.outErr, err = s.impl.StartScan(request.inQuery, request.inHandler)
+		var response closer_Close_ResponseParams
+		err = s.impl.Close()
 		if err != nil {
 			return
 		}
 		header := bindings.MessageHeader{
-			Type:      discovery_StartScan_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_StopScan_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_StopScan_Params
-		if err := message.DecodePayload(&request); err != nil {
-			return err
-		}
-		var response discovery_StopScan_ResponseParams
-		response.outErr, err = s.impl.StopScan(request.inScanId)
-		if err != nil {
-			return
-		}
-		header := bindings.MessageHeader{
-			Type:      discovery_StopScan_Name,
+			Type:      closer_Close_Name,
 			Flags:     bindings.MessageIsResponseFlag,
 			RequestId: message.Header.RequestId,
 		}
@@ -1007,23 +913,13 @@
 }
 
 type ScanHandler interface {
-	Update(inUpdate ScanUpdate) (err error)
+	OnUpdate(inUpdate Update_Pointer) (err error)
 }
 
-var scanHandler_Name = "v23::discovery::ScanHandler"
-
 type ScanHandler_Request bindings.InterfaceRequest
 
-func (r *ScanHandler_Request) Name() string {
-	return scanHandler_Name
-}
-
 type ScanHandler_Pointer bindings.InterfacePointer
 
-func (p *ScanHandler_Pointer) Name() string {
-	return scanHandler_Name
-}
-
 type ScanHandler_ServiceFactory struct {
 	Delegate ScanHandler_Factory
 }
@@ -1032,10 +928,6 @@
 	Create(request ScanHandler_Request)
 }
 
-func (f *ScanHandler_ServiceFactory) Name() string {
-	return scanHandler_Name
-}
-
 func (f *ScanHandler_ServiceFactory) ServiceDescription() service_describer.ServiceDescription {
 	return &ScanHandler_ServiceDescription{}
 }
@@ -1052,7 +944,7 @@
 	return ScanHandler_Request(r), ScanHandler_Pointer(p)
 }
 
-const scanHandler_Update_Name uint32 = 0
+const scanHandler_OnUpdate_Name uint32 = 0
 
 type ScanHandler_Proxy struct {
 	router *bindings.Router
@@ -1070,16 +962,13 @@
 	p.router.Close()
 }
 
-type scanHandler_Update_Params struct {
-	inUpdate ScanUpdate
+type scanHandler_OnUpdate_Params struct {
+	inUpdate Update_Pointer
 }
 
-func (s *scanHandler_Update_Params) Encode(encoder *bindings.Encoder) error {
+func (s *scanHandler_OnUpdate_Params) Encode(encoder *bindings.Encoder) error {
 	encoder.StartStruct(8, 0)
-	if err := encoder.WritePointer(); err != nil {
-		return err
-	}
-	if err := s.inUpdate.Encode(encoder); err != nil {
+	if err := encoder.WriteInterface(s.inUpdate.PassMessagePipe()); err != nil {
 		return err
 	}
 	if err := encoder.Finish(); err != nil {
@@ -1088,23 +977,23 @@
 	return nil
 }
 
-var scanHandler_Update_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
+var scanHandler_OnUpdate_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
 	bindings.DataHeader{16, 0},
 }
 
-func (s *scanHandler_Update_Params) Decode(decoder *bindings.Decoder) error {
+func (s *scanHandler_OnUpdate_Params) Decode(decoder *bindings.Decoder) error {
 	header, err := decoder.StartStruct()
 	if err != nil {
 		return err
 	}
-	index := sort.Search(len(scanHandler_Update_Params_Versions), func(i int) bool {
-		return scanHandler_Update_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
+	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_Update_Params_Versions) {
-		if scanHandler_Update_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
+	if index < len(scanHandler_OnUpdate_Params_Versions) {
+		if scanHandler_OnUpdate_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
 			index--
 		}
-		expectedSize := scanHandler_Update_Params_Versions[index].Size
+		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),
@@ -1112,16 +1001,15 @@
 		}
 	}
 	if header.ElementsOrVersion >= 0 {
-		pointer0, err := decoder.ReadPointer()
+		handle0, err := decoder.ReadInterface()
 		if err != nil {
 			return err
 		}
-		if pointer0 == 0 {
-			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
+		if handle0.IsValid() {
+			handleOwner := bindings.NewMessagePipeHandleOwner(handle0)
+			s.inUpdate = Update_Pointer{handleOwner}
 		} else {
-			if err := s.inUpdate.Decode(decoder); err != nil {
-				return err
-			}
+			return &bindings.ValidationError{bindings.UnexpectedInvalidHandle, "unexpected invalid handle"}
 		}
 	}
 	if err := decoder.Finish(); err != nil {
@@ -1130,12 +1018,12 @@
 	return nil
 }
 
-func (p *ScanHandler_Proxy) Update(inUpdate ScanUpdate) (err error) {
-	payload := &scanHandler_Update_Params{
+func (p *ScanHandler_Proxy) OnUpdate(inUpdate Update_Pointer) (err error) {
+	payload := &scanHandler_OnUpdate_Params{
 		inUpdate,
 	}
 	header := bindings.MessageHeader{
-		Type:  scanHandler_Update_Name,
+		Type:  scanHandler_OnUpdate_Name,
 		Flags: bindings.MessageNoFlag,
 	}
 	var message *bindings.Message
@@ -1186,17 +1074,17 @@
 
 func (s *scanHandler_Stub) Accept(message *bindings.Message) (err error) {
 	switch message.Header.Type {
-	case scanHandler_Update_Name:
+	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_Update_Params
+		var request scanHandler_OnUpdate_Params
 		if err := message.DecodePayload(&request); err != nil {
 			return err
 		}
-		err = s.impl.Update(request.inUpdate)
+		err = s.impl.OnUpdate(request.inUpdate)
 		if err != nil {
 			return
 		}
@@ -1209,34 +1097,1372 @@
 	return
 }
 
-type Service struct {
-	InstanceId    *string
-	InstanceName  *string
-	InterfaceName string
-	Attrs         *map[string]string
-	Addrs         []string
-	Attachments   *map[string][]uint8
+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)
 }
 
-func (s *Service) Encode(encoder *bindings.Encoder) error {
-	encoder.StartStruct(48, 0)
-	if s.InstanceId == nil {
-		encoder.WriteNullPointer()
-	} else {
-		if err := encoder.WritePointer(); err != nil {
+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)
+}
+
+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
 		}
-		if err := encoder.WriteString((*s.InstanceId)); err != nil {
+		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 s.InstanceName == nil {
+	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
 		}
-		if err := encoder.WriteString((*s.InstanceName)); err != nil {
+		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
 		}
 	}
@@ -1246,7 +2472,22 @@
 	if err := encoder.WriteString(s.InterfaceName); err != nil {
 		return err
 	}
-	if s.Attrs == nil {
+	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 {
@@ -1256,7 +2497,7 @@
 		{
 			var keys0 []string
 			var values0 []string
-			for key0, value0 := range *s.Attrs {
+			for key0, value0 := range *s.Attributes {
 				keys0 = append(keys0, key0)
 				values0 = append(values0, value0)
 			}
@@ -1295,21 +2536,6 @@
 			return err
 		}
 	}
-	if err := encoder.WritePointer(); err != nil {
-		return err
-	}
-	encoder.StartArray(uint32(len(s.Addrs)), 64)
-	for _, elem0 := range s.Addrs {
-		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.Attachments == nil {
 		encoder.WriteNullPointer()
 	} else {
@@ -1371,23 +2597,23 @@
 	return nil
 }
 
-var service_Versions []bindings.DataHeader = []bindings.DataHeader{
-	bindings.DataHeader{56, 0},
+var advertisement_Versions []bindings.DataHeader = []bindings.DataHeader{
+	bindings.DataHeader{48, 0},
 }
 
-func (s *Service) Decode(decoder *bindings.Decoder) error {
+func (s *Advertisement) Decode(decoder *bindings.Decoder) error {
 	header, err := decoder.StartStruct()
 	if err != nil {
 		return err
 	}
-	index := sort.Search(len(service_Versions), func(i int) bool {
-		return service_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
+	index := sort.Search(len(advertisement_Versions), func(i int) bool {
+		return advertisement_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
 	})
-	if index < len(service_Versions) {
-		if service_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
+	if index < len(advertisement_Versions) {
+		if advertisement_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
 			index--
 		}
-		expectedSize := service_Versions[index].Size
+		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),
@@ -1400,30 +2626,28 @@
 			return err
 		}
 		if pointer0 == 0 {
-			s.InstanceId = nil
+			s.Id = nil
 		} else {
-			s.InstanceId = new(string)
-			value0, err := decoder.ReadString()
+			s.Id = new([16]uint8)
+			len0, err := decoder.StartArray(8)
 			if err != nil {
 				return err
 			}
-			(*s.InstanceId) = value0
-		}
-	}
-	if header.ElementsOrVersion >= 0 {
-		pointer0, err := decoder.ReadPointer()
-		if err != nil {
-			return err
-		}
-		if pointer0 == 0 {
-			s.InstanceName = nil
-		} else {
-			s.InstanceName = new(string)
-			value0, err := decoder.ReadString()
-			if err != nil {
+			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
 			}
-			(*s.InstanceName) = value0
 		}
 	}
 	if header.ElementsOrVersion >= 0 {
@@ -1447,9 +2671,42 @@
 			return err
 		}
 		if pointer0 == 0 {
-			s.Attrs = nil
+			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
 		} else {
-			s.Attrs = new(map[string]string)
+			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
 			}
@@ -1534,40 +2791,7 @@
 			for i0 := 0; i0 < len0; i0++ {
 				map0[keys0[i0]] = values0[i0]
 			}
-			(*s.Attrs) = map0
-		}
-	}
-	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.Addrs = 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.Addrs[i0] = value1
-				}
-			}
-			if err := decoder.Finish(); err != nil {
-				return err
-			}
+			(*s.Attributes) = map0
 		}
 	}
 	if header.ElementsOrVersion >= 0 {
@@ -1682,81 +2906,10 @@
 	return nil
 }
 
-type ScanUpdate struct {
-	Service    Service
-	UpdateType UpdateType
-}
-
-func (s *ScanUpdate) Encode(encoder *bindings.Encoder) error {
-	encoder.StartStruct(16, 0)
-	if err := encoder.WritePointer(); err != nil {
-		return err
-	}
-	if err := s.Service.Encode(encoder); err != nil {
-		return err
-	}
-	if err := encoder.WriteInt32(int32(s.UpdateType)); err != nil {
-		return err
-	}
-	if err := encoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
-var scanUpdate_Versions []bindings.DataHeader = []bindings.DataHeader{
-	bindings.DataHeader{24, 0},
-}
-
-func (s *ScanUpdate) Decode(decoder *bindings.Decoder) error {
-	header, err := decoder.StartStruct()
-	if err != nil {
-		return err
-	}
-	index := sort.Search(len(scanUpdate_Versions), func(i int) bool {
-		return scanUpdate_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
-	})
-	if index < len(scanUpdate_Versions) {
-		if scanUpdate_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
-			index--
-		}
-		expectedSize := scanUpdate_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.Service.Decode(decoder); err != nil {
-				return err
-			}
-		}
-	}
-	if header.ElementsOrVersion >= 0 {
-		value0, err := decoder.ReadInt32()
-		if err != nil {
-			return err
-		}
-		s.UpdateType = UpdateType(value0)
-	}
-	if err := decoder.Finish(); err != nil {
-		return err
-	}
-	return nil
-}
-
 type Error struct {
-	Id     string
-	Action int32
-	Msg    string
+	Id         string
+	ActionCode uint32
+	Msg        string
 }
 
 func (s *Error) Encode(encoder *bindings.Encoder) error {
@@ -1767,7 +2920,7 @@
 	if err := encoder.WriteString(s.Id); err != nil {
 		return err
 	}
-	if err := encoder.WriteInt32(s.Action); err != nil {
+	if err := encoder.WriteUint32(s.ActionCode); err != nil {
 		return err
 	}
 	if err := encoder.WritePointer(); err != nil {
@@ -1821,11 +2974,11 @@
 		}
 	}
 	if header.ElementsOrVersion >= 0 {
-		value0, err := decoder.ReadInt32()
+		value0, err := decoder.ReadUint32()
 		if err != nil {
 			return err
 		}
-		s.Action = value0
+		s.ActionCode = value0
 	}
 	if header.ElementsOrVersion >= 0 {
 		pointer0, err := decoder.ReadPointer()
diff --git a/go/src/vanadium/discovery/internal/discovery.go b/go/src/vanadium/discovery/internal/discovery.go
index 949995a..a068b3b 100644
--- a/go/src/vanadium/discovery/internal/discovery.go
+++ b/go/src/vanadium/discovery/internal/discovery.go
@@ -14,220 +14,183 @@
 	"v.io/v23"
 	"v.io/v23/context"
 	"v.io/v23/discovery"
-	"v.io/v23/security"
-	"v.io/v23/verror"
 )
 
-const pkgPath = "mojo/vanadium/discovery/vanadium/discovery"
+// TODO(jhahn): Mojom 'const' is ignored in mojom.go. Remove this once it is fixed.
+const AdIdLen = 16
 
-var (
-	errInvalidInstanceId = verror.Register(pkgPath+".errInvalidInstanceId", verror.NoRetry, "{1:}{2:} instance id not valid")
-	errInvalidScanId     = verror.Register(pkgPath+".errInvalidScanId", verror.NoRetry, "{1:}{2:} scan id not valid")
-)
+// closer implements the mojom.Closer.
+type closer struct {
+	cancel func()
+}
 
-type DiscoveryCloser interface {
+func (c *closer) Close() error {
+	c.cancel()
+	return nil
+}
+
+type discoveryCloser interface {
 	mojom.Discovery
 
 	// Close closes all active tasks.
 	Close()
 }
 
-// mdiscovery is basically a thin wrapper around the Vanadium discovery API.
+// mdiscovery is a thin wrapper around the Vanadium discovery.
 type mdiscovery struct {
 	ctx *context.T
 	d   discovery.T
 
-	mu          sync.Mutex
-	activeAdvs  map[string]func() // GUARDED_BY(mu)
-	activeScans map[uint32]func() // GUARDED_BY(mu)
-	nextScanId  uint32            // GUARDED_BY(mu)
+	mu    sync.Mutex
+	stubs map[*bindings.Stub]struct{} // GUARDED_BY(mu)
 }
 
-func v2mError(err error) *mojom.Error {
-	return &mojom.Error{
-		Id:     string(verror.ErrorID(err)),
-		Action: int32(verror.Action(err)),
-		Msg:    err.Error(),
+func (d *mdiscovery) Advertise(ad mojom.Advertisement, visibility *[]string) (*[AdIdLen]uint8, *mojom.Closer_Pointer, *mojom.Error, error) {
+	// There is no way to mock _Pointer or _Request types. So we put Advertise()
+	// logic into a separate function doAdvertise() for unit testing.
+	closer, err := d.doAdvertise(&ad, visibility)
+	if err != nil {
+		return nil, nil, v2mError(err), nil
 	}
+
+	req, ptr := mojom.CreateMessagePipeForCloser()
+	stub := mojom.NewCloserStub(req, closer, bindings.GetAsyncWaiter())
+	d.serveStub(stub, closer.cancel)
+	return ad.Id, &ptr, nil, nil
 }
 
-func v2mService(s discovery.Service) mojom.Service {
-	mService := mojom.Service{
-		InterfaceName: s.InterfaceName,
-		Addrs:         s.Addrs,
-	}
-	if len(s.InstanceId) > 0 {
-		mService.InstanceId = &s.InstanceId
-	}
-	if len(s.InstanceName) > 0 {
-		mService.InstanceName = &s.InstanceName
-	}
-	if len(s.Attrs) > 0 {
-		attrs := map[string]string(s.Attrs)
-		mService.Attrs = &attrs
-	}
-	if len(s.Attachments) > 0 {
-		attachments := map[string][]byte(s.Attachments)
-		mService.Attachments = &attachments
-	}
-	return mService
-}
-
-func (d *mdiscovery) StartAdvertising(service mojom.Service, visibility *[]string) (string, *mojom.Error, error) {
-	vService := discovery.Service{
-		InterfaceName: service.InterfaceName,
-		Addrs:         service.Addrs,
-	}
-	if service.InstanceId != nil {
-		vService.InstanceId = *service.InstanceId
-	}
-	if service.InstanceName != nil {
-		vService.InstanceName = *service.InstanceName
-	}
-	if service.Attrs != nil {
-		vService.Attrs = *service.Attrs
-	}
-	if service.Attachments != nil {
-		vService.Attachments = *service.Attachments
-	}
-	var vVisibility []security.BlessingPattern
-	if visibility != nil {
-		vVisibility := make([]security.BlessingPattern, len(*visibility))
-		for i, p := range *visibility {
-			vVisibility[i] = security.BlessingPattern(p)
-		}
-	}
+func (d *mdiscovery) doAdvertise(ad *mojom.Advertisement, visibility *[]string) (*closer, error) {
+	vAd := m2vAd(ad)
+	vVisibility := m2vVisibility(visibility)
 
 	ctx, cancel := context.WithCancel(d.ctx)
-	done, err := d.d.Advertise(ctx, &vService, vVisibility)
+	done, err := d.d.Advertise(ctx, &vAd, vVisibility)
 	if err != nil {
 		cancel()
-		return "", v2mError(err), nil
+		return nil, err
 	}
+	if ad.Id == nil {
+		ad.Id = new([AdIdLen]uint8)
+	}
+	*ad.Id = vAd.Id
 	stop := func() {
 		cancel()
 		<-done
 	}
-
-	d.mu.Lock()
-	d.activeAdvs[vService.InstanceId] = stop
-	d.mu.Unlock()
-	return vService.InstanceId, nil, nil
-}
-
-func (d *mdiscovery) StopAdvertising(instanceId string) (*mojom.Error, error) {
-	d.mu.Lock()
-	stop := d.activeAdvs[instanceId]
-	delete(d.activeAdvs, instanceId)
-	d.mu.Unlock()
-	if stop == nil {
-		return v2mError(verror.New(errInvalidInstanceId, d.ctx)), nil
-	}
-	stop()
-	return nil, nil
-}
-
-func (d *mdiscovery) StartScan(query string, handlerPtr mojom.ScanHandler_Pointer) (uint32, *mojom.Error, error) {
-	// There is no way to mock _Pointer or _Request types. So we put StartScan()
-	// logic into a separate function startScan() for unit testing.
-	proxy := mojom.NewScanHandlerProxy(handlerPtr, bindings.GetAsyncWaiter())
-	return d.startScan(query, proxy)
+	return &closer{stop}, nil
 }
 
 type scanHandlerProxy interface {
-	mojom.ScanHandler
+	passUpdate(update mojom.Update) error
 	Close_Proxy()
 }
 
-func (d *mdiscovery) startScan(query string, proxy scanHandlerProxy) (uint32, *mojom.Error, error) {
+type scanHandlerProxyImpl struct {
+	*mojom.ScanHandler_Proxy
+
+	d *mdiscovery
+}
+
+func (p *scanHandlerProxyImpl) passUpdate(update mojom.Update) error {
+	req, ptr := mojom.CreateMessagePipeForUpdate()
+	stub := mojom.NewUpdateStub(req, update, bindings.GetAsyncWaiter())
+	p.d.serveStub(stub, nil)
+	return p.OnUpdate(ptr)
+}
+
+func (d *mdiscovery) Scan(query string, handlerPtr mojom.ScanHandler_Pointer) (*mojom.Closer_Pointer, *mojom.Error, error) {
+	// There is no way to mock _Pointer or _Request types. So we put Scan()
+	// logic into a separate function doScan() for unit testing.
+	proxy := mojom.NewScanHandlerProxy(handlerPtr, bindings.GetAsyncWaiter())
+	closer, err := d.doScan(query, &scanHandlerProxyImpl{proxy, d})
+	if err != nil {
+		return nil, v2mError(err), nil
+	}
+
+	req, ptr := mojom.CreateMessagePipeForCloser()
+	stub := mojom.NewCloserStub(req, closer, bindings.GetAsyncWaiter())
+	d.serveStub(stub, closer.cancel)
+	return &ptr, nil, nil
+}
+
+func (d *mdiscovery) doScan(query string, proxy scanHandlerProxy) (*closer, error) {
 	ctx, cancel := context.WithCancel(d.ctx)
 	scanCh, err := d.d.Scan(ctx, query)
 	if err != nil {
 		cancel()
 		proxy.Close_Proxy()
-		return 0, v2mError(err), nil
+		return nil, err
 	}
 
-	d.mu.Lock()
-	scanId := d.nextScanId
-	d.activeScans[scanId] = cancel
-	d.nextScanId++
-	d.mu.Unlock()
-
 	go func() {
 		defer proxy.Close_Proxy()
 
 		for update := range scanCh {
-			var mupdate mojom.ScanUpdate
-			switch u := update.(type) {
-			case discovery.UpdateFound:
-				mupdate = mojom.ScanUpdate{
-					Service:    v2mService(u.Value.Service),
-					UpdateType: mojom.UpdateType_Found,
-				}
-			case discovery.UpdateLost:
-				mupdate = mojom.ScanUpdate{
-					Service:    v2mService(u.Value.Service),
-					UpdateType: mojom.UpdateType_Lost,
-				}
-			}
-			if err := proxy.Update(mupdate); err != nil {
+			mUpdate := newMojoUpdate(ctx, update)
+			if err := proxy.passUpdate(mUpdate); err != nil {
 				return
 			}
 		}
 	}()
-
-	return scanId, nil, nil
+	return &closer{cancel}, nil
 }
 
-func (d *mdiscovery) StopScan(scanId uint32) (*mojom.Error, error) {
+func (d *mdiscovery) serveStub(stub *bindings.Stub, cleanup func()) {
 	d.mu.Lock()
-	stop := d.activeScans[scanId]
-	delete(d.activeScans, scanId)
+	d.stubs[stub] = struct{}{}
 	d.mu.Unlock()
-	if stop == nil {
-		return v2mError(verror.New(errInvalidScanId, d.ctx)), nil
-	}
-	stop()
-	return nil, nil
+
+	go func() {
+		for {
+			if err := stub.ServeRequest(); err != nil {
+				connErr, ok := err.(*bindings.ConnectionError)
+				if !ok || !connErr.Closed() {
+					d.ctx.Error(err)
+				}
+				break
+			}
+		}
+
+		d.mu.Lock()
+		delete(d.stubs, stub)
+		d.mu.Unlock()
+
+		if cleanup != nil {
+			cleanup()
+		}
+	}()
 }
 
 func (d *mdiscovery) Close() {
 	d.mu.Lock()
 	defer d.mu.Unlock()
 
-	for _, stop := range d.activeAdvs {
-		stop()
-	}
-	for _, stop := range d.activeScans {
-		stop()
+	for stub := range d.stubs {
+		stub.Close()
 	}
 }
 
 // ediscovery always returns the given error.
 type ediscovery struct{ err error }
 
-func (d *ediscovery) StartAdvertising(mojom.Service, *[]string) (string, *mojom.Error, error) {
-	return "", v2mError(d.err), nil
+func (d *ediscovery) Advertise(mojom.Advertisement, *[]string) (*[AdIdLen]uint8, *mojom.Closer_Pointer, *mojom.Error, error) {
+	return nil, nil, v2mError(d.err), nil
 }
-func (d *ediscovery) StopAdvertising(string) (*mojom.Error, error) { return v2mError(d.err), nil }
-func (d *ediscovery) StartScan(string, mojom.ScanHandler_Pointer) (uint32, *mojom.Error, error) {
-	return 0, v2mError(d.err), nil
+func (d *ediscovery) Scan(string, mojom.ScanHandler_Pointer) (*mojom.Closer_Pointer, *mojom.Error, error) {
+	return nil, v2mError(d.err), nil
 }
-func (d *ediscovery) StopScan(uint32) (*mojom.Error, error) { return v2mError(d.err), nil }
-func (d *ediscovery) Close()                                {}
+func (d *ediscovery) Close() {}
 
 // NewDiscovery returns a new Vanadium discovery instance.
-func NewDiscovery(ctx *context.T) DiscoveryCloser {
+func NewDiscovery(ctx *context.T) discoveryCloser {
 	d, err := v23.NewDiscovery(ctx)
 	if err != nil {
 		return &ediscovery{err}
 	}
 
 	return &mdiscovery{
-		ctx:         ctx,
-		d:           d,
-		activeAdvs:  make(map[string]func()),
-		activeScans: make(map[uint32]func()),
+		ctx:   ctx,
+		d:     d,
+		stubs: make(map[*bindings.Stub]struct{}),
 	}
 }
diff --git a/go/src/vanadium/discovery/internal/discovery_test.go b/go/src/vanadium/discovery/internal/discovery_test.go
index a34cc8c..93e809b 100644
--- a/go/src/vanadium/discovery/internal/discovery_test.go
+++ b/go/src/vanadium/discovery/internal/discovery_test.go
@@ -5,17 +5,13 @@
 package internal
 
 import (
-	"errors"
 	"fmt"
 	"reflect"
-	"runtime"
 	"testing"
 	"time"
 
 	mojom "mojom/vanadium/discovery"
 
-	"v.io/v23/discovery"
-
 	idiscovery "v.io/x/ref/lib/discovery"
 	dfactory "v.io/x/ref/lib/discovery/factory"
 	"v.io/x/ref/lib/discovery/plugins/mock"
@@ -30,36 +26,33 @@
 	df, _ := idiscovery.NewFactory(ctx, mock.New())
 	dfactory.InjectFactory(df)
 
-	services := []discovery.Service{
+	ads := []mojom.Advertisement{
 		{
-			InstanceId:    "123",
+			Id:            &[AdIdLen]uint8{1, 2, 3},
 			InterfaceName: "v.io/v23/a",
-			Attrs:         discovery.Attributes{"a1": "v1"},
-			Addrs:         []string{"/h1:123/x"},
+			Addresses:     []string{"/h1:123/x"},
+			Attributes:    &map[string]string{"a1": "v1"},
 		},
 		{
 			InterfaceName: "v.io/v23/b",
-			Attrs:         discovery.Attributes{"b1": "v1"},
-			Addrs:         []string{"/h1:123/y"},
+			Addresses:     []string{"/h1:123/y"},
+			Attributes:    &map[string]string{"b1": "v1"},
 		},
 	}
 
 	d1 := NewDiscovery(ctx)
+	defer d1.Close()
 
-	for i, service := range services {
-		instanceId, merr, err := d1.StartAdvertising(mkMojomService(service), nil)
-		if merr != nil || err != nil {
-			t.Fatalf("failed to advertise service: %v, %v", merr, err)
+	var adClosers []mojom.Closer
+	for i, _ := range ads {
+		closer, err := d1.(*mdiscovery).doAdvertise(&ads[i], nil)
+		if err != nil {
+			t.Fatalf("ad[%d]: failed to advertise: %v", i, err)
 		}
-		if len(instanceId) == 0 {
-			t.Errorf("service[%d]: got empty instance id", i)
+		if ads[i].Id == nil {
+			t.Errorf("ad[%d]: got nil id", i)
 		}
-
-		if len(service.InstanceId) == 0 {
-			services[i].InstanceId = instanceId
-		} else if instanceId != service.InstanceId {
-			t.Errorf("service[%d]: got instance id %v, but wanted %v", i, instanceId, service.InstanceId)
-		}
+		adClosers = append(adClosers, closer)
 	}
 
 	// Make sure none of advertisements are discoverable by the same discovery instance.
@@ -69,99 +62,76 @@
 
 	// Create a new discovery instance. All advertisements should be discovered with that.
 	d2 := NewDiscovery(ctx)
+	defer d2.Close()
 
-	if err := scanAndMatch(d2, `v.InterfaceName="v.io/v23/a"`, services[0]); err != nil {
+	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"`, services[1]); err != nil {
+
+	if err := scanAndMatch(d2, `v.InterfaceName="v.io/v23/b"`, ads[1]); err != nil {
 		t.Error(err)
 	}
-	if err := scanAndMatch(d2, "", services...); err != nil {
+	if err := scanAndMatch(d2, ``, ads...); err != nil {
 		t.Error(err)
 	}
 
 	// Open a new scan channel and consume expected advertisements first.
-	scanCh, scanStop, err := startScan(d2, `v.InterfaceName="v.io/v23/a"`)
+	scanCh, scanCloser, err := scan(d2, `v.InterfaceName="v.io/v23/a"`)
 	if err != nil {
 		t.Fatal(err)
 	}
-	defer scanStop()
+	defer scanCloser.Close()
 	update := <-scanCh
-	if !matchFound([]mojom.ScanUpdate{update}, services[0]) {
+	if !matchFound([]mojom.Update{update}, ads[0]) {
 		t.Errorf("unexpected scan: %v", update)
 	}
 
 	// Make sure scan returns the lost advertisement when advertising is stopped.
-	d1.StopAdvertising(services[0].InstanceId)
+	adClosers[0].Close()
 
 	update = <-scanCh
-	if !matchLost([]mojom.ScanUpdate{update}, services[0]) {
+	if !matchLost([]mojom.Update{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"`, services[1]); err != nil {
+	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 service.
-	d1.StopAdvertising(services[1].InstanceId)
+	// Stop advertising the remaining one; Shouldn't discover any advertisements.
+	adClosers[1].Close()
 	if err := scanAndMatch(d2, ""); err != nil {
 		t.Error(err)
 	}
 }
 
 type mockScanHandler struct {
-	ch chan mojom.ScanUpdate
+	ch chan mojom.Update
 }
 
-func (m *mockScanHandler) Update(u mojom.ScanUpdate) error {
+func (m *mockScanHandler) Close_Proxy() { close(m.ch) }
+func (m *mockScanHandler) passUpdate(u mojom.Update) error {
 	m.ch <- u
 	return nil
 }
-func (m *mockScanHandler) Close_Proxy() { close(m.ch) }
 
-func startScan(d mojom.Discovery, query string) (<-chan mojom.ScanUpdate, func(), error) {
-	ch := make(chan mojom.ScanUpdate)
-	scanId, merr, err := d.(*mdiscovery).startScan(query, &mockScanHandler{ch})
-	if merr != nil {
-		return nil, nil, errors.New(merr.Msg)
-	}
+func scan(d mojom.Discovery, query string) (<-chan mojom.Update, mojom.Closer, error) {
+	ch := make(chan mojom.Update)
+	closer, err := d.(*mdiscovery).doScan(query, &mockScanHandler{ch})
 	if err != nil {
 		return nil, nil, err
 	}
-
-	stop := func() { d.StopScan(scanId) }
-	return ch, stop, nil
+	return ch, closer, nil
 }
 
-func scan(d mojom.Discovery, query string) ([]mojom.ScanUpdate, error) {
-	ch, stop, err := startScan(d, query)
-	if err != nil {
-		return nil, err
-	}
-	defer stop()
+func scanAndMatch(d mojom.Discovery, query string, wants ...mojom.Advertisement) error {
+	const timeout = 10 * time.Second
 
-	var updates []mojom.ScanUpdate
-	for {
-		select {
-		case update := <-ch:
-			updates = append(updates, update)
-		case <-time.After(5 * time.Millisecond):
-			return updates, nil
-		}
-	}
-}
-
-func scanAndMatch(d mojom.Discovery, query string, wants ...discovery.Service) error {
-	const timeout = 3 * time.Second
-
-	var updates []mojom.ScanUpdate
+	var updates []mojom.Update
 	for now := time.Now(); time.Since(now) < timeout; {
-		runtime.Gosched()
-
 		var err error
-		updates, err = scan(d, query)
+		updates, err = doScan(d, query, len(wants))
 		if err != nil {
 			return err
 		}
@@ -172,47 +142,58 @@
 	return fmt.Errorf("Match failed; got %v, but wanted %v", updates, wants)
 }
 
-func match(updates []mojom.ScanUpdate, updateType mojom.UpdateType, wants ...discovery.Service) bool {
-	for _, want := range wants {
-		matched := false
-		for i, update := range updates {
-			if update.UpdateType == updateType && reflect.DeepEqual(update.Service, mkMojomService(want)) {
-				updates = append(updates[:i], updates[i+1:]...)
-				matched = true
-				break
-			}
+func doScan(d mojom.Discovery, query string, expectedUpdates int) ([]mojom.Update, error) {
+	scanCh, closer, err := scan(d, query)
+	if err != nil {
+		return nil, err
+	}
+	defer closer.Close()
+
+	updates := make([]mojom.Update, 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 = 5 * time.Second
 		}
-		if !matched {
+
+		select {
+		case update := <-scanCh:
+			updates = append(updates, update)
+		case <-time.After(timeout):
+			return updates, nil
+		}
+	}
+}
+
+func matchFound(updates []mojom.Update, wants ...mojom.Advertisement) bool {
+	return match(updates, false, wants...)
+}
+
+func matchLost(updates []mojom.Update, wants ...mojom.Advertisement) bool {
+	return match(updates, true, wants...)
+}
+
+func match(updates []mojom.Update, lost bool, wants ...mojom.Advertisement) bool {
+	updateMap := make(map[[AdIdLen]uint8]mojom.Update)
+	for _, update := range updates {
+		id, _ := update.GetId()
+		updateMap[id] = update
+	}
+
+	for _, want := range wants {
+		update := updateMap[*want.Id]
+		if update == nil {
 			return false
 		}
+		if got, _ := update.IsLost(); got != lost {
+			return false
+		}
+		if got, _ := update.GetAdvertisement(); !reflect.DeepEqual(got, want) {
+			return false
+		}
+		delete(updateMap, *want.Id)
 	}
-	return len(updates) == 0
-}
-
-func matchFound(updates []mojom.ScanUpdate, wants ...discovery.Service) bool {
-	return match(updates, mojom.UpdateType_Found, wants...)
-}
-
-func matchLost(updates []mojom.ScanUpdate, wants ...discovery.Service) bool {
-	return match(updates, mojom.UpdateType_Lost, wants...)
-}
-
-func mkMojomService(service discovery.Service) mojom.Service {
-	mservice := mojom.Service{
-		InstanceId:    &service.InstanceId,
-		InterfaceName: service.InterfaceName,
-		Addrs:         service.Addrs,
-	}
-	if len(service.InstanceName) > 0 {
-		mservice.InstanceName = &service.InstanceName
-	}
-	if len(service.Attrs) > 0 {
-		attrs := map[string]string(service.Attrs)
-		mservice.Attrs = &attrs
-	}
-	if len(service.Attachments) > 0 {
-		attachments := map[string][]byte(service.Attachments)
-		mservice.Attachments = &attachments
-	}
-	return mservice
+	return len(updateMap) == 0
 }
diff --git a/go/src/vanadium/discovery/internal/update.go b/go/src/vanadium/discovery/internal/update.go
new file mode 100644
index 0000000..1732562
--- /dev/null
+++ b/go/src/vanadium/discovery/internal/update.go
@@ -0,0 +1,54 @@
+// 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 internal
+
+import (
+	"fmt"
+
+	"mojo/public/go/system"
+
+	mojom "mojom/vanadium/discovery"
+
+	"v.io/v23/context"
+	"v.io/v23/discovery"
+)
+
+type mupdate struct {
+	ctx *context.T
+	u   discovery.Update
+}
+
+func (u *mupdate) IsLost() (bool, error)                    { return u.u.IsLost(), nil }
+func (u *mupdate) GetId() ([AdIdLen]uint8, error)           { return u.u.Id(), nil }
+func (u *mupdate) GetInterfaceName() (string, error)        { return u.u.InterfaceName(), nil }
+func (u *mupdate) GetAddresses() ([]string, error)          { return u.u.Addresses(), nil }
+func (u *mupdate) GetAttribute(name string) (string, error) { return u.u.Attribute(name), nil }
+
+func (u *mupdate) GetAttachment(name string) (system.ConsumerHandle, error) {
+	r, producer, consumer := system.GetCore().CreateDataPipe(nil)
+	if r != system.MOJO_RESULT_OK {
+		return nil, fmt.Errorf("can't create data pipe: %v", r)
+	}
+	go func() {
+		defer producer.Close()
+
+		dataOrErr := <-u.u.Attachment(u.ctx, name)
+		if dataOrErr.Error != nil {
+			u.ctx.Error(dataOrErr.Error)
+		} else {
+			producer.WriteData([]byte(dataOrErr.Data), system.MOJO_WRITE_DATA_FLAG_ALL_OR_NONE)
+		}
+	}()
+	return consumer, nil
+}
+
+func (u *mupdate) GetAdvertisement() (mojom.Advertisement, error) {
+	ad := u.u.Advertisement()
+	return v2mAd(&ad), nil
+}
+
+func newMojoUpdate(ctx *context.T, update discovery.Update) mojom.Update {
+	return &mupdate{ctx, update}
+}
diff --git a/go/src/vanadium/discovery/internal/update_test.go b/go/src/vanadium/discovery/internal/update_test.go
new file mode 100644
index 0000000..05a2d8f
--- /dev/null
+++ b/go/src/vanadium/discovery/internal/update_test.go
@@ -0,0 +1,66 @@
+// 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 internal
+
+import (
+	"math/rand"
+	"reflect"
+	"testing"
+	"testing/quick"
+
+	"v.io/v23/context"
+	"v.io/v23/discovery"
+)
+
+type mockUpdate struct {
+	lost bool
+	ad   discovery.Advertisement
+}
+
+func (u *mockUpdate) IsLost() bool                                                        { return u.lost }
+func (u *mockUpdate) Id() discovery.AdId                                                  { return u.ad.Id }
+func (u *mockUpdate) InterfaceName() string                                               { return u.ad.InterfaceName }
+func (u *mockUpdate) Addresses() []string                                                 { return u.ad.Addresses }
+func (u *mockUpdate) Attribute(name string) string                                        { return u.ad.Attributes[name] }
+func (u *mockUpdate) Attachment(ctx *context.T, name string) <-chan discovery.DataOrError { return nil }
+func (u *mockUpdate) Advertisement() discovery.Advertisement                              { return u.ad }
+
+func TestUpdate(t *testing.T) {
+	rand := rand.New(rand.NewSource(0))
+	for i := 0; i < 10; i++ {
+		v, ok := quick.Value(reflect.TypeOf(discovery.Advertisement{}), rand)
+		if !ok {
+			t.Fatal("failed to populate value")
+		}
+
+		lost := rand.Int()%2 == 0
+		ad := v.Interface().(discovery.Advertisement)
+
+		mUpdate := newMojoUpdate(nil, &mockUpdate{lost, ad})
+
+		if got, _ := mUpdate.IsLost(); got != lost {
+			t.Errorf("IsLost: got %v, but want %v", got, lost)
+		}
+		if got, _ := mUpdate.GetId(); got != ad.Id {
+			t.Errorf("Id: got %v, but want %v", got, ad.Id)
+		}
+		if got, _ := mUpdate.GetInterfaceName(); got != ad.InterfaceName {
+			t.Errorf("InterfaceName: got %v, but want %v", got, ad.InterfaceName)
+		}
+		if got, _ := mUpdate.GetAddresses(); !reflect.DeepEqual(got, ad.Addresses) {
+			t.Errorf("Addresses: got %v, but want %v", got, ad.Addresses)
+		}
+		for k, v := range ad.Attributes {
+			if got, _ := mUpdate.GetAttribute(k); got != v {
+				t.Errorf("Attributes[%s]: got %v, but want %v", got, v)
+			}
+		}
+
+		mAd := v2mAd(&ad)
+		if got, _ := mUpdate.GetAdvertisement(); !reflect.DeepEqual(got, mAd) {
+			t.Errorf("Advertisement: got %v, but want %v", got, mAd)
+		}
+	}
+}
diff --git a/go/src/vanadium/discovery/internal/util.go b/go/src/vanadium/discovery/internal/util.go
new file mode 100644
index 0000000..785b102
--- /dev/null
+++ b/go/src/vanadium/discovery/internal/util.go
@@ -0,0 +1,69 @@
+// 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 internal
+
+import (
+	mojom "mojom/vanadium/discovery"
+
+	"v.io/v23/discovery"
+	"v.io/v23/security"
+	"v.io/v23/verror"
+)
+
+func v2mError(err error) *mojom.Error {
+	return &mojom.Error{
+		Id:         string(verror.ErrorID(err)),
+		ActionCode: uint32(verror.Action(err)),
+		Msg:        err.Error(),
+	}
+}
+
+func v2mAd(ad *discovery.Advertisement) mojom.Advertisement {
+	mAd := mojom.Advertisement{
+		InterfaceName: ad.InterfaceName,
+		Addresses:     ad.Addresses,
+	}
+	if ad.Id.IsValid() {
+		mAd.Id = new([AdIdLen]uint8)
+		*mAd.Id = ad.Id
+	}
+	if len(ad.Attributes) > 0 {
+		attributes := map[string]string(ad.Attributes)
+		mAd.Attributes = &attributes
+	}
+	if len(ad.Attachments) > 0 {
+		attachments := map[string][]byte(ad.Attachments)
+		mAd.Attachments = &attachments
+	}
+	return mAd
+}
+
+func m2vAd(ad *mojom.Advertisement) discovery.Advertisement {
+	vAd := discovery.Advertisement{
+		InterfaceName: ad.InterfaceName,
+		Addresses:     ad.Addresses,
+	}
+	if ad.Id != nil {
+		vAd.Id = *ad.Id
+	}
+	if ad.Attributes != nil {
+		vAd.Attributes = *ad.Attributes
+	}
+	if ad.Attachments != nil {
+		vAd.Attachments = *ad.Attachments
+	}
+	return vAd
+}
+
+func m2vVisibility(visibility *[]string) []security.BlessingPattern {
+	if visibility == nil {
+		return nil
+	}
+	vVisibility := make([]security.BlessingPattern, len(*visibility))
+	for i, p := range *visibility {
+		vVisibility[i] = security.BlessingPattern(p)
+	}
+	return vVisibility
+}
diff --git a/go/src/vanadium/discovery/internal/util_test.go b/go/src/vanadium/discovery/internal/util_test.go
new file mode 100644
index 0000000..72211b4
--- /dev/null
+++ b/go/src/vanadium/discovery/internal/util_test.go
@@ -0,0 +1,38 @@
+// 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 internal
+
+import (
+	"math/rand"
+	"reflect"
+	"testing"
+	"testing/quick"
+
+	"v.io/v23/discovery"
+)
+
+func TestConvAd(t *testing.T) {
+	rand := rand.New(rand.NewSource(0))
+	for i := 0; i < 10; i++ {
+		v, ok := quick.Value(reflect.TypeOf(discovery.Advertisement{}), rand)
+		if !ok {
+			t.Fatal("failed to populate value")
+		}
+		ad := v.Interface().(discovery.Advertisement)
+		// Make reflect.DeepEqual happy in comparing nil and empty.
+		if len(ad.Attributes) == 0 {
+			ad.Attributes = nil
+		}
+		if len(ad.Attachments) == 0 {
+			ad.Attachments = nil
+		}
+
+		mAd := v2mAd(&ad)
+		vAd := m2vAd(&mAd)
+		if !reflect.DeepEqual(vAd, ad) {
+			t.Errorf("Convert: got %v, but want %v", vAd, ad)
+		}
+	}
+}
diff --git a/java/generated-src/io/v/mojo/discovery/Service.java b/java/generated-src/io/v/mojo/discovery/Advertisement.java
similarity index 79%
rename from java/generated-src/io/v/mojo/discovery/Service.java
rename to java/generated-src/io/v/mojo/discovery/Advertisement.java
index 02b1510..e592867 100644
--- a/java/generated-src/io/v/mojo/discovery/Service.java
+++ b/java/generated-src/io/v/mojo/discovery/Advertisement.java
@@ -10,51 +10,59 @@
 
 package io.v.mojo.discovery;
 
-public final class Service extends org.chromium.mojo.bindings.Struct {
+public final class Advertisement extends org.chromium.mojo.bindings.Struct {
 
-    private static final int STRUCT_SIZE = 56;
-    private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(56, 0)};
+    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 String instanceId;
-    public String instanceName;
+    public static final int ID_LEN = (int) 16L;
+
+    public byte[] id;
     public String interfaceName;
-    public java.util.Map<String, String> attrs;
-    public String[] addrs;
+    public String[] addresses;
+    public java.util.Map<String, String> attributes;
     public java.util.Map<String, byte[]> attachments;
 
-    private Service(int version) {
+    private Advertisement(int version) {
         super(STRUCT_SIZE, version);
     }
 
-    public Service() {
+    public Advertisement() {
         this(0);
     }
 
-    public static Service deserialize(org.chromium.mojo.bindings.Message message) {
+    public static Advertisement deserialize(org.chromium.mojo.bindings.Message message) {
         return decode(new org.chromium.mojo.bindings.Decoder(message));
     }
 
     @SuppressWarnings("unchecked")
-    public static Service decode(org.chromium.mojo.bindings.Decoder decoder0) {
+    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);
-        Service result = new Service(mainDataHeader.elementsOrVersion);
+        Advertisement result = new Advertisement(mainDataHeader.elementsOrVersion);
         if (mainDataHeader.elementsOrVersion >= 0) {
-            result.instanceId = decoder0.readString(8, true);
+            result.id = decoder0.readBytes(8, org.chromium.mojo.bindings.BindingsHelper.ARRAY_NULLABLE, 16);
         }
         if (mainDataHeader.elementsOrVersion >= 0) {
-            result.instanceName = decoder0.readString(16, true);
+            result.interfaceName = decoder0.readString(16, false);
         }
         if (mainDataHeader.elementsOrVersion >= 0) {
-            result.interfaceName = decoder0.readString(24, false);
+            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.attrs = null;
+                result.attributes = null;
             } else {
                 decoder1.readDataHeaderForMap();
                 String[] keys0;
@@ -79,24 +87,14 @@
                         }
                     }
                 }
-                result.attrs = new java.util.HashMap<String, String>();
+                result.attributes = new java.util.HashMap<String, String>();
                 for (int index0 = 0; index0 < keys0.length; ++index0) {
-                    result.attrs.put(keys0[index0],  values0[index0]);
+                    result.attributes.put(keys0[index0],  values0[index0]);
                 }
             }
         }
         if (mainDataHeader.elementsOrVersion >= 0) {
-            org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(40, false);
-            {
-                org.chromium.mojo.bindings.DataHeader si1 = decoder1.readDataHeaderForPointerArray(org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
-                result.addrs = new String[si1.elementsOrVersion];
-                for (int i1 = 0; i1 < si1.elementsOrVersion; ++i1) {
-                    result.addrs[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(48, true);
+            org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(40, true);
             if (decoder1 == null) {
                 result.attachments = null;
             } else {
@@ -136,18 +134,25 @@
     @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, true);
-        encoder0.encode(instanceName, 16, true);
-        encoder0.encode(interfaceName, 24, false);
-        if (attrs == null) {
+        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 = attrs.size();
+            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 : attrs.entrySet()) {
+            for (java.util.Map.Entry<String, String> entry0 : attributes.entrySet()) {
                 keys0[index0] = entry0.getKey();
                 values0[index0] = entry0.getValue();
                 ++index0;
@@ -165,18 +170,10 @@
                 }
             }
         }
-        if (addrs == null) {
-            encoder0.encodeNullPointer(40, false);
-        } else {
-            org.chromium.mojo.bindings.Encoder encoder1 = encoder0.encodePointerArray(addrs.length, 40, org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
-            for (int i0 = 0; i0 < addrs.length; ++i0) {
-                encoder1.encode(addrs[i0], org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i0, false);
-            }
-        }
         if (attachments == null) {
-            encoder0.encodeNullPointer(48, true);
+            encoder0.encodeNullPointer(40, true);
         } else {
-            org.chromium.mojo.bindings.Encoder encoder1 = encoder0.encoderForMap(48);
+            org.chromium.mojo.bindings.Encoder encoder1 = encoder0.encoderForMap(40);
             int size0 = attachments.size();
             String[] keys0 = new String[size0];
             byte[][] values0 = new byte[size0][];
@@ -212,16 +209,14 @@
             return false;
         if (getClass() != object.getClass())
             return false;
-        Service other = (Service) object;
-        if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.instanceId, other.instanceId))
-            return false;
-        if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.instanceName, other.instanceName))
+        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 (!org.chromium.mojo.bindings.BindingsHelper.equals(this.attrs, other.attrs))
+        if (!java.util.Arrays.deepEquals(this.addresses, other.addresses))
             return false;
-        if (!java.util.Arrays.deepEquals(this.addrs, other.addrs))
+        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;
@@ -235,11 +230,10 @@
     public int hashCode() {
         final int prime = 31;
         int result = prime + getClass().hashCode();
-        result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(instanceId);
-        result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(instanceName);
+        result = prime * result + java.util.Arrays.hashCode(id);
         result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(interfaceName);
-        result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(attrs);
-        result = prime * result + java.util.Arrays.deepHashCode(addrs);
+        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
new file mode 100644
index 0000000..33d8818
--- /dev/null
+++ b/java/generated-src/io/v/mojo/discovery/Closer.java
@@ -0,0 +1,23 @@
+// 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
new file mode 100644
index 0000000..005d2e8
--- /dev/null
+++ b/java/generated-src/io/v/mojo/discovery/Closer_Internal.java
@@ -0,0 +1,290 @@
+// 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
index 257529c..204ee07 100644
--- a/java/generated-src/io/v/mojo/discovery/Discovery.java
+++ b/java/generated-src/io/v/mojo/discovery/Discovery.java
@@ -17,16 +17,10 @@
 
     NamedManager<Discovery, Discovery.Proxy> MANAGER = Discovery_Internal.MANAGER;
 
-    void startAdvertising(Service service, String[] visibility, StartAdvertisingResponse callback);
-    interface StartAdvertisingResponse extends org.chromium.mojo.bindings.Callbacks.Callback2<String, Error> { }
+    void advertise(Advertisement ad, String[] visibility, AdvertiseResponse callback);
+    interface AdvertiseResponse extends org.chromium.mojo.bindings.Callbacks.Callback3<byte[], Closer, Error> { }
 
-    void stopAdvertising(String instanceId, StopAdvertisingResponse callback);
-    interface StopAdvertisingResponse extends org.chromium.mojo.bindings.Callbacks.Callback1<Error> { }
-
-    void startScan(String query, ScanHandler handler, StartScanResponse callback);
-    interface StartScanResponse extends org.chromium.mojo.bindings.Callbacks.Callback2<Integer, Error> { }
-
-    void stopScan(int scanId, StopScanResponse callback);
-    interface StopScanResponse extends org.chromium.mojo.bindings.Callbacks.Callback1<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
index 1728856..3b9d0e0 100644
--- a/java/generated-src/io/v/mojo/discovery/Discovery_Internal.java
+++ b/java/generated-src/io/v/mojo/discovery/Discovery_Internal.java
@@ -37,10 +37,8 @@
         }
     };
 
-    private static final int START_ADVERTISING_ORDINAL = 0;
-    private static final int STOP_ADVERTISING_ORDINAL = 1;
-    private static final int START_SCAN_ORDINAL = 2;
-    private static final int STOP_SCAN_ORDINAL = 3;
+    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 {
 
@@ -50,61 +48,33 @@
         }
 
         @Override
-        public void startAdvertising(Service service, String[] visibility, StartAdvertisingResponse callback) {
-            DiscoveryStartAdvertisingParams _message = new DiscoveryStartAdvertisingParams();
-            _message.service = service;
+        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(
-                                    START_ADVERTISING_ORDINAL,
+                                    ADVERTISE_ORDINAL,
                                     org.chromium.mojo.bindings.MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG,
                                     0)),
-                    new DiscoveryStartAdvertisingResponseParamsForwardToCallback(callback));
+                    new DiscoveryAdvertiseResponseParamsForwardToCallback(callback));
         }
 
         @Override
-        public void stopAdvertising(String instanceId, StopAdvertisingResponse callback) {
-            DiscoveryStopAdvertisingParams _message = new DiscoveryStopAdvertisingParams();
-            _message.instanceId = instanceId;
-            getProxyHandler().getMessageReceiver().acceptWithResponder(
-                    _message.serializeWithHeader(
-                            getProxyHandler().getCore(),
-                            new org.chromium.mojo.bindings.MessageHeader(
-                                    STOP_ADVERTISING_ORDINAL,
-                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG,
-                                    0)),
-                    new DiscoveryStopAdvertisingResponseParamsForwardToCallback(callback));
-        }
-
-        @Override
-        public void startScan(String query, ScanHandler handler, StartScanResponse callback) {
-            DiscoveryStartScanParams _message = new DiscoveryStartScanParams();
+        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(
-                                    START_SCAN_ORDINAL,
+                                    SCAN_ORDINAL,
                                     org.chromium.mojo.bindings.MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG,
                                     0)),
-                    new DiscoveryStartScanResponseParamsForwardToCallback(callback));
-        }
-
-        @Override
-        public void stopScan(int scanId, StopScanResponse callback) {
-            DiscoveryStopScanParams _message = new DiscoveryStopScanParams();
-            _message.scanId = scanId;
-            getProxyHandler().getMessageReceiver().acceptWithResponder(
-                    _message.serializeWithHeader(
-                            getProxyHandler().getCore(),
-                            new org.chromium.mojo.bindings.MessageHeader(
-                                    STOP_SCAN_ORDINAL,
-                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG,
-                                    0)),
-                    new DiscoveryStopScanResponseParamsForwardToCallback(callback));
+                    new DiscoveryScanResponseParamsForwardToCallback(callback));
         }
 
     }
@@ -150,28 +120,16 @@
                     case org.chromium.mojo.bindings.InterfaceControlMessagesConstants.RUN_MESSAGE_ID:
                         return org.chromium.mojo.bindings.InterfaceControlMessagesHelper.handleRun(
                                 getCore(), Discovery_Internal.MANAGER, messageWithHeader, receiver);
-                    case START_ADVERTISING_ORDINAL: {
-                        DiscoveryStartAdvertisingParams data =
-                                DiscoveryStartAdvertisingParams.deserialize(messageWithHeader.getPayload());
-                        getImpl().startAdvertising(data.service, data.visibility, new DiscoveryStartAdvertisingResponseParamsProxyToResponder(getCore(), receiver, header.getRequestId()));
+                    case ADVERTISE_ORDINAL: {
+                        DiscoveryAdvertiseParams data =
+                                DiscoveryAdvertiseParams.deserialize(messageWithHeader.getPayload());
+                        getImpl().advertise(data.ad, data.visibility, new DiscoveryAdvertiseResponseParamsProxyToResponder(getCore(), receiver, header.getRequestId()));
                         return true;
                     }
-                    case STOP_ADVERTISING_ORDINAL: {
-                        DiscoveryStopAdvertisingParams data =
-                                DiscoveryStopAdvertisingParams.deserialize(messageWithHeader.getPayload());
-                        getImpl().stopAdvertising(data.instanceId, new DiscoveryStopAdvertisingResponseParamsProxyToResponder(getCore(), receiver, header.getRequestId()));
-                        return true;
-                    }
-                    case START_SCAN_ORDINAL: {
-                        DiscoveryStartScanParams data =
-                                DiscoveryStartScanParams.deserialize(messageWithHeader.getPayload());
-                        getImpl().startScan(data.query, data.handler, new DiscoveryStartScanResponseParamsProxyToResponder(getCore(), receiver, header.getRequestId()));
-                        return true;
-                    }
-                    case STOP_SCAN_ORDINAL: {
-                        DiscoveryStopScanParams data =
-                                DiscoveryStopScanParams.deserialize(messageWithHeader.getPayload());
-                        getImpl().stopScan(data.scanId, new DiscoveryStopScanResponseParamsProxyToResponder(getCore(), receiver, header.getRequestId()));
+                    case SCAN_ORDINAL: {
+                        DiscoveryScanParams data =
+                                DiscoveryScanParams.deserialize(messageWithHeader.getPayload());
+                        getImpl().scan(data.query, data.handler, new DiscoveryScanResponseParamsProxyToResponder(getCore(), receiver, header.getRequestId()));
                         return true;
                     }
                     default:
@@ -184,37 +142,37 @@
         }
     }
 
-    static final class DiscoveryStartAdvertisingParams extends org.chromium.mojo.bindings.Struct {
+    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 Service service;
+        public Advertisement ad;
         public String[] visibility;
     
-        private DiscoveryStartAdvertisingParams(int version) {
+        private DiscoveryAdvertiseParams(int version) {
             super(STRUCT_SIZE, version);
         }
     
-        public DiscoveryStartAdvertisingParams() {
+        public DiscoveryAdvertiseParams() {
             this(0);
         }
     
-        public static DiscoveryStartAdvertisingParams deserialize(org.chromium.mojo.bindings.Message message) {
+        public static DiscoveryAdvertiseParams deserialize(org.chromium.mojo.bindings.Message message) {
             return decode(new org.chromium.mojo.bindings.Decoder(message));
         }
     
         @SuppressWarnings("unchecked")
-        public static DiscoveryStartAdvertisingParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
+        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);
-            DiscoveryStartAdvertisingParams result = new DiscoveryStartAdvertisingParams(mainDataHeader.elementsOrVersion);
+            DiscoveryAdvertiseParams result = new DiscoveryAdvertiseParams(mainDataHeader.elementsOrVersion);
             if (mainDataHeader.elementsOrVersion >= 0) {
                 org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(8, false);
-                result.service = Service.decode(decoder1);
+                result.ad = Advertisement.decode(decoder1);
             }
             if (mainDataHeader.elementsOrVersion >= 0) {
                 org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(16, true);
@@ -235,7 +193,7 @@
         @Override
         protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
             org.chromium.mojo.bindings.Encoder encoder0 = encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
-            encoder0.encode(service, 8, false);
+            encoder0.encode(ad, 8, false);
             if (visibility == null) {
                 encoder0.encodeNullPointer(16, true);
             } else {
@@ -257,8 +215,8 @@
                 return false;
             if (getClass() != object.getClass())
                 return false;
-            DiscoveryStartAdvertisingParams other = (DiscoveryStartAdvertisingParams) object;
-            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.service, other.service))
+            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;
@@ -272,45 +230,49 @@
         public int hashCode() {
             final int prime = 31;
             int result = prime + getClass().hashCode();
-            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(service);
+            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(ad);
             result = prime * result + java.util.Arrays.deepHashCode(visibility);
             return result;
         }
     }
 
-    static final class DiscoveryStartAdvertisingResponseParams extends org.chromium.mojo.bindings.Struct {
+    static final class DiscoveryAdvertiseResponseParams 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 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 instanceId;
+        public byte[] instanceId;
+        public Closer closer;
         public Error err;
     
-        private DiscoveryStartAdvertisingResponseParams(int version) {
+        private DiscoveryAdvertiseResponseParams(int version) {
             super(STRUCT_SIZE, version);
         }
     
-        public DiscoveryStartAdvertisingResponseParams() {
+        public DiscoveryAdvertiseResponseParams() {
             this(0);
         }
     
-        public static DiscoveryStartAdvertisingResponseParams deserialize(org.chromium.mojo.bindings.Message message) {
+        public static DiscoveryAdvertiseResponseParams deserialize(org.chromium.mojo.bindings.Message message) {
             return decode(new org.chromium.mojo.bindings.Decoder(message));
         }
     
         @SuppressWarnings("unchecked")
-        public static DiscoveryStartAdvertisingResponseParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
+        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);
-            DiscoveryStartAdvertisingResponseParams result = new DiscoveryStartAdvertisingResponseParams(mainDataHeader.elementsOrVersion);
+            DiscoveryAdvertiseResponseParams result = new DiscoveryAdvertiseResponseParams(mainDataHeader.elementsOrVersion);
             if (mainDataHeader.elementsOrVersion >= 0) {
-                result.instanceId = decoder0.readString(8, false);
+                result.instanceId = decoder0.readBytes(8, org.chromium.mojo.bindings.BindingsHelper.ARRAY_NULLABLE, 16);
             }
             if (mainDataHeader.elementsOrVersion >= 0) {
-                org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(16, true);
+                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;
@@ -320,8 +282,9 @@
         @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, false);
-            encoder0.encode(err, 16, true);
+            encoder0.encode(instanceId, 8, org.chromium.mojo.bindings.BindingsHelper.ARRAY_NULLABLE, 16);
+            encoder0.encode(closer, 16, true, Closer.MANAGER);
+            encoder0.encode(err, 24, true);
         }
     
         /**
@@ -335,8 +298,10 @@
                 return false;
             if (getClass() != object.getClass())
                 return false;
-            DiscoveryStartAdvertisingResponseParams other = (DiscoveryStartAdvertisingResponseParams) object;
-            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.instanceId, other.instanceId))
+            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;
@@ -350,17 +315,18 @@
         public int hashCode() {
             final int prime = 31;
             int result = prime + getClass().hashCode();
-            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(instanceId);
+            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 DiscoveryStartAdvertisingResponseParamsForwardToCallback extends org.chromium.mojo.bindings.SideEffectFreeCloseable
+    static class DiscoveryAdvertiseResponseParamsForwardToCallback extends org.chromium.mojo.bindings.SideEffectFreeCloseable
             implements org.chromium.mojo.bindings.MessageReceiver {
-        private final Discovery.StartAdvertisingResponse mCallback;
+        private final Discovery.AdvertiseResponse mCallback;
 
-        DiscoveryStartAdvertisingResponseParamsForwardToCallback(Discovery.StartAdvertisingResponse callback) {
+        DiscoveryAdvertiseResponseParamsForwardToCallback(Discovery.AdvertiseResponse callback) {
             this.mCallback = callback;
         }
 
@@ -370,12 +336,12 @@
                 org.chromium.mojo.bindings.ServiceMessage messageWithHeader =
                         message.asServiceMessage();
                 org.chromium.mojo.bindings.MessageHeader header = messageWithHeader.getHeader();
-                if (!header.validateHeader(START_ADVERTISING_ORDINAL,
+                if (!header.validateHeader(ADVERTISE_ORDINAL,
                                            org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG)) {
                     return false;
                 }
-                DiscoveryStartAdvertisingResponseParams response = DiscoveryStartAdvertisingResponseParams.deserialize(messageWithHeader.getPayload());
-                mCallback.call(response.instanceId, response.err);
+                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;
@@ -383,13 +349,13 @@
         }
     }
 
-    static class DiscoveryStartAdvertisingResponseParamsProxyToResponder implements Discovery.StartAdvertisingResponse {
+    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;
 
-        DiscoveryStartAdvertisingResponseParamsProxyToResponder(
+        DiscoveryAdvertiseResponseParamsProxyToResponder(
                 org.chromium.mojo.system.Core core,
                 org.chromium.mojo.bindings.MessageReceiver messageReceiver,
                 long requestId) {
@@ -399,218 +365,23 @@
         }
 
         @Override
-        public void call(String instanceId, Error err) {
-            DiscoveryStartAdvertisingResponseParams _response = new DiscoveryStartAdvertisingResponseParams();
+        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(
-                                    START_ADVERTISING_ORDINAL,
+                                    ADVERTISE_ORDINAL,
                                     org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG,
                                     mRequestId));
             mMessageReceiver.accept(_message);
         }
     }
 
-    static final class DiscoveryStopAdvertisingParams 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 instanceId;
-    
-        private DiscoveryStopAdvertisingParams(int version) {
-            super(STRUCT_SIZE, version);
-        }
-    
-        public DiscoveryStopAdvertisingParams() {
-            this(0);
-        }
-    
-        public static DiscoveryStopAdvertisingParams deserialize(org.chromium.mojo.bindings.Message message) {
-            return decode(new org.chromium.mojo.bindings.Decoder(message));
-        }
-    
-        @SuppressWarnings("unchecked")
-        public static DiscoveryStopAdvertisingParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
-            if (decoder0 == null) {
-                return null;
-            }
-            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-            DiscoveryStopAdvertisingParams result = new DiscoveryStopAdvertisingParams(mainDataHeader.elementsOrVersion);
-            if (mainDataHeader.elementsOrVersion >= 0) {
-                result.instanceId = 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(instanceId, 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;
-            DiscoveryStopAdvertisingParams other = (DiscoveryStopAdvertisingParams) object;
-            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.instanceId, other.instanceId))
-                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(instanceId);
-            return result;
-        }
-    }
-
-    static final class DiscoveryStopAdvertisingResponseParams 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 Error err;
-    
-        private DiscoveryStopAdvertisingResponseParams(int version) {
-            super(STRUCT_SIZE, version);
-        }
-    
-        public DiscoveryStopAdvertisingResponseParams() {
-            this(0);
-        }
-    
-        public static DiscoveryStopAdvertisingResponseParams deserialize(org.chromium.mojo.bindings.Message message) {
-            return decode(new org.chromium.mojo.bindings.Decoder(message));
-        }
-    
-        @SuppressWarnings("unchecked")
-        public static DiscoveryStopAdvertisingResponseParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
-            if (decoder0 == null) {
-                return null;
-            }
-            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-            DiscoveryStopAdvertisingResponseParams result = new DiscoveryStopAdvertisingResponseParams(mainDataHeader.elementsOrVersion);
-            if (mainDataHeader.elementsOrVersion >= 0) {
-                org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(8, 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(err, 8, 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;
-            DiscoveryStopAdvertisingResponseParams other = (DiscoveryStopAdvertisingResponseParams) object;
-            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(err);
-            return result;
-        }
-    }
-
-    static class DiscoveryStopAdvertisingResponseParamsForwardToCallback extends org.chromium.mojo.bindings.SideEffectFreeCloseable
-            implements org.chromium.mojo.bindings.MessageReceiver {
-        private final Discovery.StopAdvertisingResponse mCallback;
-
-        DiscoveryStopAdvertisingResponseParamsForwardToCallback(Discovery.StopAdvertisingResponse 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(STOP_ADVERTISING_ORDINAL,
-                                           org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG)) {
-                    return false;
-                }
-                DiscoveryStopAdvertisingResponseParams response = DiscoveryStopAdvertisingResponseParams.deserialize(messageWithHeader.getPayload());
-                mCallback.call(response.err);
-                return true;
-            } catch (org.chromium.mojo.bindings.DeserializationException e) {
-                return false;
-            }
-        }
-    }
-
-    static class DiscoveryStopAdvertisingResponseParamsProxyToResponder implements Discovery.StopAdvertisingResponse {
-
-        private final org.chromium.mojo.system.Core mCore;
-        private final org.chromium.mojo.bindings.MessageReceiver mMessageReceiver;
-        private final long mRequestId;
-
-        DiscoveryStopAdvertisingResponseParamsProxyToResponder(
-                org.chromium.mojo.system.Core core,
-                org.chromium.mojo.bindings.MessageReceiver messageReceiver,
-                long requestId) {
-            mCore = core;
-            mMessageReceiver = messageReceiver;
-            mRequestId = requestId;
-        }
-
-        @Override
-        public void call(Error err) {
-            DiscoveryStopAdvertisingResponseParams _response = new DiscoveryStopAdvertisingResponseParams();
-            _response.err = err;
-            org.chromium.mojo.bindings.ServiceMessage _message =
-                    _response.serializeWithHeader(
-                            mCore,
-                            new org.chromium.mojo.bindings.MessageHeader(
-                                    STOP_ADVERTISING_ORDINAL,
-                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG,
-                                    mRequestId));
-            mMessageReceiver.accept(_message);
-        }
-    }
-
-    static final class DiscoveryStartScanParams extends org.chromium.mojo.bindings.Struct {
+    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)};
@@ -619,25 +390,25 @@
         public String query;
         public ScanHandler handler;
     
-        private DiscoveryStartScanParams(int version) {
+        private DiscoveryScanParams(int version) {
             super(STRUCT_SIZE, version);
         }
     
-        public DiscoveryStartScanParams() {
+        public DiscoveryScanParams() {
             this(0);
         }
     
-        public static DiscoveryStartScanParams deserialize(org.chromium.mojo.bindings.Message message) {
+        public static DiscoveryScanParams deserialize(org.chromium.mojo.bindings.Message message) {
             return decode(new org.chromium.mojo.bindings.Decoder(message));
         }
     
         @SuppressWarnings("unchecked")
-        public static DiscoveryStartScanParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
+        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);
-            DiscoveryStartScanParams result = new DiscoveryStartScanParams(mainDataHeader.elementsOrVersion);
+            DiscoveryScanParams result = new DiscoveryScanParams(mainDataHeader.elementsOrVersion);
             if (mainDataHeader.elementsOrVersion >= 0) {
                 result.query = decoder0.readString(8, false);
             }
@@ -666,7 +437,7 @@
                 return false;
             if (getClass() != object.getClass())
                 return false;
-            DiscoveryStartScanParams other = (DiscoveryStartScanParams) object;
+            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))
@@ -687,36 +458,36 @@
         }
     }
 
-    static final class DiscoveryStartScanResponseParams extends org.chromium.mojo.bindings.Struct {
+    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 int scanId;
+        public Closer closer;
         public Error err;
     
-        private DiscoveryStartScanResponseParams(int version) {
+        private DiscoveryScanResponseParams(int version) {
             super(STRUCT_SIZE, version);
         }
     
-        public DiscoveryStartScanResponseParams() {
+        public DiscoveryScanResponseParams() {
             this(0);
         }
     
-        public static DiscoveryStartScanResponseParams deserialize(org.chromium.mojo.bindings.Message message) {
+        public static DiscoveryScanResponseParams deserialize(org.chromium.mojo.bindings.Message message) {
             return decode(new org.chromium.mojo.bindings.Decoder(message));
         }
     
         @SuppressWarnings("unchecked")
-        public static DiscoveryStartScanResponseParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
+        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);
-            DiscoveryStartScanResponseParams result = new DiscoveryStartScanResponseParams(mainDataHeader.elementsOrVersion);
+            DiscoveryScanResponseParams result = new DiscoveryScanResponseParams(mainDataHeader.elementsOrVersion);
             if (mainDataHeader.elementsOrVersion >= 0) {
-                result.scanId = decoder0.readInt(8);
+                result.closer = decoder0.readServiceInterface(8, true, Closer.MANAGER);
             }
             if (mainDataHeader.elementsOrVersion >= 0) {
                 org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(16, true);
@@ -729,7 +500,7 @@
         @Override
         protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
             org.chromium.mojo.bindings.Encoder encoder0 = encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
-            encoder0.encode(scanId, 8);
+            encoder0.encode(closer, 8, true, Closer.MANAGER);
             encoder0.encode(err, 16, true);
         }
     
@@ -744,8 +515,8 @@
                 return false;
             if (getClass() != object.getClass())
                 return false;
-            DiscoveryStartScanResponseParams other = (DiscoveryStartScanResponseParams) object;
-            if (this.scanId != other.scanId)
+            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;
@@ -759,17 +530,17 @@
         public int hashCode() {
             final int prime = 31;
             int result = prime + getClass().hashCode();
-            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(scanId);
+            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(closer);
             result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(err);
             return result;
         }
     }
 
-    static class DiscoveryStartScanResponseParamsForwardToCallback extends org.chromium.mojo.bindings.SideEffectFreeCloseable
+    static class DiscoveryScanResponseParamsForwardToCallback extends org.chromium.mojo.bindings.SideEffectFreeCloseable
             implements org.chromium.mojo.bindings.MessageReceiver {
-        private final Discovery.StartScanResponse mCallback;
+        private final Discovery.ScanResponse mCallback;
 
-        DiscoveryStartScanResponseParamsForwardToCallback(Discovery.StartScanResponse callback) {
+        DiscoveryScanResponseParamsForwardToCallback(Discovery.ScanResponse callback) {
             this.mCallback = callback;
         }
 
@@ -779,12 +550,12 @@
                 org.chromium.mojo.bindings.ServiceMessage messageWithHeader =
                         message.asServiceMessage();
                 org.chromium.mojo.bindings.MessageHeader header = messageWithHeader.getHeader();
-                if (!header.validateHeader(START_SCAN_ORDINAL,
+                if (!header.validateHeader(SCAN_ORDINAL,
                                            org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG)) {
                     return false;
                 }
-                DiscoveryStartScanResponseParams response = DiscoveryStartScanResponseParams.deserialize(messageWithHeader.getPayload());
-                mCallback.call(response.scanId, response.err);
+                DiscoveryScanResponseParams response = DiscoveryScanResponseParams.deserialize(messageWithHeader.getPayload());
+                mCallback.call(response.closer, response.err);
                 return true;
             } catch (org.chromium.mojo.bindings.DeserializationException e) {
                 return false;
@@ -792,13 +563,13 @@
         }
     }
 
-    static class DiscoveryStartScanResponseParamsProxyToResponder implements Discovery.StartScanResponse {
+    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;
 
-        DiscoveryStartScanResponseParamsProxyToResponder(
+        DiscoveryScanResponseParamsProxyToResponder(
                 org.chromium.mojo.system.Core core,
                 org.chromium.mojo.bindings.MessageReceiver messageReceiver,
                 long requestId) {
@@ -808,211 +579,15 @@
         }
 
         @Override
-        public void call(Integer scanId, Error err) {
-            DiscoveryStartScanResponseParams _response = new DiscoveryStartScanResponseParams();
-            _response.scanId = scanId;
+        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(
-                                    START_SCAN_ORDINAL,
-                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG,
-                                    mRequestId));
-            mMessageReceiver.accept(_message);
-        }
-    }
-
-    static final class DiscoveryStopScanParams 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 int scanId;
-    
-        private DiscoveryStopScanParams(int version) {
-            super(STRUCT_SIZE, version);
-        }
-    
-        public DiscoveryStopScanParams() {
-            this(0);
-        }
-    
-        public static DiscoveryStopScanParams deserialize(org.chromium.mojo.bindings.Message message) {
-            return decode(new org.chromium.mojo.bindings.Decoder(message));
-        }
-    
-        @SuppressWarnings("unchecked")
-        public static DiscoveryStopScanParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
-            if (decoder0 == null) {
-                return null;
-            }
-            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-            DiscoveryStopScanParams result = new DiscoveryStopScanParams(mainDataHeader.elementsOrVersion);
-            if (mainDataHeader.elementsOrVersion >= 0) {
-                result.scanId = decoder0.readInt(8);
-            }
-            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(scanId, 8);
-        }
-    
-        /**
-         * @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;
-            DiscoveryStopScanParams other = (DiscoveryStopScanParams) object;
-            if (this.scanId != other.scanId)
-                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(scanId);
-            return result;
-        }
-    }
-
-    static final class DiscoveryStopScanResponseParams 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 Error err;
-    
-        private DiscoveryStopScanResponseParams(int version) {
-            super(STRUCT_SIZE, version);
-        }
-    
-        public DiscoveryStopScanResponseParams() {
-            this(0);
-        }
-    
-        public static DiscoveryStopScanResponseParams deserialize(org.chromium.mojo.bindings.Message message) {
-            return decode(new org.chromium.mojo.bindings.Decoder(message));
-        }
-    
-        @SuppressWarnings("unchecked")
-        public static DiscoveryStopScanResponseParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
-            if (decoder0 == null) {
-                return null;
-            }
-            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-            DiscoveryStopScanResponseParams result = new DiscoveryStopScanResponseParams(mainDataHeader.elementsOrVersion);
-            if (mainDataHeader.elementsOrVersion >= 0) {
-                org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(8, 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(err, 8, 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;
-            DiscoveryStopScanResponseParams other = (DiscoveryStopScanResponseParams) object;
-            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(err);
-            return result;
-        }
-    }
-
-    static class DiscoveryStopScanResponseParamsForwardToCallback extends org.chromium.mojo.bindings.SideEffectFreeCloseable
-            implements org.chromium.mojo.bindings.MessageReceiver {
-        private final Discovery.StopScanResponse mCallback;
-
-        DiscoveryStopScanResponseParamsForwardToCallback(Discovery.StopScanResponse 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(STOP_SCAN_ORDINAL,
-                                           org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG)) {
-                    return false;
-                }
-                DiscoveryStopScanResponseParams response = DiscoveryStopScanResponseParams.deserialize(messageWithHeader.getPayload());
-                mCallback.call(response.err);
-                return true;
-            } catch (org.chromium.mojo.bindings.DeserializationException e) {
-                return false;
-            }
-        }
-    }
-
-    static class DiscoveryStopScanResponseParamsProxyToResponder implements Discovery.StopScanResponse {
-
-        private final org.chromium.mojo.system.Core mCore;
-        private final org.chromium.mojo.bindings.MessageReceiver mMessageReceiver;
-        private final long mRequestId;
-
-        DiscoveryStopScanResponseParamsProxyToResponder(
-                org.chromium.mojo.system.Core core,
-                org.chromium.mojo.bindings.MessageReceiver messageReceiver,
-                long requestId) {
-            mCore = core;
-            mMessageReceiver = messageReceiver;
-            mRequestId = requestId;
-        }
-
-        @Override
-        public void call(Error err) {
-            DiscoveryStopScanResponseParams _response = new DiscoveryStopScanResponseParams();
-            _response.err = err;
-            org.chromium.mojo.bindings.ServiceMessage _message =
-                    _response.serializeWithHeader(
-                            mCore,
-                            new org.chromium.mojo.bindings.MessageHeader(
-                                    STOP_SCAN_ORDINAL,
+                                    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
index a401fa9..d13f62b 100644
--- a/java/generated-src/io/v/mojo/discovery/Error.java
+++ b/java/generated-src/io/v/mojo/discovery/Error.java
@@ -17,7 +17,7 @@
     private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
 
     public String id;
-    public int action;
+    public int actionCode;
     public String msg;
 
     private Error(int version) {
@@ -43,7 +43,7 @@
             result.id = decoder0.readString(8, false);
         }
         if (mainDataHeader.elementsOrVersion >= 0) {
-            result.action = decoder0.readInt(16);
+            result.actionCode = decoder0.readInt(16);
         }
         if (mainDataHeader.elementsOrVersion >= 0) {
             result.msg = decoder0.readString(24, false);
@@ -56,7 +56,7 @@
     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(action, 16);
+        encoder0.encode(actionCode, 16);
         encoder0.encode(msg, 24, false);
     }
 
@@ -74,7 +74,7 @@
         Error other = (Error) object;
         if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.id, other.id))
             return false;
-        if (this.action != other.action)
+        if (this.actionCode != other.actionCode)
             return false;
         if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.msg, other.msg))
             return false;
@@ -89,7 +89,7 @@
         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(action);
+        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
index 4042b8e..6513d59 100644
--- a/java/generated-src/io/v/mojo/discovery/ScanHandler.java
+++ b/java/generated-src/io/v/mojo/discovery/ScanHandler.java
@@ -15,8 +15,8 @@
     public interface Proxy extends ScanHandler, org.chromium.mojo.bindings.Interface.Proxy {
     }
 
-    NamedManager<ScanHandler, ScanHandler.Proxy> MANAGER = ScanHandler_Internal.MANAGER;
+    Manager<ScanHandler, ScanHandler.Proxy> MANAGER = ScanHandler_Internal.MANAGER;
 
-    void update(ScanUpdate update);
+    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
index d3c280d..f29db38 100644
--- a/java/generated-src/io/v/mojo/discovery/ScanHandler_Internal.java
+++ b/java/generated-src/io/v/mojo/discovery/ScanHandler_Internal.java
@@ -12,12 +12,8 @@
 
 class ScanHandler_Internal {
 
-    public static final org.chromium.mojo.bindings.Interface.NamedManager<ScanHandler, ScanHandler.Proxy> MANAGER =
-            new org.chromium.mojo.bindings.Interface.NamedManager<ScanHandler, ScanHandler.Proxy>() {
-    
-        public String getName() {
-            return "v23::discovery::ScanHandler";
-        }
+    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;
@@ -37,7 +33,7 @@
         }
     };
 
-    private static final int UPDATE_ORDINAL = 0;
+    private static final int ON_UPDATE_ORDINAL = 0;
 
     static final class Proxy extends org.chromium.mojo.bindings.Interface.AbstractProxy implements ScanHandler.Proxy {
 
@@ -47,13 +43,13 @@
         }
 
         @Override
-        public void update(ScanUpdate update) {
-            ScanHandlerUpdateParams _message = new ScanHandlerUpdateParams();
+        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(UPDATE_ORDINAL)));
+                            new org.chromium.mojo.bindings.MessageHeader(ON_UPDATE_ORDINAL)));
         }
 
     }
@@ -77,10 +73,10 @@
                     case org.chromium.mojo.bindings.InterfaceControlMessagesConstants.RUN_OR_CLOSE_PIPE_MESSAGE_ID:
                         return org.chromium.mojo.bindings.InterfaceControlMessagesHelper.handleRunOrClosePipe(
                                 ScanHandler_Internal.MANAGER, messageWithHeader);
-                    case UPDATE_ORDINAL: {
-                        ScanHandlerUpdateParams data =
-                                ScanHandlerUpdateParams.deserialize(messageWithHeader.getPayload());
-                        getImpl().update(data.update);
+                    case ON_UPDATE_ORDINAL: {
+                        ScanHandlerOnUpdateParams data =
+                                ScanHandlerOnUpdateParams.deserialize(messageWithHeader.getPayload());
+                        getImpl().onUpdate(data.update);
                         return true;
                     }
                     default:
@@ -115,36 +111,35 @@
         }
     }
 
-    static final class ScanHandlerUpdateParams extends org.chromium.mojo.bindings.Struct {
+    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 ScanUpdate update;
+        public Update update;
     
-        private ScanHandlerUpdateParams(int version) {
+        private ScanHandlerOnUpdateParams(int version) {
             super(STRUCT_SIZE, version);
         }
     
-        public ScanHandlerUpdateParams() {
+        public ScanHandlerOnUpdateParams() {
             this(0);
         }
     
-        public static ScanHandlerUpdateParams deserialize(org.chromium.mojo.bindings.Message message) {
+        public static ScanHandlerOnUpdateParams deserialize(org.chromium.mojo.bindings.Message message) {
             return decode(new org.chromium.mojo.bindings.Decoder(message));
         }
     
         @SuppressWarnings("unchecked")
-        public static ScanHandlerUpdateParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
+        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);
-            ScanHandlerUpdateParams result = new ScanHandlerUpdateParams(mainDataHeader.elementsOrVersion);
+            ScanHandlerOnUpdateParams result = new ScanHandlerOnUpdateParams(mainDataHeader.elementsOrVersion);
             if (mainDataHeader.elementsOrVersion >= 0) {
-                org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(8, false);
-                result.update = ScanUpdate.decode(decoder1);
+                result.update = decoder0.readServiceInterface(8, false, Update.MANAGER);
             }
             return result;
         }
@@ -153,7 +148,7 @@
         @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);
+            encoder0.encode(update, 8, false, Update.MANAGER);
         }
     
         /**
@@ -167,7 +162,7 @@
                 return false;
             if (getClass() != object.getClass())
                 return false;
-            ScanHandlerUpdateParams other = (ScanHandlerUpdateParams) object;
+            ScanHandlerOnUpdateParams other = (ScanHandlerOnUpdateParams) object;
             if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.update, other.update))
                 return false;
             return true;
diff --git a/java/generated-src/io/v/mojo/discovery/ScanUpdate.java b/java/generated-src/io/v/mojo/discovery/ScanUpdate.java
deleted file mode 100644
index 52471d0..0000000
--- a/java/generated-src/io/v/mojo/discovery/ScanUpdate.java
+++ /dev/null
@@ -1,90 +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 ScanUpdate 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 Service service;
-    public int updateType;
-
-    private ScanUpdate(int version) {
-        super(STRUCT_SIZE, version);
-    }
-
-    public ScanUpdate() {
-        this(0);
-    }
-
-    public static ScanUpdate deserialize(org.chromium.mojo.bindings.Message message) {
-        return decode(new org.chromium.mojo.bindings.Decoder(message));
-    }
-
-    @SuppressWarnings("unchecked")
-    public static ScanUpdate decode(org.chromium.mojo.bindings.Decoder decoder0) {
-        if (decoder0 == null) {
-            return null;
-        }
-        org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-        ScanUpdate result = new ScanUpdate(mainDataHeader.elementsOrVersion);
-        if (mainDataHeader.elementsOrVersion >= 0) {
-            org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(8, false);
-            result.service = Service.decode(decoder1);
-        }
-        if (mainDataHeader.elementsOrVersion >= 0) {
-            result.updateType = decoder0.readInt(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(service, 8, false);
-        encoder0.encode(updateType, 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;
-        ScanUpdate other = (ScanUpdate) object;
-        if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.service, other.service))
-            return false;
-        if (this.updateType != other.updateType)
-            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(service);
-        result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(updateType);
-        return result;
-    }
-}
-
diff --git a/java/generated-src/io/v/mojo/discovery/Update.java b/java/generated-src/io/v/mojo/discovery/Update.java
new file mode 100644
index 0000000..5cde12c
--- /dev/null
+++ b/java/generated-src/io/v/mojo/discovery/Update.java
@@ -0,0 +1,41 @@
+// 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/UpdateType.java b/java/generated-src/io/v/mojo/discovery/UpdateType.java
deleted file mode 100644
index 7533314..0000000
--- a/java/generated-src/io/v/mojo/discovery/UpdateType.java
+++ /dev/null
@@ -1,20 +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 UpdateType {
-
-    public static final int FOUND = (int) (1L);
-    public static final int LOST = FOUND + 1;
-
-    private UpdateType() {}
-
-}
diff --git a/java/generated-src/io/v/mojo/discovery/Update_Internal.java b/java/generated-src/io/v/mojo/discovery/Update_Internal.java
new file mode 100644
index 0000000..506a9f9
--- /dev/null
+++ b/java/generated-src/io/v/mojo/discovery/Update_Internal.java
@@ -0,0 +1,1566 @@
+// 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/lib/gen/dart-gen/mojom/lib/discovery/discovery.mojom.dart b/lib/gen/dart-gen/mojom/lib/discovery/discovery.mojom.dart
index 55902c3..20eb267 100644
--- a/lib/gen/dart-gen/mojom/lib/discovery/discovery.mojom.dart
+++ b/lib/gen/dart-gen/mojom/lib/discovery/discovery.mojom.dart
@@ -11,76 +11,22 @@
 import 'package:mojo/mojo/bindings/types/mojom_types.mojom.dart' as mojom_types;
 import 'package:mojo/mojo/bindings/types/service_describer.mojom.dart' as service_describer;
 
-class UpdateType extends bindings.MojoEnum {
-  static const UpdateType found = const UpdateType._(1);
-  static const UpdateType lost = const UpdateType._(2);
-
-  const UpdateType._(int v) : super(v);
-
-  static const Map<String, UpdateType> valuesMap = const {
-    "found": found,
-    "lost": lost,
-  };
-  static const List<UpdateType> values = const [
-    found,
-    lost,
-  ];
-
-  static UpdateType valueOf(String name) => valuesMap[name];
-
-  factory UpdateType(int v) {
-    switch (v) {
-      case 1:
-        return found;
-      case 2:
-        return lost;
-      default:
-        return null;
-    }
-  }
-
-  static UpdateType decode(bindings.Decoder decoder0, int offset) {
-    int v = decoder0.decodeUint32(offset);
-    UpdateType result = new UpdateType(v);
-    if (result == null) {
-      throw new bindings.MojoCodecError(
-          'Bad value $v for enum UpdateType.');
-    }
-    return result;
-  }
-
-  String toString() {
-    switch(this) {
-      case found:
-        return 'UpdateType.found';
-      case lost:
-        return 'UpdateType.lost';
-      default:
-        return null;
-    }
-  }
-
-  int toJson() => mojoEnumValue;
-}
 
 
-
-
-
-class Service extends bindings.Struct {
+class Advertisement extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
-    const bindings.StructDataHeader(56, 0)
+    const bindings.StructDataHeader(48, 0)
   ];
-  String instanceId = null;
-  String instanceName = null;
+  static const int idLen = 16;
+  List<int> id = null;
   String interfaceName = null;
-  Map<String, String> attrs = null;
-  List<String> addrs = null;
+  List<String> addresses = null;
+  Map<String, String> attributes = null;
   Map<String, List<int>> attachments = null;
 
-  Service() : super(kVersions.last.size);
+  Advertisement() : super(kVersions.last.size);
 
-  static Service deserialize(bindings.Message message) {
+  static Advertisement deserialize(bindings.Message message) {
     var decoder = new bindings.Decoder(message);
     var result = decode(decoder);
     if (decoder.excessHandles != null) {
@@ -89,11 +35,11 @@
     return result;
   }
 
-  static Service decode(bindings.Decoder decoder0) {
+  static Advertisement decode(bindings.Decoder decoder0) {
     if (decoder0 == null) {
       return null;
     }
-    Service result = new Service();
+    Advertisement result = new Advertisement();
 
     var mainDataHeader = decoder0.decodeStructDataHeader();
     if (mainDataHeader.version <= kVersions.last.version) {
@@ -115,21 +61,29 @@
     }
     if (mainDataHeader.version >= 0) {
       
-      result.instanceId = decoder0.decodeString(8, true);
+      result.id = decoder0.decodeUint8Array(8, bindings.kArrayNullable, 16);
     }
     if (mainDataHeader.version >= 0) {
       
-      result.instanceName = decoder0.decodeString(16, true);
+      result.interfaceName = decoder0.decodeString(16, false);
     }
     if (mainDataHeader.version >= 0) {
       
-      result.interfaceName = decoder0.decodeString(24, false);
+      var decoder1 = decoder0.decodePointer(24, false);
+      {
+        var si1 = decoder1.decodeDataHeaderForPointerArray(bindings.kUnspecifiedArrayLength);
+        result.addresses = new List<String>(si1.numElements);
+        for (int i1 = 0; i1 < si1.numElements; ++i1) {
+          
+          result.addresses[i1] = decoder1.decodeString(bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i1, false);
+        }
+      }
     }
     if (mainDataHeader.version >= 0) {
       
       var decoder1 = decoder0.decodePointer(32, true);
       if (decoder1 == null) {
-        result.attrs = null;
+        result.attributes = null;
       } else {
         decoder1.decodeDataHeaderForMap();
         List<String> keys0;
@@ -158,25 +112,13 @@
             }
           }
         }
-        result.attrs = new Map<String, String>.fromIterables(
+        result.attributes = new Map<String, String>.fromIterables(
             keys0, values0);
       }
     }
     if (mainDataHeader.version >= 0) {
       
-      var decoder1 = decoder0.decodePointer(40, false);
-      {
-        var si1 = decoder1.decodeDataHeaderForPointerArray(bindings.kUnspecifiedArrayLength);
-        result.addrs = new List<String>(si1.numElements);
-        for (int i1 = 0; i1 < si1.numElements; ++i1) {
-          
-          result.addrs[i1] = decoder1.decodeString(bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i1, false);
-        }
-      }
-    }
-    if (mainDataHeader.version >= 0) {
-      
-      var decoder1 = decoder0.decodePointer(48, true);
+      var decoder1 = decoder0.decodePointer(40, true);
       if (decoder1 == null) {
         result.attachments = null;
       } else {
@@ -217,19 +159,27 @@
   void encode(bindings.Encoder encoder) {
     var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
     
-    encoder0.encodeString(instanceId, 8, true);
+    encoder0.encodeUint8Array(id, 8, bindings.kArrayNullable, 16);
     
-    encoder0.encodeString(instanceName, 16, true);
+    encoder0.encodeString(interfaceName, 16, false);
     
-    encoder0.encodeString(interfaceName, 24, false);
+    if (addresses == null) {
+      encoder0.encodeNullPointer(24, false);
+    } else {
+      var encoder1 = encoder0.encodePointerArray(addresses.length, 24, bindings.kUnspecifiedArrayLength);
+      for (int i0 = 0; i0 < addresses.length; ++i0) {
+        
+        encoder1.encodeString(addresses[i0], bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i0, false);
+      }
+    }
     
-    if (attrs == null) {
+    if (attributes == null) {
       encoder0.encodeNullPointer(32, true);
     } else {
       var encoder1 = encoder0.encoderForMap(32);
-      int size0 = attrs.length;
-      var keys0 = attrs.keys.toList();
-      var values0 = attrs.values.toList();
+      int size0 = attributes.length;
+      var keys0 = attributes.keys.toList();
+      var values0 = attributes.values.toList();
       
       {
         var encoder2 = encoder1.encodePointerArray(keys0.length, bindings.ArrayDataHeader.kHeaderSize, bindings.kUnspecifiedArrayLength);
@@ -248,20 +198,10 @@
       }
     }
     
-    if (addrs == null) {
-      encoder0.encodeNullPointer(40, false);
-    } else {
-      var encoder1 = encoder0.encodePointerArray(addrs.length, 40, bindings.kUnspecifiedArrayLength);
-      for (int i0 = 0; i0 < addrs.length; ++i0) {
-        
-        encoder1.encodeString(addrs[i0], bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i0, false);
-      }
-    }
-    
     if (attachments == null) {
-      encoder0.encodeNullPointer(48, true);
+      encoder0.encodeNullPointer(40, true);
     } else {
-      var encoder1 = encoder0.encoderForMap(48);
+      var encoder1 = encoder0.encoderForMap(40);
       int size0 = attachments.length;
       var keys0 = attachments.keys.toList();
       var values0 = attachments.values.toList();
@@ -285,22 +225,20 @@
   }
 
   String toString() {
-    return "Service("
-           "instanceId: $instanceId" ", "
-           "instanceName: $instanceName" ", "
+    return "Advertisement("
+           "id: $id" ", "
            "interfaceName: $interfaceName" ", "
-           "attrs: $attrs" ", "
-           "addrs: $addrs" ", "
+           "addresses: $addresses" ", "
+           "attributes: $attributes" ", "
            "attachments: $attachments" ")";
   }
 
   Map toJson() {
     Map map = new Map();
-    map["instanceId"] = instanceId;
-    map["instanceName"] = instanceName;
+    map["id"] = id;
     map["interfaceName"] = interfaceName;
-    map["attrs"] = attrs;
-    map["addrs"] = addrs;
+    map["addresses"] = addresses;
+    map["attributes"] = attributes;
     map["attachments"] = attachments;
     return map;
   }
@@ -309,95 +247,12 @@
 
 
 
-class ScanUpdate extends bindings.Struct {
-  static const List<bindings.StructDataHeader> kVersions = const [
-    const bindings.StructDataHeader(24, 0)
-  ];
-  Service service = null;
-  UpdateType updateType = null;
-
-  ScanUpdate() : super(kVersions.last.size);
-
-  static ScanUpdate deserialize(bindings.Message message) {
-    var decoder = new bindings.Decoder(message);
-    var result = decode(decoder);
-    if (decoder.excessHandles != null) {
-      decoder.excessHandles.forEach((h) => h.close());
-    }
-    return result;
-  }
-
-  static ScanUpdate decode(bindings.Decoder decoder0) {
-    if (decoder0 == null) {
-      return null;
-    }
-    ScanUpdate result = new ScanUpdate();
-
-    var mainDataHeader = decoder0.decodeStructDataHeader();
-    if (mainDataHeader.version <= kVersions.last.version) {
-      // Scan in reverse order to optimize for more recent versions.
-      for (int i = kVersions.length - 1; i >= 0; --i) {
-        if (mainDataHeader.version >= kVersions[i].version) {
-          if (mainDataHeader.size == kVersions[i].size) {
-            // Found a match.
-            break;
-          }
-          throw new bindings.MojoCodecError(
-              'Header size doesn\'t correspond to known version size.');
-        }
-      }
-    } else if (mainDataHeader.size < kVersions.last.size) {
-      throw new bindings.MojoCodecError(
-        'Message newer than the last known version cannot be shorter than '
-        'required by the last known version.');
-    }
-    if (mainDataHeader.version >= 0) {
-      
-      var decoder1 = decoder0.decodePointer(8, false);
-      result.service = Service.decode(decoder1);
-    }
-    if (mainDataHeader.version >= 0) {
-      
-        result.updateType = UpdateType.decode(decoder0, 16);
-        if (result.updateType == null) {
-          throw new bindings.MojoCodecError(
-            'Trying to decode null union for non-nullable UpdateType.');
-        }
-    }
-    return result;
-  }
-
-  void encode(bindings.Encoder encoder) {
-    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
-    
-    encoder0.encodeStruct(service, 8, false);
-    
-    encoder0.encodeEnum(updateType, 16);
-  }
-
-  String toString() {
-    return "ScanUpdate("
-           "service: $service" ", "
-           "updateType: $updateType" ")";
-  }
-
-  Map toJson() {
-    Map map = new Map();
-    map["service"] = service;
-    map["updateType"] = updateType;
-    return map;
-  }
-}
-
-
-
-
 class Error extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(32, 0)
   ];
   String id = null;
-  int action = 0;
+  int actionCode = 0;
   String msg = null;
 
   Error() : super(kVersions.last.size);
@@ -441,7 +296,7 @@
     }
     if (mainDataHeader.version >= 0) {
       
-      result.action = decoder0.decodeInt32(16);
+      result.actionCode = decoder0.decodeUint32(16);
     }
     if (mainDataHeader.version >= 0) {
       
@@ -455,7 +310,7 @@
     
     encoder0.encodeString(id, 8, false);
     
-    encoder0.encodeInt32(action, 16);
+    encoder0.encodeUint32(actionCode, 16);
     
     encoder0.encodeString(msg, 24, false);
   }
@@ -463,14 +318,14 @@
   String toString() {
     return "Error("
            "id: $id" ", "
-           "action: $action" ", "
+           "actionCode: $actionCode" ", "
            "msg: $msg" ")";
   }
 
   Map toJson() {
     Map map = new Map();
     map["id"] = id;
-    map["action"] = action;
+    map["actionCode"] = actionCode;
     map["msg"] = msg;
     return map;
   }
@@ -479,16 +334,16 @@
 
 
 
-class _DiscoveryStartAdvertisingParams extends bindings.Struct {
+class _DiscoveryAdvertiseParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(24, 0)
   ];
-  Service service = null;
+  Advertisement ad = null;
   List<String> visibility = null;
 
-  _DiscoveryStartAdvertisingParams() : super(kVersions.last.size);
+  _DiscoveryAdvertiseParams() : super(kVersions.last.size);
 
-  static _DiscoveryStartAdvertisingParams deserialize(bindings.Message message) {
+  static _DiscoveryAdvertiseParams deserialize(bindings.Message message) {
     var decoder = new bindings.Decoder(message);
     var result = decode(decoder);
     if (decoder.excessHandles != null) {
@@ -497,11 +352,11 @@
     return result;
   }
 
-  static _DiscoveryStartAdvertisingParams decode(bindings.Decoder decoder0) {
+  static _DiscoveryAdvertiseParams decode(bindings.Decoder decoder0) {
     if (decoder0 == null) {
       return null;
     }
-    _DiscoveryStartAdvertisingParams result = new _DiscoveryStartAdvertisingParams();
+    _DiscoveryAdvertiseParams result = new _DiscoveryAdvertiseParams();
 
     var mainDataHeader = decoder0.decodeStructDataHeader();
     if (mainDataHeader.version <= kVersions.last.version) {
@@ -524,7 +379,7 @@
     if (mainDataHeader.version >= 0) {
       
       var decoder1 = decoder0.decodePointer(8, false);
-      result.service = Service.decode(decoder1);
+      result.ad = Advertisement.decode(decoder1);
     }
     if (mainDataHeader.version >= 0) {
       
@@ -546,7 +401,7 @@
   void encode(bindings.Encoder encoder) {
     var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
     
-    encoder0.encodeStruct(service, 8, false);
+    encoder0.encodeStruct(ad, 8, false);
     
     if (visibility == null) {
       encoder0.encodeNullPointer(16, true);
@@ -560,14 +415,14 @@
   }
 
   String toString() {
-    return "_DiscoveryStartAdvertisingParams("
-           "service: $service" ", "
+    return "_DiscoveryAdvertiseParams("
+           "ad: $ad" ", "
            "visibility: $visibility" ")";
   }
 
   Map toJson() {
     Map map = new Map();
-    map["service"] = service;
+    map["ad"] = ad;
     map["visibility"] = visibility;
     return map;
   }
@@ -576,16 +431,17 @@
 
 
 
-class DiscoveryStartAdvertisingResponseParams extends bindings.Struct {
+class DiscoveryAdvertiseResponseParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
-    const bindings.StructDataHeader(24, 0)
+    const bindings.StructDataHeader(32, 0)
   ];
-  String instanceId = null;
+  List<int> instanceId = null;
+  Object closer = null;
   Error err = null;
 
-  DiscoveryStartAdvertisingResponseParams() : super(kVersions.last.size);
+  DiscoveryAdvertiseResponseParams() : super(kVersions.last.size);
 
-  static DiscoveryStartAdvertisingResponseParams deserialize(bindings.Message message) {
+  static DiscoveryAdvertiseResponseParams deserialize(bindings.Message message) {
     var decoder = new bindings.Decoder(message);
     var result = decode(decoder);
     if (decoder.excessHandles != null) {
@@ -594,11 +450,11 @@
     return result;
   }
 
-  static DiscoveryStartAdvertisingResponseParams decode(bindings.Decoder decoder0) {
+  static DiscoveryAdvertiseResponseParams decode(bindings.Decoder decoder0) {
     if (decoder0 == null) {
       return null;
     }
-    DiscoveryStartAdvertisingResponseParams result = new DiscoveryStartAdvertisingResponseParams();
+    DiscoveryAdvertiseResponseParams result = new DiscoveryAdvertiseResponseParams();
 
     var mainDataHeader = decoder0.decodeStructDataHeader();
     if (mainDataHeader.version <= kVersions.last.version) {
@@ -620,11 +476,15 @@
     }
     if (mainDataHeader.version >= 0) {
       
-      result.instanceId = decoder0.decodeString(8, false);
+      result.instanceId = decoder0.decodeUint8Array(8, bindings.kArrayNullable, 16);
     }
     if (mainDataHeader.version >= 0) {
       
-      var decoder1 = decoder0.decodePointer(16, true);
+      result.closer = decoder0.decodeServiceInterface(16, true, CloserProxy.newFromEndpoint);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(24, true);
       result.err = Error.decode(decoder1);
     }
     return result;
@@ -633,177 +493,39 @@
   void encode(bindings.Encoder encoder) {
     var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
     
-    encoder0.encodeString(instanceId, 8, false);
+    encoder0.encodeUint8Array(instanceId, 8, bindings.kArrayNullable, 16);
     
-    encoder0.encodeStruct(err, 16, true);
+    encoder0.encodeInterface(closer, 16, true);
+    
+    encoder0.encodeStruct(err, 24, true);
   }
 
   String toString() {
-    return "DiscoveryStartAdvertisingResponseParams("
+    return "DiscoveryAdvertiseResponseParams("
            "instanceId: $instanceId" ", "
+           "closer: $closer" ", "
            "err: $err" ")";
   }
 
   Map toJson() {
-    Map map = new Map();
-    map["instanceId"] = instanceId;
-    map["err"] = err;
-    return map;
+    throw new bindings.MojoCodecError(
+        'Object containing handles cannot be encoded to JSON.');
   }
 }
 
 
 
 
-class _DiscoveryStopAdvertisingParams extends bindings.Struct {
-  static const List<bindings.StructDataHeader> kVersions = const [
-    const bindings.StructDataHeader(16, 0)
-  ];
-  String instanceId = null;
-
-  _DiscoveryStopAdvertisingParams() : super(kVersions.last.size);
-
-  static _DiscoveryStopAdvertisingParams deserialize(bindings.Message message) {
-    var decoder = new bindings.Decoder(message);
-    var result = decode(decoder);
-    if (decoder.excessHandles != null) {
-      decoder.excessHandles.forEach((h) => h.close());
-    }
-    return result;
-  }
-
-  static _DiscoveryStopAdvertisingParams decode(bindings.Decoder decoder0) {
-    if (decoder0 == null) {
-      return null;
-    }
-    _DiscoveryStopAdvertisingParams result = new _DiscoveryStopAdvertisingParams();
-
-    var mainDataHeader = decoder0.decodeStructDataHeader();
-    if (mainDataHeader.version <= kVersions.last.version) {
-      // Scan in reverse order to optimize for more recent versions.
-      for (int i = kVersions.length - 1; i >= 0; --i) {
-        if (mainDataHeader.version >= kVersions[i].version) {
-          if (mainDataHeader.size == kVersions[i].size) {
-            // Found a match.
-            break;
-          }
-          throw new bindings.MojoCodecError(
-              'Header size doesn\'t correspond to known version size.');
-        }
-      }
-    } else if (mainDataHeader.size < kVersions.last.size) {
-      throw new bindings.MojoCodecError(
-        'Message newer than the last known version cannot be shorter than '
-        'required by the last known version.');
-    }
-    if (mainDataHeader.version >= 0) {
-      
-      result.instanceId = decoder0.decodeString(8, false);
-    }
-    return result;
-  }
-
-  void encode(bindings.Encoder encoder) {
-    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
-    
-    encoder0.encodeString(instanceId, 8, false);
-  }
-
-  String toString() {
-    return "_DiscoveryStopAdvertisingParams("
-           "instanceId: $instanceId" ")";
-  }
-
-  Map toJson() {
-    Map map = new Map();
-    map["instanceId"] = instanceId;
-    return map;
-  }
-}
-
-
-
-
-class DiscoveryStopAdvertisingResponseParams extends bindings.Struct {
-  static const List<bindings.StructDataHeader> kVersions = const [
-    const bindings.StructDataHeader(16, 0)
-  ];
-  Error err = null;
-
-  DiscoveryStopAdvertisingResponseParams() : super(kVersions.last.size);
-
-  static DiscoveryStopAdvertisingResponseParams deserialize(bindings.Message message) {
-    var decoder = new bindings.Decoder(message);
-    var result = decode(decoder);
-    if (decoder.excessHandles != null) {
-      decoder.excessHandles.forEach((h) => h.close());
-    }
-    return result;
-  }
-
-  static DiscoveryStopAdvertisingResponseParams decode(bindings.Decoder decoder0) {
-    if (decoder0 == null) {
-      return null;
-    }
-    DiscoveryStopAdvertisingResponseParams result = new DiscoveryStopAdvertisingResponseParams();
-
-    var mainDataHeader = decoder0.decodeStructDataHeader();
-    if (mainDataHeader.version <= kVersions.last.version) {
-      // Scan in reverse order to optimize for more recent versions.
-      for (int i = kVersions.length - 1; i >= 0; --i) {
-        if (mainDataHeader.version >= kVersions[i].version) {
-          if (mainDataHeader.size == kVersions[i].size) {
-            // Found a match.
-            break;
-          }
-          throw new bindings.MojoCodecError(
-              'Header size doesn\'t correspond to known version size.');
-        }
-      }
-    } else if (mainDataHeader.size < kVersions.last.size) {
-      throw new bindings.MojoCodecError(
-        'Message newer than the last known version cannot be shorter than '
-        'required by the last known version.');
-    }
-    if (mainDataHeader.version >= 0) {
-      
-      var decoder1 = decoder0.decodePointer(8, true);
-      result.err = Error.decode(decoder1);
-    }
-    return result;
-  }
-
-  void encode(bindings.Encoder encoder) {
-    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
-    
-    encoder0.encodeStruct(err, 8, true);
-  }
-
-  String toString() {
-    return "DiscoveryStopAdvertisingResponseParams("
-           "err: $err" ")";
-  }
-
-  Map toJson() {
-    Map map = new Map();
-    map["err"] = err;
-    return map;
-  }
-}
-
-
-
-
-class _DiscoveryStartScanParams extends bindings.Struct {
+class _DiscoveryScanParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(24, 0)
   ];
   String query = null;
   Object handler = null;
 
-  _DiscoveryStartScanParams() : super(kVersions.last.size);
+  _DiscoveryScanParams() : super(kVersions.last.size);
 
-  static _DiscoveryStartScanParams deserialize(bindings.Message message) {
+  static _DiscoveryScanParams deserialize(bindings.Message message) {
     var decoder = new bindings.Decoder(message);
     var result = decode(decoder);
     if (decoder.excessHandles != null) {
@@ -812,11 +534,11 @@
     return result;
   }
 
-  static _DiscoveryStartScanParams decode(bindings.Decoder decoder0) {
+  static _DiscoveryScanParams decode(bindings.Decoder decoder0) {
     if (decoder0 == null) {
       return null;
     }
-    _DiscoveryStartScanParams result = new _DiscoveryStartScanParams();
+    _DiscoveryScanParams result = new _DiscoveryScanParams();
 
     var mainDataHeader = decoder0.decodeStructDataHeader();
     if (mainDataHeader.version <= kVersions.last.version) {
@@ -856,7 +578,7 @@
   }
 
   String toString() {
-    return "_DiscoveryStartScanParams("
+    return "_DiscoveryScanParams("
            "query: $query" ", "
            "handler: $handler" ")";
   }
@@ -870,16 +592,16 @@
 
 
 
-class DiscoveryStartScanResponseParams extends bindings.Struct {
+class DiscoveryScanResponseParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(24, 0)
   ];
-  int scanId = 0;
+  Object closer = null;
   Error err = null;
 
-  DiscoveryStartScanResponseParams() : super(kVersions.last.size);
+  DiscoveryScanResponseParams() : super(kVersions.last.size);
 
-  static DiscoveryStartScanResponseParams deserialize(bindings.Message message) {
+  static DiscoveryScanResponseParams deserialize(bindings.Message message) {
     var decoder = new bindings.Decoder(message);
     var result = decode(decoder);
     if (decoder.excessHandles != null) {
@@ -888,11 +610,11 @@
     return result;
   }
 
-  static DiscoveryStartScanResponseParams decode(bindings.Decoder decoder0) {
+  static DiscoveryScanResponseParams decode(bindings.Decoder decoder0) {
     if (decoder0 == null) {
       return null;
     }
-    DiscoveryStartScanResponseParams result = new DiscoveryStartScanResponseParams();
+    DiscoveryScanResponseParams result = new DiscoveryScanResponseParams();
 
     var mainDataHeader = decoder0.decodeStructDataHeader();
     if (mainDataHeader.version <= kVersions.last.version) {
@@ -914,7 +636,7 @@
     }
     if (mainDataHeader.version >= 0) {
       
-      result.scanId = decoder0.decodeUint32(8);
+      result.closer = decoder0.decodeServiceInterface(8, true, CloserProxy.newFromEndpoint);
     }
     if (mainDataHeader.version >= 0) {
       
@@ -927,37 +649,34 @@
   void encode(bindings.Encoder encoder) {
     var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
     
-    encoder0.encodeUint32(scanId, 8);
+    encoder0.encodeInterface(closer, 8, true);
     
     encoder0.encodeStruct(err, 16, true);
   }
 
   String toString() {
-    return "DiscoveryStartScanResponseParams("
-           "scanId: $scanId" ", "
+    return "DiscoveryScanResponseParams("
+           "closer: $closer" ", "
            "err: $err" ")";
   }
 
   Map toJson() {
-    Map map = new Map();
-    map["scanId"] = scanId;
-    map["err"] = err;
-    return map;
+    throw new bindings.MojoCodecError(
+        'Object containing handles cannot be encoded to JSON.');
   }
 }
 
 
 
 
-class _DiscoveryStopScanParams extends bindings.Struct {
+class _CloserCloseParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
-    const bindings.StructDataHeader(16, 0)
+    const bindings.StructDataHeader(8, 0)
   ];
-  int scanId = 0;
 
-  _DiscoveryStopScanParams() : super(kVersions.last.size);
+  _CloserCloseParams() : super(kVersions.last.size);
 
-  static _DiscoveryStopScanParams deserialize(bindings.Message message) {
+  static _CloserCloseParams deserialize(bindings.Message message) {
     var decoder = new bindings.Decoder(message);
     var result = decode(decoder);
     if (decoder.excessHandles != null) {
@@ -966,11 +685,132 @@
     return result;
   }
 
-  static _DiscoveryStopScanParams decode(bindings.Decoder decoder0) {
+  static _CloserCloseParams decode(bindings.Decoder decoder0) {
     if (decoder0 == null) {
       return null;
     }
-    _DiscoveryStopScanParams result = new _DiscoveryStopScanParams();
+    _CloserCloseParams result = new _CloserCloseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    encoder.getStructEncoderAtOffset(kVersions.last);
+  }
+
+  String toString() {
+    return "_CloserCloseParams("")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    return map;
+  }
+}
+
+
+
+
+class CloserCloseResponseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(8, 0)
+  ];
+
+  CloserCloseResponseParams() : super(kVersions.last.size);
+
+  static CloserCloseResponseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static CloserCloseResponseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    CloserCloseResponseParams result = new CloserCloseResponseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    encoder.getStructEncoderAtOffset(kVersions.last);
+  }
+
+  String toString() {
+    return "CloserCloseResponseParams("")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    return map;
+  }
+}
+
+
+
+
+class _ScanHandlerOnUpdateParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  Object update = null;
+
+  _ScanHandlerOnUpdateParams() : super(kVersions.last.size);
+
+  static _ScanHandlerOnUpdateParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _ScanHandlerOnUpdateParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _ScanHandlerOnUpdateParams result = new _ScanHandlerOnUpdateParams();
 
     var mainDataHeader = decoder0.decodeStructDataHeader();
     if (mainDataHeader.version <= kVersions.last.version) {
@@ -992,7 +832,7 @@
     }
     if (mainDataHeader.version >= 0) {
       
-      result.scanId = decoder0.decodeUint32(8);
+      result.update = decoder0.decodeServiceInterface(8, false, UpdateProxy.newFromEndpoint);
     }
     return result;
   }
@@ -1000,33 +840,31 @@
   void encode(bindings.Encoder encoder) {
     var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
     
-    encoder0.encodeUint32(scanId, 8);
+    encoder0.encodeInterface(update, 8, false);
   }
 
   String toString() {
-    return "_DiscoveryStopScanParams("
-           "scanId: $scanId" ")";
+    return "_ScanHandlerOnUpdateParams("
+           "update: $update" ")";
   }
 
   Map toJson() {
-    Map map = new Map();
-    map["scanId"] = scanId;
-    return map;
+    throw new bindings.MojoCodecError(
+        'Object containing handles cannot be encoded to JSON.');
   }
 }
 
 
 
 
-class DiscoveryStopScanResponseParams extends bindings.Struct {
+class _UpdateIsLostParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
-    const bindings.StructDataHeader(16, 0)
+    const bindings.StructDataHeader(8, 0)
   ];
-  Error err = null;
 
-  DiscoveryStopScanResponseParams() : super(kVersions.last.size);
+  _UpdateIsLostParams() : super(kVersions.last.size);
 
-  static DiscoveryStopScanResponseParams deserialize(bindings.Message message) {
+  static _UpdateIsLostParams deserialize(bindings.Message message) {
     var decoder = new bindings.Decoder(message);
     var result = decode(decoder);
     if (decoder.excessHandles != null) {
@@ -1035,11 +873,72 @@
     return result;
   }
 
-  static DiscoveryStopScanResponseParams decode(bindings.Decoder decoder0) {
+  static _UpdateIsLostParams decode(bindings.Decoder decoder0) {
     if (decoder0 == null) {
       return null;
     }
-    DiscoveryStopScanResponseParams result = new DiscoveryStopScanResponseParams();
+    _UpdateIsLostParams result = new _UpdateIsLostParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    encoder.getStructEncoderAtOffset(kVersions.last);
+  }
+
+  String toString() {
+    return "_UpdateIsLostParams("")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    return map;
+  }
+}
+
+
+
+
+class UpdateIsLostResponseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  bool lost = false;
+
+  UpdateIsLostResponseParams() : super(kVersions.last.size);
+
+  static UpdateIsLostResponseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static UpdateIsLostResponseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    UpdateIsLostResponseParams result = new UpdateIsLostResponseParams();
 
     var mainDataHeader = decoder0.decodeStructDataHeader();
     if (mainDataHeader.version <= kVersions.last.version) {
@@ -1061,8 +960,7 @@
     }
     if (mainDataHeader.version >= 0) {
       
-      var decoder1 = decoder0.decodePointer(8, true);
-      result.err = Error.decode(decoder1);
+      result.lost = decoder0.decodeBool(8, 0);
     }
     return result;
   }
@@ -1070,17 +968,17 @@
   void encode(bindings.Encoder encoder) {
     var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
     
-    encoder0.encodeStruct(err, 8, true);
+    encoder0.encodeBool(lost, 8, 0);
   }
 
   String toString() {
-    return "DiscoveryStopScanResponseParams("
-           "err: $err" ")";
+    return "UpdateIsLostResponseParams("
+           "lost: $lost" ")";
   }
 
   Map toJson() {
     Map map = new Map();
-    map["err"] = err;
+    map["lost"] = lost;
     return map;
   }
 }
@@ -1088,15 +986,14 @@
 
 
 
-class _ScanHandlerUpdateParams extends bindings.Struct {
+class _UpdateGetIdParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
-    const bindings.StructDataHeader(16, 0)
+    const bindings.StructDataHeader(8, 0)
   ];
-  ScanUpdate update = null;
 
-  _ScanHandlerUpdateParams() : super(kVersions.last.size);
+  _UpdateGetIdParams() : super(kVersions.last.size);
 
-  static _ScanHandlerUpdateParams deserialize(bindings.Message message) {
+  static _UpdateGetIdParams deserialize(bindings.Message message) {
     var decoder = new bindings.Decoder(message);
     var result = decode(decoder);
     if (decoder.excessHandles != null) {
@@ -1105,11 +1002,330 @@
     return result;
   }
 
-  static _ScanHandlerUpdateParams decode(bindings.Decoder decoder0) {
+  static _UpdateGetIdParams decode(bindings.Decoder decoder0) {
     if (decoder0 == null) {
       return null;
     }
-    _ScanHandlerUpdateParams result = new _ScanHandlerUpdateParams();
+    _UpdateGetIdParams result = new _UpdateGetIdParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    encoder.getStructEncoderAtOffset(kVersions.last);
+  }
+
+  String toString() {
+    return "_UpdateGetIdParams("")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    return map;
+  }
+}
+
+
+
+
+class UpdateGetIdResponseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  List<int> id = null;
+
+  UpdateGetIdResponseParams() : super(kVersions.last.size);
+
+  static UpdateGetIdResponseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static UpdateGetIdResponseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    UpdateGetIdResponseParams result = new UpdateGetIdResponseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.id = decoder0.decodeUint8Array(8, bindings.kNothingNullable, 16);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeUint8Array(id, 8, bindings.kNothingNullable, 16);
+  }
+
+  String toString() {
+    return "UpdateGetIdResponseParams("
+           "id: $id" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["id"] = id;
+    return map;
+  }
+}
+
+
+
+
+class _UpdateGetInterfaceNameParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(8, 0)
+  ];
+
+  _UpdateGetInterfaceNameParams() : super(kVersions.last.size);
+
+  static _UpdateGetInterfaceNameParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _UpdateGetInterfaceNameParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _UpdateGetInterfaceNameParams result = new _UpdateGetInterfaceNameParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    encoder.getStructEncoderAtOffset(kVersions.last);
+  }
+
+  String toString() {
+    return "_UpdateGetInterfaceNameParams("")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    return map;
+  }
+}
+
+
+
+
+class UpdateGetInterfaceNameResponseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  String interfaceName = null;
+
+  UpdateGetInterfaceNameResponseParams() : super(kVersions.last.size);
+
+  static UpdateGetInterfaceNameResponseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static UpdateGetInterfaceNameResponseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    UpdateGetInterfaceNameResponseParams result = new UpdateGetInterfaceNameResponseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.interfaceName = decoder0.decodeString(8, false);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeString(interfaceName, 8, false);
+  }
+
+  String toString() {
+    return "UpdateGetInterfaceNameResponseParams("
+           "interfaceName: $interfaceName" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["interfaceName"] = interfaceName;
+    return map;
+  }
+}
+
+
+
+
+class _UpdateGetAddressesParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(8, 0)
+  ];
+
+  _UpdateGetAddressesParams() : super(kVersions.last.size);
+
+  static _UpdateGetAddressesParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _UpdateGetAddressesParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _UpdateGetAddressesParams result = new _UpdateGetAddressesParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    encoder.getStructEncoderAtOffset(kVersions.last);
+  }
+
+  String toString() {
+    return "_UpdateGetAddressesParams("")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    return map;
+  }
+}
+
+
+
+
+class UpdateGetAddressesResponseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  List<String> addresses = null;
+
+  UpdateGetAddressesResponseParams() : super(kVersions.last.size);
+
+  static UpdateGetAddressesResponseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static UpdateGetAddressesResponseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    UpdateGetAddressesResponseParams result = new UpdateGetAddressesResponseParams();
 
     var mainDataHeader = decoder0.decodeStructDataHeader();
     if (mainDataHeader.version <= kVersions.last.version) {
@@ -1132,7 +1348,14 @@
     if (mainDataHeader.version >= 0) {
       
       var decoder1 = decoder0.decodePointer(8, false);
-      result.update = ScanUpdate.decode(decoder1);
+      {
+        var si1 = decoder1.decodeDataHeaderForPointerArray(bindings.kUnspecifiedArrayLength);
+        result.addresses = new List<String>(si1.numElements);
+        for (int i1 = 0; i1 < si1.numElements; ++i1) {
+          
+          result.addresses[i1] = decoder1.decodeString(bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i1, false);
+        }
+      }
     }
     return result;
   }
@@ -1140,17 +1363,25 @@
   void encode(bindings.Encoder encoder) {
     var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
     
-    encoder0.encodeStruct(update, 8, false);
+    if (addresses == null) {
+      encoder0.encodeNullPointer(8, false);
+    } else {
+      var encoder1 = encoder0.encodePointerArray(addresses.length, 8, bindings.kUnspecifiedArrayLength);
+      for (int i0 = 0; i0 < addresses.length; ++i0) {
+        
+        encoder1.encodeString(addresses[i0], bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i0, false);
+      }
+    }
   }
 
   String toString() {
-    return "_ScanHandlerUpdateParams("
-           "update: $update" ")";
+    return "UpdateGetAddressesResponseParams("
+           "addresses: $addresses" ")";
   }
 
   Map toJson() {
     Map map = new Map();
-    map["update"] = update;
+    map["addresses"] = addresses;
     return map;
   }
 }
@@ -1158,10 +1389,413 @@
 
 
 
-const int _Discovery_startAdvertisingName = 0;
-const int _Discovery_stopAdvertisingName = 1;
-const int _Discovery_startScanName = 2;
-const int _Discovery_stopScanName = 3;
+class _UpdateGetAttributeParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  String name = null;
+
+  _UpdateGetAttributeParams() : super(kVersions.last.size);
+
+  static _UpdateGetAttributeParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _UpdateGetAttributeParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _UpdateGetAttributeParams result = new _UpdateGetAttributeParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.name = decoder0.decodeString(8, false);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeString(name, 8, false);
+  }
+
+  String toString() {
+    return "_UpdateGetAttributeParams("
+           "name: $name" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["name"] = name;
+    return map;
+  }
+}
+
+
+
+
+class UpdateGetAttributeResponseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  String attribute = null;
+
+  UpdateGetAttributeResponseParams() : super(kVersions.last.size);
+
+  static UpdateGetAttributeResponseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static UpdateGetAttributeResponseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    UpdateGetAttributeResponseParams result = new UpdateGetAttributeResponseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.attribute = decoder0.decodeString(8, false);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeString(attribute, 8, false);
+  }
+
+  String toString() {
+    return "UpdateGetAttributeResponseParams("
+           "attribute: $attribute" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["attribute"] = attribute;
+    return map;
+  }
+}
+
+
+
+
+class _UpdateGetAttachmentParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  String name = null;
+
+  _UpdateGetAttachmentParams() : super(kVersions.last.size);
+
+  static _UpdateGetAttachmentParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _UpdateGetAttachmentParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _UpdateGetAttachmentParams result = new _UpdateGetAttachmentParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.name = decoder0.decodeString(8, false);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeString(name, 8, false);
+  }
+
+  String toString() {
+    return "_UpdateGetAttachmentParams("
+           "name: $name" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["name"] = name;
+    return map;
+  }
+}
+
+
+
+
+class UpdateGetAttachmentResponseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  core.MojoDataPipeConsumer data = null;
+
+  UpdateGetAttachmentResponseParams() : super(kVersions.last.size);
+
+  static UpdateGetAttachmentResponseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static UpdateGetAttachmentResponseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    UpdateGetAttachmentResponseParams result = new UpdateGetAttachmentResponseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.data = decoder0.decodeConsumerHandle(8, false);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeConsumerHandle(data, 8, false);
+  }
+
+  String toString() {
+    return "UpdateGetAttachmentResponseParams("
+           "data: $data" ")";
+  }
+
+  Map toJson() {
+    throw new bindings.MojoCodecError(
+        'Object containing handles cannot be encoded to JSON.');
+  }
+}
+
+
+
+
+class _UpdateGetAdvertisementParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(8, 0)
+  ];
+
+  _UpdateGetAdvertisementParams() : super(kVersions.last.size);
+
+  static _UpdateGetAdvertisementParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static _UpdateGetAdvertisementParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    _UpdateGetAdvertisementParams result = new _UpdateGetAdvertisementParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    encoder.getStructEncoderAtOffset(kVersions.last);
+  }
+
+  String toString() {
+    return "_UpdateGetAdvertisementParams("")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    return map;
+  }
+}
+
+
+
+
+class UpdateGetAdvertisementResponseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  Advertisement ad = null;
+
+  UpdateGetAdvertisementResponseParams() : super(kVersions.last.size);
+
+  static UpdateGetAdvertisementResponseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static UpdateGetAdvertisementResponseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    UpdateGetAdvertisementResponseParams result = new UpdateGetAdvertisementResponseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(8, false);
+      result.ad = Advertisement.decode(decoder1);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeStruct(ad, 8, false);
+  }
+
+  String toString() {
+    return "UpdateGetAdvertisementResponseParams("
+           "ad: $ad" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["ad"] = ad;
+    return map;
+  }
+}
+
+
+
+
+const int _Discovery_advertiseName = 0;
+const int _Discovery_scanName = 1;
 
 
 
@@ -1175,10 +1809,8 @@
 
 abstract class Discovery {
   static const String serviceName = "v23::discovery::Discovery";
-  dynamic startAdvertising(Service service,List<String> visibility,[Function responseFactory = null]);
-  dynamic stopAdvertising(String instanceId,[Function responseFactory = null]);
-  dynamic startScan(String query,Object handler,[Function responseFactory = null]);
-  dynamic stopScan(int scanId,[Function responseFactory = null]);
+  dynamic advertise(Advertisement ad,List<String> visibility,[Function responseFactory = null]);
+  dynamic scan(String query,Object handler,[Function responseFactory = null]);
 }
 
 
@@ -1202,8 +1834,8 @@
 
   void handleResponse(bindings.ServiceMessage message) {
     switch (message.header.type) {
-      case _Discovery_startAdvertisingName:
-        var r = DiscoveryStartAdvertisingResponseParams.deserialize(
+      case _Discovery_advertiseName:
+        var r = DiscoveryAdvertiseResponseParams.deserialize(
             message.payload);
         if (!message.header.hasRequestId) {
           proxyError("Expected a message with a valid request Id.");
@@ -1222,48 +1854,8 @@
         }
         c.complete(r);
         break;
-      case _Discovery_stopAdvertisingName:
-        var r = DiscoveryStopAdvertisingResponseParams.deserialize(
-            message.payload);
-        if (!message.header.hasRequestId) {
-          proxyError("Expected a message with a valid request Id.");
-          return;
-        }
-        Completer c = completerMap[message.header.requestId];
-        if (c == null) {
-          proxyError(
-              "Message had unknown request Id: ${message.header.requestId}");
-          return;
-        }
-        completerMap.remove(message.header.requestId);
-        if (c.isCompleted) {
-          proxyError("Response completer already completed");
-          return;
-        }
-        c.complete(r);
-        break;
-      case _Discovery_startScanName:
-        var r = DiscoveryStartScanResponseParams.deserialize(
-            message.payload);
-        if (!message.header.hasRequestId) {
-          proxyError("Expected a message with a valid request Id.");
-          return;
-        }
-        Completer c = completerMap[message.header.requestId];
-        if (c == null) {
-          proxyError(
-              "Message had unknown request Id: ${message.header.requestId}");
-          return;
-        }
-        completerMap.remove(message.header.requestId);
-        if (c.isCompleted) {
-          proxyError("Response completer already completed");
-          return;
-        }
-        c.complete(r);
-        break;
-      case _Discovery_stopScanName:
-        var r = DiscoveryStopScanResponseParams.deserialize(
+      case _Discovery_scanName:
+        var r = DiscoveryScanResponseParams.deserialize(
             message.payload);
         if (!message.header.hasRequestId) {
           proxyError("Expected a message with a valid request Id.");
@@ -1300,41 +1892,23 @@
   _DiscoveryProxyImpl _proxyImpl;
 
   _DiscoveryProxyCalls(this._proxyImpl);
-    dynamic startAdvertising(Service service,List<String> visibility,[Function responseFactory = null]) {
-      var params = new _DiscoveryStartAdvertisingParams();
-      params.service = service;
+    dynamic advertise(Advertisement ad,List<String> visibility,[Function responseFactory = null]) {
+      var params = new _DiscoveryAdvertiseParams();
+      params.ad = ad;
       params.visibility = visibility;
       return _proxyImpl.sendMessageWithRequestId(
           params,
-          _Discovery_startAdvertisingName,
+          _Discovery_advertiseName,
           -1,
           bindings.MessageHeader.kMessageExpectsResponse);
     }
-    dynamic stopAdvertising(String instanceId,[Function responseFactory = null]) {
-      var params = new _DiscoveryStopAdvertisingParams();
-      params.instanceId = instanceId;
-      return _proxyImpl.sendMessageWithRequestId(
-          params,
-          _Discovery_stopAdvertisingName,
-          -1,
-          bindings.MessageHeader.kMessageExpectsResponse);
-    }
-    dynamic startScan(String query,Object handler,[Function responseFactory = null]) {
-      var params = new _DiscoveryStartScanParams();
+    dynamic scan(String query,Object handler,[Function responseFactory = null]) {
+      var params = new _DiscoveryScanParams();
       params.query = query;
       params.handler = handler;
       return _proxyImpl.sendMessageWithRequestId(
           params,
-          _Discovery_startScanName,
-          -1,
-          bindings.MessageHeader.kMessageExpectsResponse);
-    }
-    dynamic stopScan(int scanId,[Function responseFactory = null]) {
-      var params = new _DiscoveryStopScanParams();
-      params.scanId = scanId;
-      return _proxyImpl.sendMessageWithRequestId(
-          params,
-          _Discovery_stopScanName,
+          _Discovery_scanName,
           -1,
           bindings.MessageHeader.kMessageExpectsResponse);
     }
@@ -1419,25 +1993,16 @@
   }
 
 
-  DiscoveryStartAdvertisingResponseParams _DiscoveryStartAdvertisingResponseParamsFactory(String instanceId, Error err) {
-    var mojo_factory_result = new DiscoveryStartAdvertisingResponseParams();
+  DiscoveryAdvertiseResponseParams _DiscoveryAdvertiseResponseParamsFactory(List<int> instanceId, Object closer, Error err) {
+    var mojo_factory_result = new DiscoveryAdvertiseResponseParams();
     mojo_factory_result.instanceId = instanceId;
+    mojo_factory_result.closer = closer;
     mojo_factory_result.err = err;
     return mojo_factory_result;
   }
-  DiscoveryStopAdvertisingResponseParams _DiscoveryStopAdvertisingResponseParamsFactory(Error err) {
-    var mojo_factory_result = new DiscoveryStopAdvertisingResponseParams();
-    mojo_factory_result.err = err;
-    return mojo_factory_result;
-  }
-  DiscoveryStartScanResponseParams _DiscoveryStartScanResponseParamsFactory(int scanId, Error err) {
-    var mojo_factory_result = new DiscoveryStartScanResponseParams();
-    mojo_factory_result.scanId = scanId;
-    mojo_factory_result.err = err;
-    return mojo_factory_result;
-  }
-  DiscoveryStopScanResponseParams _DiscoveryStopScanResponseParamsFactory(Error err) {
-    var mojo_factory_result = new DiscoveryStopScanResponseParams();
+  DiscoveryScanResponseParams _DiscoveryScanResponseParamsFactory(Object closer, Error err) {
+    var mojo_factory_result = new DiscoveryScanResponseParams();
+    mojo_factory_result.closer = closer;
     mojo_factory_result.err = err;
     return mojo_factory_result;
   }
@@ -1450,16 +2015,16 @@
     }
     assert(_impl != null);
     switch (message.header.type) {
-      case _Discovery_startAdvertisingName:
-        var params = _DiscoveryStartAdvertisingParams.deserialize(
+      case _Discovery_advertiseName:
+        var params = _DiscoveryAdvertiseParams.deserialize(
             message.payload);
-        var response = _impl.startAdvertising(params.service,params.visibility,_DiscoveryStartAdvertisingResponseParamsFactory);
+        var response = _impl.advertise(params.ad,params.visibility,_DiscoveryAdvertiseResponseParamsFactory);
         if (response is Future) {
           return response.then((response) {
             if (response != null) {
               return buildResponseWithId(
                   response,
-                  _Discovery_startAdvertisingName,
+                  _Discovery_advertiseName,
                   message.header.requestId,
                   bindings.MessageHeader.kMessageIsResponse);
             }
@@ -1467,21 +2032,21 @@
         } else if (response != null) {
           return buildResponseWithId(
               response,
-              _Discovery_startAdvertisingName,
+              _Discovery_advertiseName,
               message.header.requestId,
               bindings.MessageHeader.kMessageIsResponse);
         }
         break;
-      case _Discovery_stopAdvertisingName:
-        var params = _DiscoveryStopAdvertisingParams.deserialize(
+      case _Discovery_scanName:
+        var params = _DiscoveryScanParams.deserialize(
             message.payload);
-        var response = _impl.stopAdvertising(params.instanceId,_DiscoveryStopAdvertisingResponseParamsFactory);
+        var response = _impl.scan(params.query,params.handler,_DiscoveryScanResponseParamsFactory);
         if (response is Future) {
           return response.then((response) {
             if (response != null) {
               return buildResponseWithId(
                   response,
-                  _Discovery_stopAdvertisingName,
+                  _Discovery_scanName,
                   message.header.requestId,
                   bindings.MessageHeader.kMessageIsResponse);
             }
@@ -1489,51 +2054,7 @@
         } else if (response != null) {
           return buildResponseWithId(
               response,
-              _Discovery_stopAdvertisingName,
-              message.header.requestId,
-              bindings.MessageHeader.kMessageIsResponse);
-        }
-        break;
-      case _Discovery_startScanName:
-        var params = _DiscoveryStartScanParams.deserialize(
-            message.payload);
-        var response = _impl.startScan(params.query,params.handler,_DiscoveryStartScanResponseParamsFactory);
-        if (response is Future) {
-          return response.then((response) {
-            if (response != null) {
-              return buildResponseWithId(
-                  response,
-                  _Discovery_startScanName,
-                  message.header.requestId,
-                  bindings.MessageHeader.kMessageIsResponse);
-            }
-          });
-        } else if (response != null) {
-          return buildResponseWithId(
-              response,
-              _Discovery_startScanName,
-              message.header.requestId,
-              bindings.MessageHeader.kMessageIsResponse);
-        }
-        break;
-      case _Discovery_stopScanName:
-        var params = _DiscoveryStopScanParams.deserialize(
-            message.payload);
-        var response = _impl.stopScan(params.scanId,_DiscoveryStopScanResponseParamsFactory);
-        if (response is Future) {
-          return response.then((response) {
-            if (response != null) {
-              return buildResponseWithId(
-                  response,
-                  _Discovery_stopScanName,
-                  message.header.requestId,
-                  bindings.MessageHeader.kMessageIsResponse);
-            }
-          });
-        } else if (response != null) {
-          return buildResponseWithId(
-              response,
-              _Discovery_stopScanName,
+              _Discovery_scanName,
               message.header.requestId,
               bindings.MessageHeader.kMessageIsResponse);
         }
@@ -1562,7 +2083,231 @@
     new _DiscoveryServiceDescription();
 }
 
-const int _ScanHandler_updateName = 0;
+const int _Closer_closeName = 0;
+
+
+
+class _CloserServiceDescription implements service_describer.ServiceDescription {
+  dynamic getTopLevelInterface([Function responseFactory]) => null;
+
+  dynamic getTypeDefinition(String typeKey, [Function responseFactory]) => null;
+
+  dynamic getAllTypeDefinitions([Function responseFactory]) => null;
+}
+
+abstract class Closer {
+  static const String serviceName = null;
+  dynamic close([Function responseFactory = null]);
+}
+
+
+class _CloserProxyImpl extends bindings.Proxy {
+  _CloserProxyImpl.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) : super.fromEndpoint(endpoint);
+
+  _CloserProxyImpl.fromHandle(core.MojoHandle handle) :
+      super.fromHandle(handle);
+
+  _CloserProxyImpl.unbound() : super.unbound();
+
+  static _CloserProxyImpl newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For _CloserProxyImpl"));
+    return new _CloserProxyImpl.fromEndpoint(endpoint);
+  }
+
+  service_describer.ServiceDescription get serviceDescription =>
+    new _CloserServiceDescription();
+
+  void handleResponse(bindings.ServiceMessage message) {
+    switch (message.header.type) {
+      case _Closer_closeName:
+        var r = CloserCloseResponseParams.deserialize(
+            message.payload);
+        if (!message.header.hasRequestId) {
+          proxyError("Expected a message with a valid request Id.");
+          return;
+        }
+        Completer c = completerMap[message.header.requestId];
+        if (c == null) {
+          proxyError(
+              "Message had unknown request Id: ${message.header.requestId}");
+          return;
+        }
+        completerMap.remove(message.header.requestId);
+        if (c.isCompleted) {
+          proxyError("Response completer already completed");
+          return;
+        }
+        c.complete(r);
+        break;
+      default:
+        proxyError("Unexpected message type: ${message.header.type}");
+        close(immediate: true);
+        break;
+    }
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "_CloserProxyImpl($superString)";
+  }
+}
+
+
+class _CloserProxyCalls implements Closer {
+  _CloserProxyImpl _proxyImpl;
+
+  _CloserProxyCalls(this._proxyImpl);
+    dynamic close([Function responseFactory = null]) {
+      var params = new _CloserCloseParams();
+      return _proxyImpl.sendMessageWithRequestId(
+          params,
+          _Closer_closeName,
+          -1,
+          bindings.MessageHeader.kMessageExpectsResponse);
+    }
+}
+
+
+class CloserProxy implements bindings.ProxyBase {
+  final bindings.Proxy impl;
+  Closer ptr;
+
+  CloserProxy(_CloserProxyImpl proxyImpl) :
+      impl = proxyImpl,
+      ptr = new _CloserProxyCalls(proxyImpl);
+
+  CloserProxy.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) :
+      impl = new _CloserProxyImpl.fromEndpoint(endpoint) {
+    ptr = new _CloserProxyCalls(impl);
+  }
+
+  CloserProxy.fromHandle(core.MojoHandle handle) :
+      impl = new _CloserProxyImpl.fromHandle(handle) {
+    ptr = new _CloserProxyCalls(impl);
+  }
+
+  CloserProxy.unbound() :
+      impl = new _CloserProxyImpl.unbound() {
+    ptr = new _CloserProxyCalls(impl);
+  }
+
+  factory CloserProxy.connectToService(
+      bindings.ServiceConnector s, String url, [String serviceName]) {
+    CloserProxy p = new CloserProxy.unbound();
+    s.connectToService(url, p, serviceName);
+    return p;
+  }
+
+  static CloserProxy newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For CloserProxy"));
+    return new CloserProxy.fromEndpoint(endpoint);
+  }
+
+  String get serviceName => Closer.serviceName;
+
+  Future close({bool immediate: false}) => impl.close(immediate: immediate);
+
+  Future responseOrError(Future f) => impl.responseOrError(f);
+
+  Future get errorFuture => impl.errorFuture;
+
+  int get version => impl.version;
+
+  Future<int> queryVersion() => impl.queryVersion();
+
+  void requireVersion(int requiredVersion) {
+    impl.requireVersion(requiredVersion);
+  }
+
+  String toString() {
+    return "CloserProxy($impl)";
+  }
+}
+
+
+class CloserStub extends bindings.Stub {
+  Closer _impl = null;
+
+  CloserStub.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint, [this._impl])
+      : super.fromEndpoint(endpoint);
+
+  CloserStub.fromHandle(core.MojoHandle handle, [this._impl])
+      : super.fromHandle(handle);
+
+  CloserStub.unbound() : super.unbound();
+
+  static CloserStub newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For CloserStub"));
+    return new CloserStub.fromEndpoint(endpoint);
+  }
+
+
+  CloserCloseResponseParams _CloserCloseResponseParamsFactory() {
+    var mojo_factory_result = new CloserCloseResponseParams();
+    return mojo_factory_result;
+  }
+
+  dynamic handleMessage(bindings.ServiceMessage message) {
+    if (bindings.ControlMessageHandler.isControlMessage(message)) {
+      return bindings.ControlMessageHandler.handleMessage(this,
+                                                          0,
+                                                          message);
+    }
+    assert(_impl != null);
+    switch (message.header.type) {
+      case _Closer_closeName:
+        var params = _CloserCloseParams.deserialize(
+            message.payload);
+        var response = _impl.close(_CloserCloseResponseParamsFactory);
+        if (response is Future) {
+          return response.then((response) {
+            if (response != null) {
+              return buildResponseWithId(
+                  response,
+                  _Closer_closeName,
+                  message.header.requestId,
+                  bindings.MessageHeader.kMessageIsResponse);
+            }
+          });
+        } else if (response != null) {
+          return buildResponseWithId(
+              response,
+              _Closer_closeName,
+              message.header.requestId,
+              bindings.MessageHeader.kMessageIsResponse);
+        }
+        break;
+      default:
+        throw new bindings.MojoCodecError("Unexpected message name");
+        break;
+    }
+    return null;
+  }
+
+  Closer get impl => _impl;
+  set impl(Closer d) {
+    assert(_impl == null);
+    _impl = d;
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "CloserStub($superString)";
+  }
+
+  int get version => 0;
+
+  service_describer.ServiceDescription get serviceDescription =>
+    new _CloserServiceDescription();
+}
+
+const int _ScanHandler_onUpdateName = 0;
 
 
 
@@ -1575,8 +2320,8 @@
 }
 
 abstract class ScanHandler {
-  static const String serviceName = "v23::discovery::ScanHandler";
-  void update(ScanUpdate update);
+  static const String serviceName = null;
+  void onUpdate(Object update);
 }
 
 
@@ -1618,14 +2363,14 @@
   _ScanHandlerProxyImpl _proxyImpl;
 
   _ScanHandlerProxyCalls(this._proxyImpl);
-    void update(ScanUpdate update) {
+    void onUpdate(Object update) {
       if (!_proxyImpl.isBound) {
         _proxyImpl.proxyError("The Proxy is closed.");
         return;
       }
-      var params = new _ScanHandlerUpdateParams();
+      var params = new _ScanHandlerOnUpdateParams();
       params.update = update;
-      _proxyImpl.sendMessage(params, _ScanHandler_updateName);
+      _proxyImpl.sendMessage(params, _ScanHandler_onUpdateName);
     }
 }
 
@@ -1717,10 +2462,10 @@
     }
     assert(_impl != null);
     switch (message.header.type) {
-      case _ScanHandler_updateName:
-        var params = _ScanHandlerUpdateParams.deserialize(
+      case _ScanHandler_onUpdateName:
+        var params = _ScanHandlerOnUpdateParams.deserialize(
             message.payload);
-        _impl.update(params.update);
+        _impl.onUpdate(params.update);
         break;
       default:
         throw new bindings.MojoCodecError("Unexpected message name");
@@ -1746,5 +2491,574 @@
     new _ScanHandlerServiceDescription();
 }
 
+const int _Update_isLostName = 0;
+const int _Update_getIdName = 1;
+const int _Update_getInterfaceNameName = 2;
+const int _Update_getAddressesName = 3;
+const int _Update_getAttributeName = 4;
+const int _Update_getAttachmentName = 5;
+const int _Update_getAdvertisementName = 6;
+
+
+
+class _UpdateServiceDescription implements service_describer.ServiceDescription {
+  dynamic getTopLevelInterface([Function responseFactory]) => null;
+
+  dynamic getTypeDefinition(String typeKey, [Function responseFactory]) => null;
+
+  dynamic getAllTypeDefinitions([Function responseFactory]) => null;
+}
+
+abstract class Update {
+  static const String serviceName = null;
+  dynamic isLost([Function responseFactory = null]);
+  dynamic getId([Function responseFactory = null]);
+  dynamic getInterfaceName([Function responseFactory = null]);
+  dynamic getAddresses([Function responseFactory = null]);
+  dynamic getAttribute(String name,[Function responseFactory = null]);
+  dynamic getAttachment(String name,[Function responseFactory = null]);
+  dynamic getAdvertisement([Function responseFactory = null]);
+}
+
+
+class _UpdateProxyImpl extends bindings.Proxy {
+  _UpdateProxyImpl.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) : super.fromEndpoint(endpoint);
+
+  _UpdateProxyImpl.fromHandle(core.MojoHandle handle) :
+      super.fromHandle(handle);
+
+  _UpdateProxyImpl.unbound() : super.unbound();
+
+  static _UpdateProxyImpl newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For _UpdateProxyImpl"));
+    return new _UpdateProxyImpl.fromEndpoint(endpoint);
+  }
+
+  service_describer.ServiceDescription get serviceDescription =>
+    new _UpdateServiceDescription();
+
+  void handleResponse(bindings.ServiceMessage message) {
+    switch (message.header.type) {
+      case _Update_isLostName:
+        var r = UpdateIsLostResponseParams.deserialize(
+            message.payload);
+        if (!message.header.hasRequestId) {
+          proxyError("Expected a message with a valid request Id.");
+          return;
+        }
+        Completer c = completerMap[message.header.requestId];
+        if (c == null) {
+          proxyError(
+              "Message had unknown request Id: ${message.header.requestId}");
+          return;
+        }
+        completerMap.remove(message.header.requestId);
+        if (c.isCompleted) {
+          proxyError("Response completer already completed");
+          return;
+        }
+        c.complete(r);
+        break;
+      case _Update_getIdName:
+        var r = UpdateGetIdResponseParams.deserialize(
+            message.payload);
+        if (!message.header.hasRequestId) {
+          proxyError("Expected a message with a valid request Id.");
+          return;
+        }
+        Completer c = completerMap[message.header.requestId];
+        if (c == null) {
+          proxyError(
+              "Message had unknown request Id: ${message.header.requestId}");
+          return;
+        }
+        completerMap.remove(message.header.requestId);
+        if (c.isCompleted) {
+          proxyError("Response completer already completed");
+          return;
+        }
+        c.complete(r);
+        break;
+      case _Update_getInterfaceNameName:
+        var r = UpdateGetInterfaceNameResponseParams.deserialize(
+            message.payload);
+        if (!message.header.hasRequestId) {
+          proxyError("Expected a message with a valid request Id.");
+          return;
+        }
+        Completer c = completerMap[message.header.requestId];
+        if (c == null) {
+          proxyError(
+              "Message had unknown request Id: ${message.header.requestId}");
+          return;
+        }
+        completerMap.remove(message.header.requestId);
+        if (c.isCompleted) {
+          proxyError("Response completer already completed");
+          return;
+        }
+        c.complete(r);
+        break;
+      case _Update_getAddressesName:
+        var r = UpdateGetAddressesResponseParams.deserialize(
+            message.payload);
+        if (!message.header.hasRequestId) {
+          proxyError("Expected a message with a valid request Id.");
+          return;
+        }
+        Completer c = completerMap[message.header.requestId];
+        if (c == null) {
+          proxyError(
+              "Message had unknown request Id: ${message.header.requestId}");
+          return;
+        }
+        completerMap.remove(message.header.requestId);
+        if (c.isCompleted) {
+          proxyError("Response completer already completed");
+          return;
+        }
+        c.complete(r);
+        break;
+      case _Update_getAttributeName:
+        var r = UpdateGetAttributeResponseParams.deserialize(
+            message.payload);
+        if (!message.header.hasRequestId) {
+          proxyError("Expected a message with a valid request Id.");
+          return;
+        }
+        Completer c = completerMap[message.header.requestId];
+        if (c == null) {
+          proxyError(
+              "Message had unknown request Id: ${message.header.requestId}");
+          return;
+        }
+        completerMap.remove(message.header.requestId);
+        if (c.isCompleted) {
+          proxyError("Response completer already completed");
+          return;
+        }
+        c.complete(r);
+        break;
+      case _Update_getAttachmentName:
+        var r = UpdateGetAttachmentResponseParams.deserialize(
+            message.payload);
+        if (!message.header.hasRequestId) {
+          proxyError("Expected a message with a valid request Id.");
+          return;
+        }
+        Completer c = completerMap[message.header.requestId];
+        if (c == null) {
+          proxyError(
+              "Message had unknown request Id: ${message.header.requestId}");
+          return;
+        }
+        completerMap.remove(message.header.requestId);
+        if (c.isCompleted) {
+          proxyError("Response completer already completed");
+          return;
+        }
+        c.complete(r);
+        break;
+      case _Update_getAdvertisementName:
+        var r = UpdateGetAdvertisementResponseParams.deserialize(
+            message.payload);
+        if (!message.header.hasRequestId) {
+          proxyError("Expected a message with a valid request Id.");
+          return;
+        }
+        Completer c = completerMap[message.header.requestId];
+        if (c == null) {
+          proxyError(
+              "Message had unknown request Id: ${message.header.requestId}");
+          return;
+        }
+        completerMap.remove(message.header.requestId);
+        if (c.isCompleted) {
+          proxyError("Response completer already completed");
+          return;
+        }
+        c.complete(r);
+        break;
+      default:
+        proxyError("Unexpected message type: ${message.header.type}");
+        close(immediate: true);
+        break;
+    }
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "_UpdateProxyImpl($superString)";
+  }
+}
+
+
+class _UpdateProxyCalls implements Update {
+  _UpdateProxyImpl _proxyImpl;
+
+  _UpdateProxyCalls(this._proxyImpl);
+    dynamic isLost([Function responseFactory = null]) {
+      var params = new _UpdateIsLostParams();
+      return _proxyImpl.sendMessageWithRequestId(
+          params,
+          _Update_isLostName,
+          -1,
+          bindings.MessageHeader.kMessageExpectsResponse);
+    }
+    dynamic getId([Function responseFactory = null]) {
+      var params = new _UpdateGetIdParams();
+      return _proxyImpl.sendMessageWithRequestId(
+          params,
+          _Update_getIdName,
+          -1,
+          bindings.MessageHeader.kMessageExpectsResponse);
+    }
+    dynamic getInterfaceName([Function responseFactory = null]) {
+      var params = new _UpdateGetInterfaceNameParams();
+      return _proxyImpl.sendMessageWithRequestId(
+          params,
+          _Update_getInterfaceNameName,
+          -1,
+          bindings.MessageHeader.kMessageExpectsResponse);
+    }
+    dynamic getAddresses([Function responseFactory = null]) {
+      var params = new _UpdateGetAddressesParams();
+      return _proxyImpl.sendMessageWithRequestId(
+          params,
+          _Update_getAddressesName,
+          -1,
+          bindings.MessageHeader.kMessageExpectsResponse);
+    }
+    dynamic getAttribute(String name,[Function responseFactory = null]) {
+      var params = new _UpdateGetAttributeParams();
+      params.name = name;
+      return _proxyImpl.sendMessageWithRequestId(
+          params,
+          _Update_getAttributeName,
+          -1,
+          bindings.MessageHeader.kMessageExpectsResponse);
+    }
+    dynamic getAttachment(String name,[Function responseFactory = null]) {
+      var params = new _UpdateGetAttachmentParams();
+      params.name = name;
+      return _proxyImpl.sendMessageWithRequestId(
+          params,
+          _Update_getAttachmentName,
+          -1,
+          bindings.MessageHeader.kMessageExpectsResponse);
+    }
+    dynamic getAdvertisement([Function responseFactory = null]) {
+      var params = new _UpdateGetAdvertisementParams();
+      return _proxyImpl.sendMessageWithRequestId(
+          params,
+          _Update_getAdvertisementName,
+          -1,
+          bindings.MessageHeader.kMessageExpectsResponse);
+    }
+}
+
+
+class UpdateProxy implements bindings.ProxyBase {
+  final bindings.Proxy impl;
+  Update ptr;
+
+  UpdateProxy(_UpdateProxyImpl proxyImpl) :
+      impl = proxyImpl,
+      ptr = new _UpdateProxyCalls(proxyImpl);
+
+  UpdateProxy.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) :
+      impl = new _UpdateProxyImpl.fromEndpoint(endpoint) {
+    ptr = new _UpdateProxyCalls(impl);
+  }
+
+  UpdateProxy.fromHandle(core.MojoHandle handle) :
+      impl = new _UpdateProxyImpl.fromHandle(handle) {
+    ptr = new _UpdateProxyCalls(impl);
+  }
+
+  UpdateProxy.unbound() :
+      impl = new _UpdateProxyImpl.unbound() {
+    ptr = new _UpdateProxyCalls(impl);
+  }
+
+  factory UpdateProxy.connectToService(
+      bindings.ServiceConnector s, String url, [String serviceName]) {
+    UpdateProxy p = new UpdateProxy.unbound();
+    s.connectToService(url, p, serviceName);
+    return p;
+  }
+
+  static UpdateProxy newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For UpdateProxy"));
+    return new UpdateProxy.fromEndpoint(endpoint);
+  }
+
+  String get serviceName => Update.serviceName;
+
+  Future close({bool immediate: false}) => impl.close(immediate: immediate);
+
+  Future responseOrError(Future f) => impl.responseOrError(f);
+
+  Future get errorFuture => impl.errorFuture;
+
+  int get version => impl.version;
+
+  Future<int> queryVersion() => impl.queryVersion();
+
+  void requireVersion(int requiredVersion) {
+    impl.requireVersion(requiredVersion);
+  }
+
+  String toString() {
+    return "UpdateProxy($impl)";
+  }
+}
+
+
+class UpdateStub extends bindings.Stub {
+  Update _impl = null;
+
+  UpdateStub.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint, [this._impl])
+      : super.fromEndpoint(endpoint);
+
+  UpdateStub.fromHandle(core.MojoHandle handle, [this._impl])
+      : super.fromHandle(handle);
+
+  UpdateStub.unbound() : super.unbound();
+
+  static UpdateStub newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For UpdateStub"));
+    return new UpdateStub.fromEndpoint(endpoint);
+  }
+
+
+  UpdateIsLostResponseParams _UpdateIsLostResponseParamsFactory(bool lost) {
+    var mojo_factory_result = new UpdateIsLostResponseParams();
+    mojo_factory_result.lost = lost;
+    return mojo_factory_result;
+  }
+  UpdateGetIdResponseParams _UpdateGetIdResponseParamsFactory(List<int> id) {
+    var mojo_factory_result = new UpdateGetIdResponseParams();
+    mojo_factory_result.id = id;
+    return mojo_factory_result;
+  }
+  UpdateGetInterfaceNameResponseParams _UpdateGetInterfaceNameResponseParamsFactory(String interfaceName) {
+    var mojo_factory_result = new UpdateGetInterfaceNameResponseParams();
+    mojo_factory_result.interfaceName = interfaceName;
+    return mojo_factory_result;
+  }
+  UpdateGetAddressesResponseParams _UpdateGetAddressesResponseParamsFactory(List<String> addresses) {
+    var mojo_factory_result = new UpdateGetAddressesResponseParams();
+    mojo_factory_result.addresses = addresses;
+    return mojo_factory_result;
+  }
+  UpdateGetAttributeResponseParams _UpdateGetAttributeResponseParamsFactory(String attribute) {
+    var mojo_factory_result = new UpdateGetAttributeResponseParams();
+    mojo_factory_result.attribute = attribute;
+    return mojo_factory_result;
+  }
+  UpdateGetAttachmentResponseParams _UpdateGetAttachmentResponseParamsFactory(core.MojoDataPipeConsumer data) {
+    var mojo_factory_result = new UpdateGetAttachmentResponseParams();
+    mojo_factory_result.data = data;
+    return mojo_factory_result;
+  }
+  UpdateGetAdvertisementResponseParams _UpdateGetAdvertisementResponseParamsFactory(Advertisement ad) {
+    var mojo_factory_result = new UpdateGetAdvertisementResponseParams();
+    mojo_factory_result.ad = ad;
+    return mojo_factory_result;
+  }
+
+  dynamic handleMessage(bindings.ServiceMessage message) {
+    if (bindings.ControlMessageHandler.isControlMessage(message)) {
+      return bindings.ControlMessageHandler.handleMessage(this,
+                                                          0,
+                                                          message);
+    }
+    assert(_impl != null);
+    switch (message.header.type) {
+      case _Update_isLostName:
+        var params = _UpdateIsLostParams.deserialize(
+            message.payload);
+        var response = _impl.isLost(_UpdateIsLostResponseParamsFactory);
+        if (response is Future) {
+          return response.then((response) {
+            if (response != null) {
+              return buildResponseWithId(
+                  response,
+                  _Update_isLostName,
+                  message.header.requestId,
+                  bindings.MessageHeader.kMessageIsResponse);
+            }
+          });
+        } else if (response != null) {
+          return buildResponseWithId(
+              response,
+              _Update_isLostName,
+              message.header.requestId,
+              bindings.MessageHeader.kMessageIsResponse);
+        }
+        break;
+      case _Update_getIdName:
+        var params = _UpdateGetIdParams.deserialize(
+            message.payload);
+        var response = _impl.getId(_UpdateGetIdResponseParamsFactory);
+        if (response is Future) {
+          return response.then((response) {
+            if (response != null) {
+              return buildResponseWithId(
+                  response,
+                  _Update_getIdName,
+                  message.header.requestId,
+                  bindings.MessageHeader.kMessageIsResponse);
+            }
+          });
+        } else if (response != null) {
+          return buildResponseWithId(
+              response,
+              _Update_getIdName,
+              message.header.requestId,
+              bindings.MessageHeader.kMessageIsResponse);
+        }
+        break;
+      case _Update_getInterfaceNameName:
+        var params = _UpdateGetInterfaceNameParams.deserialize(
+            message.payload);
+        var response = _impl.getInterfaceName(_UpdateGetInterfaceNameResponseParamsFactory);
+        if (response is Future) {
+          return response.then((response) {
+            if (response != null) {
+              return buildResponseWithId(
+                  response,
+                  _Update_getInterfaceNameName,
+                  message.header.requestId,
+                  bindings.MessageHeader.kMessageIsResponse);
+            }
+          });
+        } else if (response != null) {
+          return buildResponseWithId(
+              response,
+              _Update_getInterfaceNameName,
+              message.header.requestId,
+              bindings.MessageHeader.kMessageIsResponse);
+        }
+        break;
+      case _Update_getAddressesName:
+        var params = _UpdateGetAddressesParams.deserialize(
+            message.payload);
+        var response = _impl.getAddresses(_UpdateGetAddressesResponseParamsFactory);
+        if (response is Future) {
+          return response.then((response) {
+            if (response != null) {
+              return buildResponseWithId(
+                  response,
+                  _Update_getAddressesName,
+                  message.header.requestId,
+                  bindings.MessageHeader.kMessageIsResponse);
+            }
+          });
+        } else if (response != null) {
+          return buildResponseWithId(
+              response,
+              _Update_getAddressesName,
+              message.header.requestId,
+              bindings.MessageHeader.kMessageIsResponse);
+        }
+        break;
+      case _Update_getAttributeName:
+        var params = _UpdateGetAttributeParams.deserialize(
+            message.payload);
+        var response = _impl.getAttribute(params.name,_UpdateGetAttributeResponseParamsFactory);
+        if (response is Future) {
+          return response.then((response) {
+            if (response != null) {
+              return buildResponseWithId(
+                  response,
+                  _Update_getAttributeName,
+                  message.header.requestId,
+                  bindings.MessageHeader.kMessageIsResponse);
+            }
+          });
+        } else if (response != null) {
+          return buildResponseWithId(
+              response,
+              _Update_getAttributeName,
+              message.header.requestId,
+              bindings.MessageHeader.kMessageIsResponse);
+        }
+        break;
+      case _Update_getAttachmentName:
+        var params = _UpdateGetAttachmentParams.deserialize(
+            message.payload);
+        var response = _impl.getAttachment(params.name,_UpdateGetAttachmentResponseParamsFactory);
+        if (response is Future) {
+          return response.then((response) {
+            if (response != null) {
+              return buildResponseWithId(
+                  response,
+                  _Update_getAttachmentName,
+                  message.header.requestId,
+                  bindings.MessageHeader.kMessageIsResponse);
+            }
+          });
+        } else if (response != null) {
+          return buildResponseWithId(
+              response,
+              _Update_getAttachmentName,
+              message.header.requestId,
+              bindings.MessageHeader.kMessageIsResponse);
+        }
+        break;
+      case _Update_getAdvertisementName:
+        var params = _UpdateGetAdvertisementParams.deserialize(
+            message.payload);
+        var response = _impl.getAdvertisement(_UpdateGetAdvertisementResponseParamsFactory);
+        if (response is Future) {
+          return response.then((response) {
+            if (response != null) {
+              return buildResponseWithId(
+                  response,
+                  _Update_getAdvertisementName,
+                  message.header.requestId,
+                  bindings.MessageHeader.kMessageIsResponse);
+            }
+          });
+        } else if (response != null) {
+          return buildResponseWithId(
+              response,
+              _Update_getAdvertisementName,
+              message.header.requestId,
+              bindings.MessageHeader.kMessageIsResponse);
+        }
+        break;
+      default:
+        throw new bindings.MojoCodecError("Unexpected message name");
+        break;
+    }
+    return null;
+  }
+
+  Update get impl => _impl;
+  set impl(Update d) {
+    assert(_impl == null);
+    _impl = d;
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "UpdateStub($superString)";
+  }
+
+  int get version => 0;
+
+  service_describer.ServiceDescription get serviceDescription =>
+    new _UpdateServiceDescription();
+}
+
 
 
diff --git a/mojoconfig b/mojoconfig
index 9e2c0d5..1aeabf8 100644
--- a/mojoconfig
+++ b/mojoconfig
@@ -4,6 +4,7 @@
   'dev_servers': [
     {
       'host': 'https://mojo.v.io/',
+      'port': 32000,
       'mappings': [
         ('', [
           '@{DISCOVERY_BUILD_DIR}',
diff --git a/mojom/vanadium/discovery.mojom b/mojom/vanadium/discovery.mojom
index 0ae5c2d..41786cb 100644
--- a/mojom/vanadium/discovery.mojom
+++ b/mojom/vanadium/discovery.mojom
@@ -6,79 +6,133 @@
 module discovery;
 
 // Copied from v.io/v23/discovery/types.vdl
-struct Service {
-  // The universal unique identifier of a service instance.
-  // If this is not specified, a random 128 bit (16 byte) UUID will be used.
-  string? InstanceId;
-  // Optional name of the service instance.
-  string? InstanceName;
-  // The interface that the service implements.
+//
+// Advertisement represents a feed into advertiser to broadcast its contents
+// to scanners.
+//
+// A large advertisement may require additional RPC calls causing delay in
+// discovery. We limit the maximum size of an advertisement to 512 bytes
+// excluding id and attachments.
+struct Advertisement {
+  const int32 ID_LEN = 16;
+
+  // Universal unique identifier of the advertisement.
+  // If this is not specified, a random unique identifier will be assigned.
+  array<uint8, 16>? id;
+
+  // Interface name that the advertised service implements.
   // E.g., 'v.io/v23/services/vtrace.Store'.
-  string InterfaceName;
-  // The service attributes.
+  string interface_name;
+
+  // Addresses (vanadium object names) that the advertised service is served on.
+  // E.g., '/host:port/a/b/c', '/ns.dev.v.io:8101/blah/blah'.
+  array<string> addresses;
+
+  // Attributes as a key/value pair.
   // E.g., {'resolution': '1024x768'}.
-  map<string, string>? Attrs;
-  // The addresses that the service is served on.
-  // E.g., '/host:port/a/b/c'.
-  array<string> Addrs;
-  // The service attachments.
+  //
+  // The key must be US-ASCII printable characters, excluding the '=' character
+  // and should not start with '_' character.
+  map<string, string>? attributes;
+
+  // Attachments as a key/value pair.
   // E.g., {'thumbnail': binary_data }.
-  map<string, array<uint8>>? Attachments;
+  //
+  // Unlike attributes, attachments are for binary data and they are not queryable.
+  // We limit the maximum size of a single attachment to 4K bytes.
+  //
+  // The key must be US-ASCII printable characters, excluding the '=' character
+  // and should not start with '_' character.
+  map<string, array<uint8>>? attachments;
 };
 
-enum UpdateType {
-  found = 1,
-  lost,
-};
-
-struct ScanUpdate {
-  Service service;
-  UpdateType update_type;
-};
-
+// Error wraps verror.
 struct Error {
-  string id;
-  int32 action;
+  string id;  // empty string means no error
+  uint32 action_code;
   string msg;
 };
 
-// Discovery provides Vanadium discovery operations.
+// Discovery provides Vanadium discovery service.
 [ServiceName="v23::discovery::Discovery"]
 interface Discovery {
-  // StartAdvertising advertises the service to be discovered by "Scanner"
-  // implementations. visibility is used to limit the principals that can see
-  // the advertisement. An empty set means that there are no restrictions on
-  // visibility (i.e, equivalent to []security.BlessingPattern{security.AllPrincipals}).
+  // Broadcasts the advertisement to be discovered by |Scan| operations.
+  //
+  // |visibility| is used to limit the principals that can see the advertisement. An
+  // empty set means that there are no restrictions on visibility (i.e, equivalent
+  // to []security.BlessingPattern{security.AllPrincipals}).
+  //
+  // If the advertisement id is not specified, a random unique a random unique identifier
+  // will be assigned. The advertisement should not be changed while it is being advertised.
   //
   // It is an error to have simultaneously active advertisements for two identical
-  // instances (service.InstanceUuid).
-  StartAdvertising(Service service, array<string>? visibility) => (string instance_id, Error? err);
-
-  // StopAdvertising stops the advertisement associated with the given instance id.
-  StopAdvertising(string instance_id) => (Error? Err);
-
-  // Scan scans for services matching the query passed and calls ScanHandler with updates.
+  // instances (Advertisement.id).
   //
-  // The query is a WHERE expression of syncQL query against scanned services, where
-  // keys are InstanceUuids and values are Service.
+  // Advertising will continue until the returned |closer| is closed.
+  Advertise(Advertisement ad, array<string>? visibility) => (array<uint8, 16>? instance_id, Closer? closer, Error? err);
+
+  // Scans advertisements that match the |query| and calls the |handler| with updates.
+  //
+  // Scan excludes the advertisements that are advertised from the same discovery
+  // instance.
+  //
+  // The |query| is a WHERE expression of a syncQL query against advertisements, where
+  // key is Advertisement.id and value is Advertisement.
   //
   // Examples
   //
-  //    v.InstanceName = "v.io/i"
-  //    v.InstanceName = "v.io/i" AND v.Attrs["a"] = "v"
-  //    v.Attrs["a"] = "v1" OR v.Attrs["a"] = "v2"
+  //    v.InterfaceName = "v.io/i"
+  //    v.InterfaceName = "v.io/i" AND v.Attributes["a"] = "v"
+  //    v.Attributes["a"] = "v1" OR v.Attributes["a"] = "v2"
   //
   // SyncQL tutorial at:
-  //    https://github.com/vanadium/docs/blob/master/tutorials/syncql-tutorial.md
-  StartScan(string query, ScanHandler handler) => (uint32 scan_id, Error? err);
-
-  // StopScan stops the scanning associated with the given scan id.
-  StopScan(uint32 scan_id) => (Error? err);
+  //    https://vanadium.github.io/tutorials/syncbase/syncql-tutorial.html
+  //
+  // Scanning will continue until the returned |closer| is closed.
+  Scan(string query, ScanHandler handler) => (Closer? closer, Error? err);
 };
 
-// ScanHandler is used to pass updates about services that are found/lost during the scan.
-[ServiceName="v23::discovery::ScanHandler"]
+// Closer wraps the Close method.
+interface Closer {
+  Close() => ();
+};
+
+// ScanHandler is used to pass advertisements that are found/lost during the scan.
 interface ScanHandler {
-  // Update will be called when a Service is found or lost.
-  Update(ScanUpdate update);
+  // Called with each discovery update.
+  OnUpdate(Update update);
+};
+
+// Update is the interface for a discovery update.
+interface Update {
+  // Returns true when this update corresponds to an advertisement
+  // that led to a previous update vanishing.
+  IsLost() => (bool lost);
+
+  // Returns the universal unique identifier of the advertisement.
+  GetId() => (array<uint8, 16> id);
+
+  // Returns the interface name that the service implements.
+  GetInterfaceName() => (string interface_name);
+
+  // Returns the addresses (vanadium object names) that the service
+  // is served on.
+  GetAddresses() => (array<string> addresses);
+
+  // Returns the named attribute. An empty string is returned if
+  // not found.
+  GetAttribute(string name) => (string attribute);
+
+  // Returns the channel on which the named attachment can be read.
+  // A zero-length data is returned if not found.
+  //
+  // This may do RPC calls if the attachment is not fetched yet.
+  //
+  // Attachments may not be available when this update is for lost advertisement.
+  GetAttachment(string name) => (handle<data_pipe_consumer> data);
+
+  // Returns the advertisement that this update corresponds to.
+  //
+  // The returned advertisement may not include all attachments.
+  GetAdvertisement() => (Advertisement ad);
 };
