mojo/discovery: Upgrade Discovery

The previous issue with the discovery crash should be gone with this.

Already published.

Ignoring copyright checks on the generated *.java files

Change-Id: I3276026d6113355e0d085efddd8c70b07f875bf3
diff --git a/.jiriignore b/.jiriignore
index ed981e9..6eef5c6 100644
--- a/.jiriignore
+++ b/.jiriignore
@@ -1,2 +1,3 @@
 go/src/mojom/vanadium/discovery/discovery.mojom.go
 lib/gen/dart-gen/mojom/lib/discovery/discovery.mojom.dart
+java/generated-src/io/v/mojo/discovery
diff --git a/Makefile b/Makefile
index 88d5cd9..02700ca 100644
--- a/Makefile
+++ b/Makefile
@@ -38,10 +38,16 @@
 .PHONY: gen-mojom
 gen-mojom: go/src/mojom/vanadium/discovery/discovery.mojom.go lib/gen/dart-gen/mojom/lib/mojo/discovery.mojom.dart java/generated-src/io/v/mojo/discovery/Advertiser.java
 
+# Note: These Java files are checked in.
 java/generated-src/io/v/mojo/discovery/Advertiser.java: java/generated-src/mojom/vanadium/discovery.mojom.srcjar
 	cd java/generated-src/ && jar -xf mojom/vanadium/discovery.mojom.srcjar
 
+# Clean up the old files and regenerate mojom files.
+# Due to https://github.com/domokit/mojo/issues/674, we must create the folder
+# that will hold the srcjar. This .srcjar is not checked in, however.
 java/generated-src/mojom/vanadium/discovery.mojom.srcjar: mojom/vanadium/discovery.mojom | mojo-env-check
+	rm -r java/generated-src/io/v/mojo/discovery
+	mkdir -p java/generated-src/mojom/vanadium
 	$(call MOJOM_GEN,$<,.,java/generated-src,java)
 
 go/src/mojom/vanadium/discovery/discovery.mojom.go: mojom/vanadium/discovery.mojom | mojo-env-check
diff --git a/go/src/examples/scanner/scanner.go b/go/src/examples/scanner/scanner.go
index 2ad52a1..d380ce4 100644
--- a/go/src/examples/scanner/scanner.go
+++ b/go/src/examples/scanner/scanner.go
@@ -19,7 +19,7 @@
 
 type scanHandler struct{}
 
-func (*scanHandler) Update(update discovery.Update) error {
+func (*scanHandler) Update(update discovery.ScanUpdate) error {
 	var tag string
 	switch update.UpdateType {
 	case discovery.UpdateType_Found:
diff --git a/go/src/mojom/vanadium/discovery/discovery.mojom.go b/go/src/mojom/vanadium/discovery/discovery.mojom.go
index f8e7461..3d65012 100644
--- a/go/src/mojom/vanadium/discovery/discovery.mojom.go
+++ b/go/src/mojom/vanadium/discovery/discovery.mojom.go
@@ -19,81 +19,6 @@
 	sort "sort"
 )
 
-// These IDs are the Mojom Identifiers / Type Keys.
-// Mojom libraries importing this one will use these identifiers when building
-// TypeReference objects.
-var ID_discovery_UpdateType__ string = "discovery_UpdateType__"
-var ID_discovery_Service__ string = "discovery_Service__"
-var ID_discovery_Update__ string = "discovery_Update__"
-var ID_discovery_Error__ string = "discovery_Error__"
-var ID_discovery_Discovery__ string = "discovery_Discovery__"
-var ID_discovery_ScanHandler__ string = "discovery_ScanHandler__"
-
-var discoveryDesc__ = make(map[string]mojom_types.UserDefinedType)
-
-func init() {
-	discoveryDesc__["discovery_UpdateType__"] = &mojom_types.UserDefinedTypeEnumType{
-		Value: discovery_UpdateType__(),
-	}
-	discoveryDesc__["discovery_Service__"] = &mojom_types.UserDefinedTypeStructType{
-		Value: discovery_Service__(),
-	}
-
-	discoveryDesc__["discovery_Update__"] = &mojom_types.UserDefinedTypeStructType{
-		Value: discovery_Update__(),
-	}
-
-	discoveryDesc__["discovery_Error__"] = &mojom_types.UserDefinedTypeStructType{
-		Value: discovery_Error__(),
-	}
-
-	discoveryDesc__["discovery_Discovery__"] = &mojom_types.UserDefinedTypeInterfaceType{
-		Value: discovery_Discovery__(),
-	}
-	discoveryDesc__["discovery_Discovery_StartAdvertising_Params__"] = &mojom_types.UserDefinedTypeStructType{
-		Value: discovery_Discovery_StartAdvertising_Params__(),
-	}
-
-	discoveryDesc__["discovery_Discovery_StartAdvertising_ResponseParams__"] = &mojom_types.UserDefinedTypeStructType{
-		Value: discovery_Discovery_StartAdvertising_ResponseParams__(),
-	}
-
-	discoveryDesc__["discovery_Discovery_StopAdvertising_Params__"] = &mojom_types.UserDefinedTypeStructType{
-		Value: discovery_Discovery_StopAdvertising_Params__(),
-	}
-
-	discoveryDesc__["discovery_Discovery_StopAdvertising_ResponseParams__"] = &mojom_types.UserDefinedTypeStructType{
-		Value: discovery_Discovery_StopAdvertising_ResponseParams__(),
-	}
-
-	discoveryDesc__["discovery_Discovery_StartScan_Params__"] = &mojom_types.UserDefinedTypeStructType{
-		Value: discovery_Discovery_StartScan_Params__(),
-	}
-
-	discoveryDesc__["discovery_ScanHandler__"] = &mojom_types.UserDefinedTypeInterfaceType{
-		Value: discovery_ScanHandler__(),
-	}
-	discoveryDesc__["discovery_ScanHandler_Update_Params__"] = &mojom_types.UserDefinedTypeStructType{
-		Value: discovery_ScanHandler_Update_Params__(),
-	}
-
-	discoveryDesc__["discovery_Discovery_StartScan_ResponseParams__"] = &mojom_types.UserDefinedTypeStructType{
-		Value: discovery_Discovery_StartScan_ResponseParams__(),
-	}
-
-	discoveryDesc__["discovery_Discovery_StopScan_Params__"] = &mojom_types.UserDefinedTypeStructType{
-		Value: discovery_Discovery_StopScan_Params__(),
-	}
-
-	discoveryDesc__["discovery_Discovery_StopScan_ResponseParams__"] = &mojom_types.UserDefinedTypeStructType{
-		Value: discovery_Discovery_StopScan_ResponseParams__(),
-	}
-
-}
-func GetAllMojomTypeDefinitions() map[string]mojom_types.UserDefinedType {
-	return discoveryDesc__
-}
-
 type UpdateType int32
 
 const (
@@ -101,36 +26,6 @@
 	UpdateType_Lost  = UpdateType_Found + 1
 )
 
-// String names and labels used by the MojomEnum types.
-var (
-	enumName_UpdateType            = "UpdateType"
-	enumFullIdentifier_UpdateType  = "discovery.UpdateType"
-	enumFieldName_UpdateType_Found = "Found"
-	enumFieldName_UpdateType_Lost  = "Lost"
-)
-
-func discovery_UpdateType__() mojom_types.MojomEnum {
-	return mojom_types.MojomEnum{
-		DeclData: &mojom_types.DeclarationData{
-			ShortName:      &enumName_UpdateType,
-			FullIdentifier: &enumFullIdentifier_UpdateType,
-		},
-		Values: []mojom_types.EnumValue{mojom_types.EnumValue{
-			DeclData: &mojom_types.DeclarationData{
-				ShortName: &enumFieldName_UpdateType_Found,
-			},
-			EnumTypeKey: ID_discovery_UpdateType__,
-			IntValue:    int32(1),
-		}, mojom_types.EnumValue{
-			DeclData: &mojom_types.DeclarationData{
-				ShortName: &enumFieldName_UpdateType_Lost,
-			},
-			EnumTypeKey: ID_discovery_UpdateType__,
-			IntValue:    int32(2),
-		}},
-	}
-}
-
 type Discovery interface {
 	StartAdvertising(inService Service, inVisibility *[]string) (outInstanceId string, outErr *Error, err error)
 	StopAdvertising(inInstanceId string) (outErr *Error, err error)
@@ -315,38 +210,6 @@
 	return nil
 }
 
-// String names and labels used by the MojomStruct types.
-var (
-	structName_DiscoveryStartAdvertisingParams                   = "DiscoveryStartAdvertisingParams"
-	structFullIdentifier_DiscoveryStartAdvertisingParams         = "discovery.DiscoveryStartAdvertisingParams"
-	structFieldName_DiscoveryStartAdvertisingParams_InService    = "InService"
-	structFieldName_DiscoveryStartAdvertisingParams_InVisibility = "InVisibility"
-)
-
-func discovery_Discovery_StartAdvertising_Params__() mojom_types.MojomStruct {
-	return mojom_types.MojomStruct{
-		DeclData: &mojom_types.DeclarationData{
-			ShortName:      &structName_DiscoveryStartAdvertisingParams,
-			FullIdentifier: &structFullIdentifier_DiscoveryStartAdvertisingParams,
-		}, Fields: []mojom_types.StructField{mojom_types.StructField{
-			DeclData: &mojom_types.DeclarationData{
-				ShortName: &structFieldName_DiscoveryStartAdvertisingParams_InService,
-			},
-			Type: &mojom_types.TypeTypeReference{
-				Value: mojom_types.TypeReference{Identifier: &ID_discovery_Service__,
-					TypeKey: &ID_discovery_Service__},
-			},
-		}, mojom_types.StructField{
-			DeclData: &mojom_types.DeclarationData{
-				ShortName: &structFieldName_DiscoveryStartAdvertisingParams_InVisibility,
-			},
-			Type: &mojom_types.TypeArrayType{
-				Value: mojom_types.ArrayType{Nullable: true, ElementType: &mojom_types.TypeStringType{mojom_types.StringType{false}}},
-			},
-		}},
-	}
-}
-
 type discovery_StartAdvertising_ResponseParams struct {
 	outInstanceId string
 	outErr        *Error
@@ -434,36 +297,6 @@
 	return nil
 }
 
-// String names and labels used by the MojomStruct types.
-var (
-	structName_DiscoveryStartAdvertisingResponseParams                    = "DiscoveryStartAdvertisingResponseParams"
-	structFullIdentifier_DiscoveryStartAdvertisingResponseParams          = "discovery.DiscoveryStartAdvertisingResponseParams"
-	structFieldName_DiscoveryStartAdvertisingResponseParams_OutInstanceId = "OutInstanceId"
-	structFieldName_DiscoveryStartAdvertisingResponseParams_OutErr        = "OutErr"
-)
-
-func discovery_Discovery_StartAdvertising_ResponseParams__() mojom_types.MojomStruct {
-	return mojom_types.MojomStruct{
-		DeclData: &mojom_types.DeclarationData{
-			ShortName:      &structName_DiscoveryStartAdvertisingResponseParams,
-			FullIdentifier: &structFullIdentifier_DiscoveryStartAdvertisingResponseParams,
-		}, Fields: []mojom_types.StructField{mojom_types.StructField{
-			DeclData: &mojom_types.DeclarationData{
-				ShortName: &structFieldName_DiscoveryStartAdvertisingResponseParams_OutInstanceId,
-			},
-			Type: &mojom_types.TypeStringType{mojom_types.StringType{false}},
-		}, mojom_types.StructField{
-			DeclData: &mojom_types.DeclarationData{
-				ShortName: &structFieldName_DiscoveryStartAdvertisingResponseParams_OutErr,
-			},
-			Type: &mojom_types.TypeTypeReference{
-				Value: mojom_types.TypeReference{Nullable: true, Identifier: &ID_discovery_Error__,
-					TypeKey: &ID_discovery_Error__},
-			},
-		}},
-	}
-}
-
 func (p *Discovery_Proxy) StartAdvertising(inService Service, inVisibility *[]string) (outInstanceId string, outErr *Error, err error) {
 	payload := &discovery_StartAdvertising_Params{
 		inService,
@@ -569,27 +402,6 @@
 	return nil
 }
 
-// String names and labels used by the MojomStruct types.
-var (
-	structName_DiscoveryStopAdvertisingParams                   = "DiscoveryStopAdvertisingParams"
-	structFullIdentifier_DiscoveryStopAdvertisingParams         = "discovery.DiscoveryStopAdvertisingParams"
-	structFieldName_DiscoveryStopAdvertisingParams_InInstanceId = "InInstanceId"
-)
-
-func discovery_Discovery_StopAdvertising_Params__() mojom_types.MojomStruct {
-	return mojom_types.MojomStruct{
-		DeclData: &mojom_types.DeclarationData{
-			ShortName:      &structName_DiscoveryStopAdvertisingParams,
-			FullIdentifier: &structFullIdentifier_DiscoveryStopAdvertisingParams,
-		}, Fields: []mojom_types.StructField{mojom_types.StructField{
-			DeclData: &mojom_types.DeclarationData{
-				ShortName: &structFieldName_DiscoveryStopAdvertisingParams_InInstanceId,
-			},
-			Type: &mojom_types.TypeStringType{mojom_types.StringType{false}},
-		}},
-	}
-}
-
 type discovery_StopAdvertising_ResponseParams struct {
 	outErr *Error
 }
@@ -655,30 +467,6 @@
 	return nil
 }
 
-// String names and labels used by the MojomStruct types.
-var (
-	structName_DiscoveryStopAdvertisingResponseParams             = "DiscoveryStopAdvertisingResponseParams"
-	structFullIdentifier_DiscoveryStopAdvertisingResponseParams   = "discovery.DiscoveryStopAdvertisingResponseParams"
-	structFieldName_DiscoveryStopAdvertisingResponseParams_OutErr = "OutErr"
-)
-
-func discovery_Discovery_StopAdvertising_ResponseParams__() mojom_types.MojomStruct {
-	return mojom_types.MojomStruct{
-		DeclData: &mojom_types.DeclarationData{
-			ShortName:      &structName_DiscoveryStopAdvertisingResponseParams,
-			FullIdentifier: &structFullIdentifier_DiscoveryStopAdvertisingResponseParams,
-		}, Fields: []mojom_types.StructField{mojom_types.StructField{
-			DeclData: &mojom_types.DeclarationData{
-				ShortName: &structFieldName_DiscoveryStopAdvertisingResponseParams_OutErr,
-			},
-			Type: &mojom_types.TypeTypeReference{
-				Value: mojom_types.TypeReference{Nullable: true, Identifier: &ID_discovery_Error__,
-					TypeKey: &ID_discovery_Error__},
-			},
-		}},
-	}
-}
-
 func (p *Discovery_Proxy) StopAdvertising(inInstanceId string) (outErr *Error, err error) {
 	payload := &discovery_StopAdvertising_Params{
 		inInstanceId,
@@ -798,36 +586,6 @@
 	return nil
 }
 
-// String names and labels used by the MojomStruct types.
-var (
-	structName_DiscoveryStartScanParams                = "DiscoveryStartScanParams"
-	structFullIdentifier_DiscoveryStartScanParams      = "discovery.DiscoveryStartScanParams"
-	structFieldName_DiscoveryStartScanParams_InQuery   = "InQuery"
-	structFieldName_DiscoveryStartScanParams_InHandler = "InHandler"
-)
-
-func discovery_Discovery_StartScan_Params__() mojom_types.MojomStruct {
-	return mojom_types.MojomStruct{
-		DeclData: &mojom_types.DeclarationData{
-			ShortName:      &structName_DiscoveryStartScanParams,
-			FullIdentifier: &structFullIdentifier_DiscoveryStartScanParams,
-		}, Fields: []mojom_types.StructField{mojom_types.StructField{
-			DeclData: &mojom_types.DeclarationData{
-				ShortName: &structFieldName_DiscoveryStartScanParams_InQuery,
-			},
-			Type: &mojom_types.TypeStringType{mojom_types.StringType{false}},
-		}, mojom_types.StructField{
-			DeclData: &mojom_types.DeclarationData{
-				ShortName: &structFieldName_DiscoveryStartScanParams_InHandler,
-			},
-			Type: &mojom_types.TypeTypeReference{
-				Value: mojom_types.TypeReference{Identifier: &ID_discovery_ScanHandler__,
-					TypeKey: &ID_discovery_ScanHandler__},
-			},
-		}},
-	}
-}
-
 type discovery_StartScan_ResponseParams struct {
 	outScanId uint32
 	outErr    *Error
@@ -904,36 +662,6 @@
 	return nil
 }
 
-// String names and labels used by the MojomStruct types.
-var (
-	structName_DiscoveryStartScanResponseParams                = "DiscoveryStartScanResponseParams"
-	structFullIdentifier_DiscoveryStartScanResponseParams      = "discovery.DiscoveryStartScanResponseParams"
-	structFieldName_DiscoveryStartScanResponseParams_OutScanId = "OutScanId"
-	structFieldName_DiscoveryStartScanResponseParams_OutErr    = "OutErr"
-)
-
-func discovery_Discovery_StartScan_ResponseParams__() mojom_types.MojomStruct {
-	return mojom_types.MojomStruct{
-		DeclData: &mojom_types.DeclarationData{
-			ShortName:      &structName_DiscoveryStartScanResponseParams,
-			FullIdentifier: &structFullIdentifier_DiscoveryStartScanResponseParams,
-		}, Fields: []mojom_types.StructField{mojom_types.StructField{
-			DeclData: &mojom_types.DeclarationData{
-				ShortName: &structFieldName_DiscoveryStartScanResponseParams_OutScanId,
-			},
-			Type: &mojom_types.TypeSimpleType{mojom_types.SimpleType_UinT32},
-		}, mojom_types.StructField{
-			DeclData: &mojom_types.DeclarationData{
-				ShortName: &structFieldName_DiscoveryStartScanResponseParams_OutErr,
-			},
-			Type: &mojom_types.TypeTypeReference{
-				Value: mojom_types.TypeReference{Nullable: true, Identifier: &ID_discovery_Error__,
-					TypeKey: &ID_discovery_Error__},
-			},
-		}},
-	}
-}
-
 func (p *Discovery_Proxy) StartScan(inQuery string, inHandler ScanHandler_Pointer) (outScanId uint32, outErr *Error, err error) {
 	payload := &discovery_StartScan_Params{
 		inQuery,
@@ -1028,27 +756,6 @@
 	return nil
 }
 
-// String names and labels used by the MojomStruct types.
-var (
-	structName_DiscoveryStopScanParams               = "DiscoveryStopScanParams"
-	structFullIdentifier_DiscoveryStopScanParams     = "discovery.DiscoveryStopScanParams"
-	structFieldName_DiscoveryStopScanParams_InScanId = "InScanId"
-)
-
-func discovery_Discovery_StopScan_Params__() mojom_types.MojomStruct {
-	return mojom_types.MojomStruct{
-		DeclData: &mojom_types.DeclarationData{
-			ShortName:      &structName_DiscoveryStopScanParams,
-			FullIdentifier: &structFullIdentifier_DiscoveryStopScanParams,
-		}, Fields: []mojom_types.StructField{mojom_types.StructField{
-			DeclData: &mojom_types.DeclarationData{
-				ShortName: &structFieldName_DiscoveryStopScanParams_InScanId,
-			},
-			Type: &mojom_types.TypeSimpleType{mojom_types.SimpleType_UinT32},
-		}},
-	}
-}
-
 type discovery_StopScan_ResponseParams struct {
 	outErr *Error
 }
@@ -1114,30 +821,6 @@
 	return nil
 }
 
-// String names and labels used by the MojomStruct types.
-var (
-	structName_DiscoveryStopScanResponseParams             = "DiscoveryStopScanResponseParams"
-	structFullIdentifier_DiscoveryStopScanResponseParams   = "discovery.DiscoveryStopScanResponseParams"
-	structFieldName_DiscoveryStopScanResponseParams_OutErr = "OutErr"
-)
-
-func discovery_Discovery_StopScan_ResponseParams__() mojom_types.MojomStruct {
-	return mojom_types.MojomStruct{
-		DeclData: &mojom_types.DeclarationData{
-			ShortName:      &structName_DiscoveryStopScanResponseParams,
-			FullIdentifier: &structFullIdentifier_DiscoveryStopScanResponseParams,
-		}, Fields: []mojom_types.StructField{mojom_types.StructField{
-			DeclData: &mojom_types.DeclarationData{
-				ShortName: &structFieldName_DiscoveryStopScanResponseParams_OutErr,
-			},
-			Type: &mojom_types.TypeTypeReference{
-				Value: mojom_types.TypeReference{Nullable: true, Identifier: &ID_discovery_Error__,
-					TypeKey: &ID_discovery_Error__},
-			},
-		}},
-	}
-}
-
 func (p *Discovery_Proxy) StopScan(inScanId uint32) (outErr *Error, err error) {
 	payload := &discovery_StopScan_Params{
 		inScanId,
@@ -1189,59 +872,6 @@
 	return bindings.NewStub(connector, &discovery_Stub{connector, impl})
 }
 
-var (
-	interfaceName_Discovery                        = "Discovery"
-	interfaceFullIdentifier_Discovery              = "discovery.Discovery"
-	interfaceMethodName_Discovery_StartAdvertising = "StartAdvertising"
-	interfaceMethodName_Discovery_StopAdvertising  = "StopAdvertising"
-	interfaceMethodName_Discovery_StartScan        = "StartScan"
-	interfaceMethodName_Discovery_StopScan         = "StopScan"
-)
-
-func discovery_Discovery__() mojom_types.MojomInterface {
-	responseParamsMap := make(map[string]*mojom_types.MojomStruct)
-	_ = responseParamsMap // To avoid the declared but unused compiler error
-	mstruct_StartAdvertising := discovery_Discovery_StartAdvertising_ResponseParams__()
-	responseParamsMap[interfaceMethodName_Discovery_StartAdvertising] = &mstruct_StartAdvertising
-	mstruct_StopAdvertising := discovery_Discovery_StopAdvertising_ResponseParams__()
-	responseParamsMap[interfaceMethodName_Discovery_StopAdvertising] = &mstruct_StopAdvertising
-	mstruct_StartScan := discovery_Discovery_StartScan_ResponseParams__()
-	responseParamsMap[interfaceMethodName_Discovery_StartScan] = &mstruct_StartScan
-	mstruct_StopScan := discovery_Discovery_StopScan_ResponseParams__()
-	responseParamsMap[interfaceMethodName_Discovery_StopScan] = &mstruct_StopScan
-	return mojom_types.MojomInterface{
-		DeclData: &mojom_types.DeclarationData{
-			ShortName:      &interfaceName_Discovery,
-			FullIdentifier: &interfaceFullIdentifier_Discovery,
-		},
-		Methods: map[uint32]mojom_types.MojomMethod{discovery_StartAdvertising_Name: mojom_types.MojomMethod{
-			DeclData: &mojom_types.DeclarationData{
-				ShortName: &interfaceMethodName_Discovery_StartAdvertising,
-			},
-			Parameters:     discovery_Discovery_StartAdvertising_Params__(),
-			ResponseParams: responseParamsMap[interfaceMethodName_Discovery_StartAdvertising],
-		}, discovery_StopAdvertising_Name: mojom_types.MojomMethod{
-			DeclData: &mojom_types.DeclarationData{
-				ShortName: &interfaceMethodName_Discovery_StopAdvertising,
-			},
-			Parameters:     discovery_Discovery_StopAdvertising_Params__(),
-			ResponseParams: responseParamsMap[interfaceMethodName_Discovery_StopAdvertising],
-		}, discovery_StartScan_Name: mojom_types.MojomMethod{
-			DeclData: &mojom_types.DeclarationData{
-				ShortName: &interfaceMethodName_Discovery_StartScan,
-			},
-			Parameters:     discovery_Discovery_StartScan_Params__(),
-			ResponseParams: responseParamsMap[interfaceMethodName_Discovery_StartScan],
-		}, discovery_StopScan_Name: mojom_types.MojomMethod{
-			DeclData: &mojom_types.DeclarationData{
-				ShortName: &interfaceMethodName_Discovery_StopScan,
-			},
-			Parameters:     discovery_Discovery_StopScan_Params__(),
-			ResponseParams: responseParamsMap[interfaceMethodName_Discovery_StopScan],
-		}},
-	}
-}
-
 func (f *Discovery_Request) ServiceDescription() service_describer.ServiceDescription {
 	return &Discovery_ServiceDescription{}
 }
@@ -1249,19 +879,18 @@
 type Discovery_ServiceDescription struct{}
 
 func (sd *Discovery_ServiceDescription) GetTopLevelInterface() (outMojomInterface mojom_types.MojomInterface, err error) {
-	return discovery_Discovery__(), nil
+	err = fmt.Errorf("GetTopLevelInterface not implemented")
+	return
 }
 
 func (sd *Discovery_ServiceDescription) GetTypeDefinition(inTypeKey string) (outType mojom_types.UserDefinedType, err error) {
-	if udt, ok := GetAllMojomTypeDefinitions()[inTypeKey]; ok {
-		return udt, nil
-	}
-	return nil, fmt.Errorf("%s_ServiceDescription does not recognize %s", "Discovery", inTypeKey)
+	err = fmt.Errorf("GetTypeDefinition not implemented")
+	return
 }
 
 func (sd *Discovery_ServiceDescription) GetAllTypeDefinitions() (outDefinitions *map[string]mojom_types.UserDefinedType, err error) {
-	o := GetAllMojomTypeDefinitions()
-	return &o, nil
+	err = fmt.Errorf("GetAllTypeDefinitions not implemented")
+	return
 }
 
 var _ service_describer.ServiceDescription = (*Discovery_ServiceDescription)(nil)
@@ -1378,7 +1007,7 @@
 }
 
 type ScanHandler interface {
-	Update(inUpdate Update) (err error)
+	Update(inUpdate ScanUpdate) (err error)
 }
 
 var scanHandler_Name = "v23::discovery::ScanHandler"
@@ -1442,7 +1071,7 @@
 }
 
 type scanHandler_Update_Params struct {
-	inUpdate Update
+	inUpdate ScanUpdate
 }
 
 func (s *scanHandler_Update_Params) Encode(encoder *bindings.Encoder) error {
@@ -1501,31 +1130,7 @@
 	return nil
 }
 
-// String names and labels used by the MojomStruct types.
-var (
-	structName_ScanHandlerUpdateParams               = "ScanHandlerUpdateParams"
-	structFullIdentifier_ScanHandlerUpdateParams     = "discovery.ScanHandlerUpdateParams"
-	structFieldName_ScanHandlerUpdateParams_InUpdate = "InUpdate"
-)
-
-func discovery_ScanHandler_Update_Params__() mojom_types.MojomStruct {
-	return mojom_types.MojomStruct{
-		DeclData: &mojom_types.DeclarationData{
-			ShortName:      &structName_ScanHandlerUpdateParams,
-			FullIdentifier: &structFullIdentifier_ScanHandlerUpdateParams,
-		}, Fields: []mojom_types.StructField{mojom_types.StructField{
-			DeclData: &mojom_types.DeclarationData{
-				ShortName: &structFieldName_ScanHandlerUpdateParams_InUpdate,
-			},
-			Type: &mojom_types.TypeTypeReference{
-				Value: mojom_types.TypeReference{Identifier: &ID_discovery_Update__,
-					TypeKey: &ID_discovery_Update__},
-			},
-		}},
-	}
-}
-
-func (p *ScanHandler_Proxy) Update(inUpdate Update) (err error) {
+func (p *ScanHandler_Proxy) Update(inUpdate ScanUpdate) (err error) {
 	payload := &scanHandler_Update_Params{
 		inUpdate,
 	}
@@ -1556,30 +1161,6 @@
 	return bindings.NewStub(connector, &scanHandler_Stub{connector, impl})
 }
 
-var (
-	interfaceName_ScanHandler              = "ScanHandler"
-	interfaceFullIdentifier_ScanHandler    = "discovery.ScanHandler"
-	interfaceMethodName_ScanHandler_Update = "Update"
-)
-
-func discovery_ScanHandler__() mojom_types.MojomInterface {
-	responseParamsMap := make(map[string]*mojom_types.MojomStruct)
-	_ = responseParamsMap // To avoid the declared but unused compiler error
-	return mojom_types.MojomInterface{
-		DeclData: &mojom_types.DeclarationData{
-			ShortName:      &interfaceName_ScanHandler,
-			FullIdentifier: &interfaceFullIdentifier_ScanHandler,
-		},
-		Methods: map[uint32]mojom_types.MojomMethod{scanHandler_Update_Name: mojom_types.MojomMethod{
-			DeclData: &mojom_types.DeclarationData{
-				ShortName: &interfaceMethodName_ScanHandler_Update,
-			},
-			Parameters:     discovery_ScanHandler_Update_Params__(),
-			ResponseParams: responseParamsMap[interfaceMethodName_ScanHandler_Update],
-		}},
-	}
-}
-
 func (f *ScanHandler_Request) ServiceDescription() service_describer.ServiceDescription {
 	return &ScanHandler_ServiceDescription{}
 }
@@ -1587,19 +1168,18 @@
 type ScanHandler_ServiceDescription struct{}
 
 func (sd *ScanHandler_ServiceDescription) GetTopLevelInterface() (outMojomInterface mojom_types.MojomInterface, err error) {
-	return discovery_ScanHandler__(), nil
+	err = fmt.Errorf("GetTopLevelInterface not implemented")
+	return
 }
 
 func (sd *ScanHandler_ServiceDescription) GetTypeDefinition(inTypeKey string) (outType mojom_types.UserDefinedType, err error) {
-	if udt, ok := GetAllMojomTypeDefinitions()[inTypeKey]; ok {
-		return udt, nil
-	}
-	return nil, fmt.Errorf("%s_ServiceDescription does not recognize %s", "ScanHandler", inTypeKey)
+	err = fmt.Errorf("GetTypeDefinition not implemented")
+	return
 }
 
 func (sd *ScanHandler_ServiceDescription) GetAllTypeDefinitions() (outDefinitions *map[string]mojom_types.UserDefinedType, err error) {
-	o := GetAllMojomTypeDefinitions()
-	return &o, nil
+	err = fmt.Errorf("GetAllTypeDefinitions not implemented")
+	return
 }
 
 var _ service_describer.ServiceDescription = (*ScanHandler_ServiceDescription)(nil)
@@ -2102,75 +1682,12 @@
 	return nil
 }
 
-// String names and labels used by the MojomStruct types.
-var (
-	structName_Service                    = "Service"
-	structFullIdentifier_Service          = "discovery.Service"
-	structFieldName_Service_InstanceId    = "InstanceId"
-	structFieldName_Service_InstanceName  = "InstanceName"
-	structFieldName_Service_InterfaceName = "InterfaceName"
-	structFieldName_Service_Attrs         = "Attrs"
-	structFieldName_Service_Addrs         = "Addrs"
-	structFieldName_Service_Attachments   = "Attachments"
-)
-
-func discovery_Service__() mojom_types.MojomStruct {
-	return mojom_types.MojomStruct{
-		DeclData: &mojom_types.DeclarationData{
-			ShortName:      &structName_Service,
-			FullIdentifier: &structFullIdentifier_Service,
-		}, Fields: []mojom_types.StructField{mojom_types.StructField{
-			DeclData: &mojom_types.DeclarationData{
-				ShortName: &structFieldName_Service_InstanceId,
-			},
-			Type: &mojom_types.TypeStringType{mojom_types.StringType{true}},
-		}, mojom_types.StructField{
-			DeclData: &mojom_types.DeclarationData{
-				ShortName: &structFieldName_Service_InstanceName,
-			},
-			Type: &mojom_types.TypeStringType{mojom_types.StringType{true}},
-		}, mojom_types.StructField{
-			DeclData: &mojom_types.DeclarationData{
-				ShortName: &structFieldName_Service_InterfaceName,
-			},
-			Type: &mojom_types.TypeStringType{mojom_types.StringType{false}},
-		}, mojom_types.StructField{
-			DeclData: &mojom_types.DeclarationData{
-				ShortName: &structFieldName_Service_Attrs,
-			},
-			Type: &mojom_types.TypeMapType{
-				Value: mojom_types.MapType{Nullable: true, KeyType: &mojom_types.TypeStringType{mojom_types.StringType{false}},
-					ValueType: &mojom_types.TypeStringType{mojom_types.StringType{false}},
-				},
-			},
-		}, mojom_types.StructField{
-			DeclData: &mojom_types.DeclarationData{
-				ShortName: &structFieldName_Service_Addrs,
-			},
-			Type: &mojom_types.TypeArrayType{
-				Value: mojom_types.ArrayType{ElementType: &mojom_types.TypeStringType{mojom_types.StringType{false}}},
-			},
-		}, mojom_types.StructField{
-			DeclData: &mojom_types.DeclarationData{
-				ShortName: &structFieldName_Service_Attachments,
-			},
-			Type: &mojom_types.TypeMapType{
-				Value: mojom_types.MapType{Nullable: true, KeyType: &mojom_types.TypeStringType{mojom_types.StringType{false}},
-					ValueType: &mojom_types.TypeArrayType{
-						Value: mojom_types.ArrayType{ElementType: &mojom_types.TypeSimpleType{mojom_types.SimpleType_UinT8}},
-					},
-				},
-			},
-		}},
-	}
-}
-
-type Update struct {
+type ScanUpdate struct {
 	Service    Service
 	UpdateType UpdateType
 }
 
-func (s *Update) Encode(encoder *bindings.Encoder) error {
+func (s *ScanUpdate) Encode(encoder *bindings.Encoder) error {
 	encoder.StartStruct(16, 0)
 	if err := encoder.WritePointer(); err != nil {
 		return err
@@ -2187,23 +1704,23 @@
 	return nil
 }
 
-var update_Versions []bindings.DataHeader = []bindings.DataHeader{
+var scanUpdate_Versions []bindings.DataHeader = []bindings.DataHeader{
 	bindings.DataHeader{24, 0},
 }
 
-func (s *Update) Decode(decoder *bindings.Decoder) error {
+func (s *ScanUpdate) Decode(decoder *bindings.Decoder) error {
 	header, err := decoder.StartStruct()
 	if err != nil {
 		return err
 	}
-	index := sort.Search(len(update_Versions), func(i int) bool {
-		return update_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
+	index := sort.Search(len(scanUpdate_Versions), func(i int) bool {
+		return scanUpdate_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
 	})
-	if index < len(update_Versions) {
-		if update_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
+	if index < len(scanUpdate_Versions) {
+		if scanUpdate_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
 			index--
 		}
-		expectedSize := update_Versions[index].Size
+		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),
@@ -2236,39 +1753,6 @@
 	return nil
 }
 
-// String names and labels used by the MojomStruct types.
-var (
-	structName_Update                 = "Update"
-	structFullIdentifier_Update       = "discovery.Update"
-	structFieldName_Update_Service    = "Service"
-	structFieldName_Update_UpdateType = "UpdateType"
-)
-
-func discovery_Update__() mojom_types.MojomStruct {
-	return mojom_types.MojomStruct{
-		DeclData: &mojom_types.DeclarationData{
-			ShortName:      &structName_Update,
-			FullIdentifier: &structFullIdentifier_Update,
-		}, Fields: []mojom_types.StructField{mojom_types.StructField{
-			DeclData: &mojom_types.DeclarationData{
-				ShortName: &structFieldName_Update_Service,
-			},
-			Type: &mojom_types.TypeTypeReference{
-				Value: mojom_types.TypeReference{Identifier: &ID_discovery_Service__,
-					TypeKey: &ID_discovery_Service__},
-			},
-		}, mojom_types.StructField{
-			DeclData: &mojom_types.DeclarationData{
-				ShortName: &structFieldName_Update_UpdateType,
-			},
-			Type: &mojom_types.TypeTypeReference{
-				Value: mojom_types.TypeReference{Identifier: &ID_discovery_UpdateType__,
-					TypeKey: &ID_discovery_UpdateType__},
-			},
-		}},
-	}
-}
-
 type Error struct {
 	Id     string
 	Action int32
@@ -2363,36 +1847,3 @@
 	}
 	return nil
 }
-
-// String names and labels used by the MojomStruct types.
-var (
-	structName_Error             = "Error"
-	structFullIdentifier_Error   = "discovery.Error"
-	structFieldName_Error_Id     = "Id"
-	structFieldName_Error_Action = "Action"
-	structFieldName_Error_Msg    = "Msg"
-)
-
-func discovery_Error__() mojom_types.MojomStruct {
-	return mojom_types.MojomStruct{
-		DeclData: &mojom_types.DeclarationData{
-			ShortName:      &structName_Error,
-			FullIdentifier: &structFullIdentifier_Error,
-		}, Fields: []mojom_types.StructField{mojom_types.StructField{
-			DeclData: &mojom_types.DeclarationData{
-				ShortName: &structFieldName_Error_Id,
-			},
-			Type: &mojom_types.TypeStringType{mojom_types.StringType{false}},
-		}, mojom_types.StructField{
-			DeclData: &mojom_types.DeclarationData{
-				ShortName: &structFieldName_Error_Action,
-			},
-			Type: &mojom_types.TypeSimpleType{mojom_types.SimpleType_InT32},
-		}, mojom_types.StructField{
-			DeclData: &mojom_types.DeclarationData{
-				ShortName: &structFieldName_Error_Msg,
-			},
-			Type: &mojom_types.TypeStringType{mojom_types.StringType{false}},
-		}},
-	}
-}
diff --git a/go/src/vanadium/discovery/internal/discovery.go b/go/src/vanadium/discovery/internal/discovery.go
index 2b582bb..949995a 100644
--- a/go/src/vanadium/discovery/internal/discovery.go
+++ b/go/src/vanadium/discovery/internal/discovery.go
@@ -158,15 +158,15 @@
 		defer proxy.Close_Proxy()
 
 		for update := range scanCh {
-			var mupdate mojom.Update
+			var mupdate mojom.ScanUpdate
 			switch u := update.(type) {
 			case discovery.UpdateFound:
-				mupdate = mojom.Update{
+				mupdate = mojom.ScanUpdate{
 					Service:    v2mService(u.Value.Service),
 					UpdateType: mojom.UpdateType_Found,
 				}
 			case discovery.UpdateLost:
-				mupdate = mojom.Update{
+				mupdate = mojom.ScanUpdate{
 					Service:    v2mService(u.Value.Service),
 					UpdateType: mojom.UpdateType_Lost,
 				}
diff --git a/go/src/vanadium/discovery/internal/discovery_test.go b/go/src/vanadium/discovery/internal/discovery_test.go
index 85829b3..a34cc8c 100644
--- a/go/src/vanadium/discovery/internal/discovery_test.go
+++ b/go/src/vanadium/discovery/internal/discovery_test.go
@@ -87,7 +87,7 @@
 	}
 	defer scanStop()
 	update := <-scanCh
-	if !matchFound([]mojom.Update{update}, services[0]) {
+	if !matchFound([]mojom.ScanUpdate{update}, services[0]) {
 		t.Errorf("unexpected scan: %v", update)
 	}
 
@@ -95,7 +95,7 @@
 	d1.StopAdvertising(services[0].InstanceId)
 
 	update = <-scanCh
-	if !matchLost([]mojom.Update{update}, services[0]) {
+	if !matchLost([]mojom.ScanUpdate{update}, services[0]) {
 		t.Errorf("unexpected scan: %v", update)
 	}
 
@@ -112,17 +112,17 @@
 }
 
 type mockScanHandler struct {
-	ch chan mojom.Update
+	ch chan mojom.ScanUpdate
 }
 
-func (m *mockScanHandler) Update(u mojom.Update) error {
+func (m *mockScanHandler) Update(u mojom.ScanUpdate) error {
 	m.ch <- u
 	return nil
 }
 func (m *mockScanHandler) Close_Proxy() { close(m.ch) }
 
-func startScan(d mojom.Discovery, query string) (<-chan mojom.Update, func(), error) {
-	ch := make(chan mojom.Update)
+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)
@@ -135,14 +135,14 @@
 	return ch, stop, nil
 }
 
-func scan(d mojom.Discovery, query string) ([]mojom.Update, error) {
+func scan(d mojom.Discovery, query string) ([]mojom.ScanUpdate, error) {
 	ch, stop, err := startScan(d, query)
 	if err != nil {
 		return nil, err
 	}
 	defer stop()
 
-	var updates []mojom.Update
+	var updates []mojom.ScanUpdate
 	for {
 		select {
 		case update := <-ch:
@@ -156,7 +156,7 @@
 func scanAndMatch(d mojom.Discovery, query string, wants ...discovery.Service) error {
 	const timeout = 3 * time.Second
 
-	var updates []mojom.Update
+	var updates []mojom.ScanUpdate
 	for now := time.Now(); time.Since(now) < timeout; {
 		runtime.Gosched()
 
@@ -172,7 +172,7 @@
 	return fmt.Errorf("Match failed; got %v, but wanted %v", updates, wants)
 }
 
-func match(updates []mojom.Update, updateType mojom.UpdateType, wants ...discovery.Service) bool {
+func match(updates []mojom.ScanUpdate, updateType mojom.UpdateType, wants ...discovery.Service) bool {
 	for _, want := range wants {
 		matched := false
 		for i, update := range updates {
@@ -189,11 +189,11 @@
 	return len(updates) == 0
 }
 
-func matchFound(updates []mojom.Update, wants ...discovery.Service) bool {
+func matchFound(updates []mojom.ScanUpdate, wants ...discovery.Service) bool {
 	return match(updates, mojom.UpdateType_Found, wants...)
 }
 
-func matchLost(updates []mojom.Update, wants ...discovery.Service) bool {
+func matchLost(updates []mojom.ScanUpdate, wants ...discovery.Service) bool {
 	return match(updates, mojom.UpdateType_Lost, wants...)
 }
 
diff --git a/java/generated-src/io/v/mojo/discovery/Advertiser.java b/java/generated-src/io/v/mojo/discovery/Advertiser.java
deleted file mode 100644
index 2878c73..0000000
--- a/java/generated-src/io/v/mojo/discovery/Advertiser.java
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2015 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// 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 Advertiser extends org.chromium.mojo.bindings.Interface {
-
-    public interface Proxy extends Advertiser, org.chromium.mojo.bindings.Interface.Proxy {
-    }
-
-    NamedManager<Advertiser, Advertiser.Proxy> MANAGER = Advertiser_Internal.MANAGER;
-
-    void advertise(Service service, String[] visibility, AdvertiseResponse callback);
-    interface AdvertiseResponse extends org.chromium.mojo.bindings.Callbacks.Callback3<Integer, String, Error> { }
-
-    void stop(int h, StopResponse callback);
-    interface StopResponse extends org.chromium.mojo.bindings.Callbacks.Callback1<Error> { }
-}
-
diff --git a/java/generated-src/io/v/mojo/discovery/Advertiser_Internal.java b/java/generated-src/io/v/mojo/discovery/Advertiser_Internal.java
deleted file mode 100644
index 8ae035f..0000000
--- a/java/generated-src/io/v/mojo/discovery/Advertiser_Internal.java
+++ /dev/null
@@ -1,584 +0,0 @@
-// Copyright 2015 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// 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 Advertiser_Internal {
-
-    public static final org.chromium.mojo.bindings.Interface.NamedManager<Advertiser, Advertiser.Proxy> MANAGER =
-            new org.chromium.mojo.bindings.Interface.NamedManager<Advertiser, Advertiser.Proxy>() {
-    
-        public String getName() {
-            return "v23::discovery::Advertiser";
-        }
-    
-        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, Advertiser impl) {
-            return new Stub(core, impl);
-        }
-    
-        public Advertiser[] buildArray(int size) {
-          return new Advertiser[size];
-        }
-    };
-
-    private static final int ADVERTISE_ORDINAL = 0;
-    private static final int STOP_ORDINAL = 1;
-
-    static final class Proxy extends org.chromium.mojo.bindings.Interface.AbstractProxy implements Advertiser.Proxy {
-
-        Proxy(org.chromium.mojo.system.Core core,
-              org.chromium.mojo.bindings.MessageReceiverWithResponder messageReceiver) {
-            super(core, messageReceiver);
-        }
-
-        @Override
-        public void advertise(Service service, String[] visibility, AdvertiseResponse callback) {
-            AdvertiserAdvertiseParams _message = new AdvertiserAdvertiseParams();
-            _message.service = service;
-            _message.visibility = visibility;
-            getProxyHandler().getMessageReceiver().acceptWithResponder(
-                    _message.serializeWithHeader(
-                            getProxyHandler().getCore(),
-                            new org.chromium.mojo.bindings.MessageHeader(
-                                    ADVERTISE_ORDINAL,
-                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG,
-                                    0)),
-                    new AdvertiserAdvertiseResponseParamsForwardToCallback(callback));
-        }
-
-        @Override
-        public void stop(int h, StopResponse callback) {
-            AdvertiserStopParams _message = new AdvertiserStopParams();
-            _message.h = h;
-            getProxyHandler().getMessageReceiver().acceptWithResponder(
-                    _message.serializeWithHeader(
-                            getProxyHandler().getCore(),
-                            new org.chromium.mojo.bindings.MessageHeader(
-                                    STOP_ORDINAL,
-                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG,
-                                    0)),
-                    new AdvertiserStopResponseParamsForwardToCallback(callback));
-        }
-
-    }
-
-    static final class Stub extends org.chromium.mojo.bindings.Interface.Stub<Advertiser> {
-
-        Stub(org.chromium.mojo.system.Core core, Advertiser 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(
-                                Advertiser_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(), Advertiser_Internal.MANAGER, messageWithHeader, receiver);
-                    case ADVERTISE_ORDINAL: {
-                        AdvertiserAdvertiseParams data =
-                                AdvertiserAdvertiseParams.deserialize(messageWithHeader.getPayload());
-                        getImpl().advertise(data.service, data.visibility, new AdvertiserAdvertiseResponseParamsProxyToResponder(getCore(), receiver, header.getRequestId()));
-                        return true;
-                    }
-                    case STOP_ORDINAL: {
-                        AdvertiserStopParams data =
-                                AdvertiserStopParams.deserialize(messageWithHeader.getPayload());
-                        getImpl().stop(data.h, new AdvertiserStopResponseParamsProxyToResponder(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 AdvertiserAdvertiseParams 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 String[] visibility;
-    
-        private AdvertiserAdvertiseParams(int version) {
-            super(STRUCT_SIZE, version);
-        }
-    
-        public AdvertiserAdvertiseParams() {
-            this(0);
-        }
-    
-        public static AdvertiserAdvertiseParams deserialize(org.chromium.mojo.bindings.Message message) {
-            return decode(new org.chromium.mojo.bindings.Decoder(message));
-        }
-    
-        @SuppressWarnings("unchecked")
-        public static AdvertiserAdvertiseParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
-            if (decoder0 == null) {
-                return null;
-            }
-            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-            AdvertiserAdvertiseParams result = new AdvertiserAdvertiseParams(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) {
-                org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(16, true);
-                if (decoder1 == null) {
-                    result.visibility = null;
-                } else {
-                    org.chromium.mojo.bindings.DataHeader si1 = decoder1.readDataHeaderForPointerArray(org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
-                    result.visibility = new String[si1.elementsOrVersion];
-                    for (int i1 = 0; i1 < si1.elementsOrVersion; ++i1) {
-                        result.visibility[i1] = decoder1.readString(org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i1, false);
-                    }
-                }
-            }
-            return result;
-        }
-    
-        @SuppressWarnings("unchecked")
-        @Override
-        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
-            org.chromium.mojo.bindings.Encoder encoder0 = encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
-            encoder0.encode(service, 8, false);
-            if (visibility == null) {
-                encoder0.encodeNullPointer(16, true);
-            } else {
-                org.chromium.mojo.bindings.Encoder encoder1 = encoder0.encodePointerArray(visibility.length, 16, org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
-                for (int i0 = 0; i0 < visibility.length; ++i0) {
-                    encoder1.encode(visibility[i0], org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i0, false);
-                }
-            }
-        }
-    
-        /**
-         * @see Object#equals(Object)
-         */
-        @Override
-        public boolean equals(Object object) {
-            if (object == this)
-                return true;
-            if (object == null)
-                return false;
-            if (getClass() != object.getClass())
-                return false;
-            AdvertiserAdvertiseParams other = (AdvertiserAdvertiseParams) object;
-            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.service, other.service))
-                return false;
-            if (!java.util.Arrays.deepEquals(this.visibility, other.visibility))
-                return false;
-            return true;
-        }
-    
-        /**
-         * @see Object#hashCode()
-         */
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = prime + getClass().hashCode();
-            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(service);
-            result = prime * result + java.util.Arrays.deepHashCode(visibility);
-            return result;
-        }
-    }
-
-    static final class AdvertiserAdvertiseResponseParams extends org.chromium.mojo.bindings.Struct {
-    
-        private static final int STRUCT_SIZE = 32;
-        private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(32, 0)};
-        private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
-    
-        public int handle;
-        public String instanceId;
-        public Error err;
-    
-        private AdvertiserAdvertiseResponseParams(int version) {
-            super(STRUCT_SIZE, version);
-        }
-    
-        public AdvertiserAdvertiseResponseParams() {
-            this(0);
-        }
-    
-        public static AdvertiserAdvertiseResponseParams deserialize(org.chromium.mojo.bindings.Message message) {
-            return decode(new org.chromium.mojo.bindings.Decoder(message));
-        }
-    
-        @SuppressWarnings("unchecked")
-        public static AdvertiserAdvertiseResponseParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
-            if (decoder0 == null) {
-                return null;
-            }
-            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-            AdvertiserAdvertiseResponseParams result = new AdvertiserAdvertiseResponseParams(mainDataHeader.elementsOrVersion);
-            if (mainDataHeader.elementsOrVersion >= 0) {
-                result.handle = decoder0.readInt(8);
-            }
-            if (mainDataHeader.elementsOrVersion >= 0) {
-                result.instanceId = decoder0.readString(16, false);
-            }
-            if (mainDataHeader.elementsOrVersion >= 0) {
-                org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(24, true);
-                result.err = Error.decode(decoder1);
-            }
-            return result;
-        }
-    
-        @SuppressWarnings("unchecked")
-        @Override
-        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
-            org.chromium.mojo.bindings.Encoder encoder0 = encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
-            encoder0.encode(handle, 8);
-            encoder0.encode(instanceId, 16, false);
-            encoder0.encode(err, 24, true);
-        }
-    
-        /**
-         * @see Object#equals(Object)
-         */
-        @Override
-        public boolean equals(Object object) {
-            if (object == this)
-                return true;
-            if (object == null)
-                return false;
-            if (getClass() != object.getClass())
-                return false;
-            AdvertiserAdvertiseResponseParams other = (AdvertiserAdvertiseResponseParams) object;
-            if (this.handle != other.handle)
-                return false;
-            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.instanceId, other.instanceId))
-                return false;
-            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.err, other.err))
-                return false;
-            return true;
-        }
-    
-        /**
-         * @see Object#hashCode()
-         */
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = prime + getClass().hashCode();
-            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(handle);
-            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(instanceId);
-            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(err);
-            return result;
-        }
-    }
-
-    static class AdvertiserAdvertiseResponseParamsForwardToCallback extends org.chromium.mojo.bindings.SideEffectFreeCloseable
-            implements org.chromium.mojo.bindings.MessageReceiver {
-        private final Advertiser.AdvertiseResponse mCallback;
-
-        AdvertiserAdvertiseResponseParamsForwardToCallback(Advertiser.AdvertiseResponse callback) {
-            this.mCallback = callback;
-        }
-
-        @Override
-        public boolean accept(org.chromium.mojo.bindings.Message message) {
-            try {
-                org.chromium.mojo.bindings.ServiceMessage messageWithHeader =
-                        message.asServiceMessage();
-                org.chromium.mojo.bindings.MessageHeader header = messageWithHeader.getHeader();
-                if (!header.validateHeader(ADVERTISE_ORDINAL,
-                                           org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG)) {
-                    return false;
-                }
-                AdvertiserAdvertiseResponseParams response = AdvertiserAdvertiseResponseParams.deserialize(messageWithHeader.getPayload());
-                mCallback.call(response.handle, response.instanceId, response.err);
-                return true;
-            } catch (org.chromium.mojo.bindings.DeserializationException e) {
-                return false;
-            }
-        }
-    }
-
-    static class AdvertiserAdvertiseResponseParamsProxyToResponder implements Advertiser.AdvertiseResponse {
-
-        private final org.chromium.mojo.system.Core mCore;
-        private final org.chromium.mojo.bindings.MessageReceiver mMessageReceiver;
-        private final long mRequestId;
-
-        AdvertiserAdvertiseResponseParamsProxyToResponder(
-                org.chromium.mojo.system.Core core,
-                org.chromium.mojo.bindings.MessageReceiver messageReceiver,
-                long requestId) {
-            mCore = core;
-            mMessageReceiver = messageReceiver;
-            mRequestId = requestId;
-        }
-
-        @Override
-        public void call(Integer handle, String instanceId, Error err) {
-            AdvertiserAdvertiseResponseParams _response = new AdvertiserAdvertiseResponseParams();
-            _response.handle = handle;
-            _response.instanceId = instanceId;
-            _response.err = err;
-            org.chromium.mojo.bindings.ServiceMessage _message =
-                    _response.serializeWithHeader(
-                            mCore,
-                            new org.chromium.mojo.bindings.MessageHeader(
-                                    ADVERTISE_ORDINAL,
-                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG,
-                                    mRequestId));
-            mMessageReceiver.accept(_message);
-        }
-    }
-
-    static final class AdvertiserStopParams 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 h;
-    
-        private AdvertiserStopParams(int version) {
-            super(STRUCT_SIZE, version);
-        }
-    
-        public AdvertiserStopParams() {
-            this(0);
-        }
-    
-        public static AdvertiserStopParams deserialize(org.chromium.mojo.bindings.Message message) {
-            return decode(new org.chromium.mojo.bindings.Decoder(message));
-        }
-    
-        @SuppressWarnings("unchecked")
-        public static AdvertiserStopParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
-            if (decoder0 == null) {
-                return null;
-            }
-            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-            AdvertiserStopParams result = new AdvertiserStopParams(mainDataHeader.elementsOrVersion);
-            if (mainDataHeader.elementsOrVersion >= 0) {
-                result.h = 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(h, 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;
-            AdvertiserStopParams other = (AdvertiserStopParams) object;
-            if (this.h != other.h)
-                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(h);
-            return result;
-        }
-    }
-
-    static final class AdvertiserStopResponseParams 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 AdvertiserStopResponseParams(int version) {
-            super(STRUCT_SIZE, version);
-        }
-    
-        public AdvertiserStopResponseParams() {
-            this(0);
-        }
-    
-        public static AdvertiserStopResponseParams deserialize(org.chromium.mojo.bindings.Message message) {
-            return decode(new org.chromium.mojo.bindings.Decoder(message));
-        }
-    
-        @SuppressWarnings("unchecked")
-        public static AdvertiserStopResponseParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
-            if (decoder0 == null) {
-                return null;
-            }
-            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-            AdvertiserStopResponseParams result = new AdvertiserStopResponseParams(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;
-            AdvertiserStopResponseParams other = (AdvertiserStopResponseParams) 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 AdvertiserStopResponseParamsForwardToCallback extends org.chromium.mojo.bindings.SideEffectFreeCloseable
-            implements org.chromium.mojo.bindings.MessageReceiver {
-        private final Advertiser.StopResponse mCallback;
-
-        AdvertiserStopResponseParamsForwardToCallback(Advertiser.StopResponse 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_ORDINAL,
-                                           org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG)) {
-                    return false;
-                }
-                AdvertiserStopResponseParams response = AdvertiserStopResponseParams.deserialize(messageWithHeader.getPayload());
-                mCallback.call(response.err);
-                return true;
-            } catch (org.chromium.mojo.bindings.DeserializationException e) {
-                return false;
-            }
-        }
-    }
-
-    static class AdvertiserStopResponseParamsProxyToResponder implements Advertiser.StopResponse {
-
-        private final org.chromium.mojo.system.Core mCore;
-        private final org.chromium.mojo.bindings.MessageReceiver mMessageReceiver;
-        private final long mRequestId;
-
-        AdvertiserStopResponseParamsProxyToResponder(
-                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) {
-            AdvertiserStopResponseParams _response = new AdvertiserStopResponseParams();
-            _response.err = err;
-            org.chromium.mojo.bindings.ServiceMessage _message =
-                    _response.serializeWithHeader(
-                            mCore,
-                            new org.chromium.mojo.bindings.MessageHeader(
-                                    STOP_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
new file mode 100644
index 0000000..257529c
--- /dev/null
+++ b/java/generated-src/io/v/mojo/discovery/Discovery.java
@@ -0,0 +1,32 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file is autogenerated by:
+//     mojo/public/tools/bindings/mojom_bindings_generator.py
+// For:
+//     mojom/vanadium/discovery.mojom
+//
+
+package io.v.mojo.discovery;
+
+public interface Discovery extends org.chromium.mojo.bindings.Interface {
+
+    public interface Proxy extends Discovery, org.chromium.mojo.bindings.Interface.Proxy {
+    }
+
+    NamedManager<Discovery, Discovery.Proxy> MANAGER = Discovery_Internal.MANAGER;
+
+    void startAdvertising(Service service, String[] visibility, StartAdvertisingResponse callback);
+    interface StartAdvertisingResponse extends org.chromium.mojo.bindings.Callbacks.Callback2<String, 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> { }
+}
+
diff --git a/java/generated-src/io/v/mojo/discovery/Discovery_Internal.java b/java/generated-src/io/v/mojo/discovery/Discovery_Internal.java
new file mode 100644
index 0000000..1728856
--- /dev/null
+++ b/java/generated-src/io/v/mojo/discovery/Discovery_Internal.java
@@ -0,0 +1,1023 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file is autogenerated by:
+//     mojo/public/tools/bindings/mojom_bindings_generator.py
+// For:
+//     mojom/vanadium/discovery.mojom
+//
+
+package io.v.mojo.discovery;
+
+class Discovery_Internal {
+
+    public static final org.chromium.mojo.bindings.Interface.NamedManager<Discovery, Discovery.Proxy> MANAGER =
+            new org.chromium.mojo.bindings.Interface.NamedManager<Discovery, Discovery.Proxy>() {
+    
+        public String getName() {
+            return "v23::discovery::Discovery";
+        }
+    
+        public int getVersion() {
+          return 0;
+        }
+    
+        public Proxy buildProxy(org.chromium.mojo.system.Core core,
+                                org.chromium.mojo.bindings.MessageReceiverWithResponder messageReceiver) {
+            return new Proxy(core, messageReceiver);
+        }
+    
+        public Stub buildStub(org.chromium.mojo.system.Core core, Discovery impl) {
+            return new Stub(core, impl);
+        }
+    
+        public Discovery[] buildArray(int size) {
+          return new Discovery[size];
+        }
+    };
+
+    private static final int 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;
+
+    static final class Proxy extends org.chromium.mojo.bindings.Interface.AbstractProxy implements Discovery.Proxy {
+
+        Proxy(org.chromium.mojo.system.Core core,
+              org.chromium.mojo.bindings.MessageReceiverWithResponder messageReceiver) {
+            super(core, messageReceiver);
+        }
+
+        @Override
+        public void startAdvertising(Service service, String[] visibility, StartAdvertisingResponse callback) {
+            DiscoveryStartAdvertisingParams _message = new DiscoveryStartAdvertisingParams();
+            _message.service = service;
+            _message.visibility = visibility;
+            getProxyHandler().getMessageReceiver().acceptWithResponder(
+                    _message.serializeWithHeader(
+                            getProxyHandler().getCore(),
+                            new org.chromium.mojo.bindings.MessageHeader(
+                                    START_ADVERTISING_ORDINAL,
+                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG,
+                                    0)),
+                    new DiscoveryStartAdvertisingResponseParamsForwardToCallback(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();
+            _message.query = query;
+            _message.handler = handler;
+            getProxyHandler().getMessageReceiver().acceptWithResponder(
+                    _message.serializeWithHeader(
+                            getProxyHandler().getCore(),
+                            new org.chromium.mojo.bindings.MessageHeader(
+                                    START_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));
+        }
+
+    }
+
+    static final class Stub extends org.chromium.mojo.bindings.Interface.Stub<Discovery> {
+
+        Stub(org.chromium.mojo.system.Core core, Discovery impl) {
+            super(core, impl);
+        }
+
+        @Override
+        public boolean accept(org.chromium.mojo.bindings.Message message) {
+            try {
+                org.chromium.mojo.bindings.ServiceMessage messageWithHeader =
+                        message.asServiceMessage();
+                org.chromium.mojo.bindings.MessageHeader header = messageWithHeader.getHeader();
+                if (!header.validateHeader(org.chromium.mojo.bindings.MessageHeader.NO_FLAG)) {
+                    return false;
+                }
+                switch(header.getType()) {
+                    case org.chromium.mojo.bindings.InterfaceControlMessagesConstants.RUN_OR_CLOSE_PIPE_MESSAGE_ID:
+                        return org.chromium.mojo.bindings.InterfaceControlMessagesHelper.handleRunOrClosePipe(
+                                Discovery_Internal.MANAGER, messageWithHeader);
+                    default:
+                        return false;
+                }
+            } catch (org.chromium.mojo.bindings.DeserializationException e) {
+                System.err.println(e.toString());
+                return false;
+            }
+        }
+
+        @Override
+        public boolean acceptWithResponder(org.chromium.mojo.bindings.Message message, org.chromium.mojo.bindings.MessageReceiver receiver) {
+            try {
+                org.chromium.mojo.bindings.ServiceMessage messageWithHeader =
+                        message.asServiceMessage();
+                org.chromium.mojo.bindings.MessageHeader header = messageWithHeader.getHeader();
+                if (!header.validateHeader(org.chromium.mojo.bindings.MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG)) {
+                    return false;
+                }
+                switch(header.getType()) {
+                    case org.chromium.mojo.bindings.InterfaceControlMessagesConstants.RUN_MESSAGE_ID:
+                        return org.chromium.mojo.bindings.InterfaceControlMessagesHelper.handleRun(
+                                getCore(), Discovery_Internal.MANAGER, messageWithHeader, receiver);
+                    case START_ADVERTISING_ORDINAL: {
+                        DiscoveryStartAdvertisingParams data =
+                                DiscoveryStartAdvertisingParams.deserialize(messageWithHeader.getPayload());
+                        getImpl().startAdvertising(data.service, data.visibility, new DiscoveryStartAdvertisingResponseParamsProxyToResponder(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()));
+                        return true;
+                    }
+                    default:
+                        return false;
+                }
+            } catch (org.chromium.mojo.bindings.DeserializationException e) {
+                System.err.println(e.toString());
+                return false;
+            }
+        }
+    }
+
+    static final class DiscoveryStartAdvertisingParams 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 String[] visibility;
+    
+        private DiscoveryStartAdvertisingParams(int version) {
+            super(STRUCT_SIZE, version);
+        }
+    
+        public DiscoveryStartAdvertisingParams() {
+            this(0);
+        }
+    
+        public static DiscoveryStartAdvertisingParams 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) {
+            if (decoder0 == null) {
+                return null;
+            }
+            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
+            DiscoveryStartAdvertisingParams result = new DiscoveryStartAdvertisingParams(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) {
+                org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(16, true);
+                if (decoder1 == null) {
+                    result.visibility = null;
+                } else {
+                    org.chromium.mojo.bindings.DataHeader si1 = decoder1.readDataHeaderForPointerArray(org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
+                    result.visibility = new String[si1.elementsOrVersion];
+                    for (int i1 = 0; i1 < si1.elementsOrVersion; ++i1) {
+                        result.visibility[i1] = decoder1.readString(org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i1, false);
+                    }
+                }
+            }
+            return result;
+        }
+    
+        @SuppressWarnings("unchecked")
+        @Override
+        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
+            org.chromium.mojo.bindings.Encoder encoder0 = encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
+            encoder0.encode(service, 8, false);
+            if (visibility == null) {
+                encoder0.encodeNullPointer(16, true);
+            } else {
+                org.chromium.mojo.bindings.Encoder encoder1 = encoder0.encodePointerArray(visibility.length, 16, org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
+                for (int i0 = 0; i0 < visibility.length; ++i0) {
+                    encoder1.encode(visibility[i0], org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i0, false);
+                }
+            }
+        }
+    
+        /**
+         * @see Object#equals(Object)
+         */
+        @Override
+        public boolean equals(Object object) {
+            if (object == this)
+                return true;
+            if (object == null)
+                return false;
+            if (getClass() != object.getClass())
+                return false;
+            DiscoveryStartAdvertisingParams other = (DiscoveryStartAdvertisingParams) object;
+            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.service, other.service))
+                return false;
+            if (!java.util.Arrays.deepEquals(this.visibility, other.visibility))
+                return false;
+            return true;
+        }
+    
+        /**
+         * @see Object#hashCode()
+         */
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = prime + getClass().hashCode();
+            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(service);
+            result = prime * result + java.util.Arrays.deepHashCode(visibility);
+            return result;
+        }
+    }
+
+    static final class DiscoveryStartAdvertisingResponseParams extends org.chromium.mojo.bindings.Struct {
+    
+        private static final int STRUCT_SIZE = 24;
+        private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(24, 0)};
+        private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
+    
+        public String instanceId;
+        public Error err;
+    
+        private DiscoveryStartAdvertisingResponseParams(int version) {
+            super(STRUCT_SIZE, version);
+        }
+    
+        public DiscoveryStartAdvertisingResponseParams() {
+            this(0);
+        }
+    
+        public static DiscoveryStartAdvertisingResponseParams 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) {
+            if (decoder0 == null) {
+                return null;
+            }
+            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
+            DiscoveryStartAdvertisingResponseParams result = new DiscoveryStartAdvertisingResponseParams(mainDataHeader.elementsOrVersion);
+            if (mainDataHeader.elementsOrVersion >= 0) {
+                result.instanceId = decoder0.readString(8, false);
+            }
+            if (mainDataHeader.elementsOrVersion >= 0) {
+                org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(16, true);
+                result.err = Error.decode(decoder1);
+            }
+            return result;
+        }
+    
+        @SuppressWarnings("unchecked")
+        @Override
+        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
+            org.chromium.mojo.bindings.Encoder encoder0 = encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
+            encoder0.encode(instanceId, 8, false);
+            encoder0.encode(err, 16, true);
+        }
+    
+        /**
+         * @see Object#equals(Object)
+         */
+        @Override
+        public boolean equals(Object object) {
+            if (object == this)
+                return true;
+            if (object == null)
+                return false;
+            if (getClass() != object.getClass())
+                return false;
+            DiscoveryStartAdvertisingResponseParams other = (DiscoveryStartAdvertisingResponseParams) object;
+            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.instanceId, other.instanceId))
+                return false;
+            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.err, other.err))
+                return false;
+            return true;
+        }
+    
+        /**
+         * @see Object#hashCode()
+         */
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = prime + getClass().hashCode();
+            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(instanceId);
+            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(err);
+            return result;
+        }
+    }
+
+    static class DiscoveryStartAdvertisingResponseParamsForwardToCallback extends org.chromium.mojo.bindings.SideEffectFreeCloseable
+            implements org.chromium.mojo.bindings.MessageReceiver {
+        private final Discovery.StartAdvertisingResponse mCallback;
+
+        DiscoveryStartAdvertisingResponseParamsForwardToCallback(Discovery.StartAdvertisingResponse 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(START_ADVERTISING_ORDINAL,
+                                           org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG)) {
+                    return false;
+                }
+                DiscoveryStartAdvertisingResponseParams response = DiscoveryStartAdvertisingResponseParams.deserialize(messageWithHeader.getPayload());
+                mCallback.call(response.instanceId, response.err);
+                return true;
+            } catch (org.chromium.mojo.bindings.DeserializationException e) {
+                return false;
+            }
+        }
+    }
+
+    static class DiscoveryStartAdvertisingResponseParamsProxyToResponder implements Discovery.StartAdvertisingResponse {
+
+        private final org.chromium.mojo.system.Core mCore;
+        private final org.chromium.mojo.bindings.MessageReceiver mMessageReceiver;
+        private final long mRequestId;
+
+        DiscoveryStartAdvertisingResponseParamsProxyToResponder(
+                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 instanceId, Error err) {
+            DiscoveryStartAdvertisingResponseParams _response = new DiscoveryStartAdvertisingResponseParams();
+            _response.instanceId = instanceId;
+            _response.err = err;
+            org.chromium.mojo.bindings.ServiceMessage _message =
+                    _response.serializeWithHeader(
+                            mCore,
+                            new org.chromium.mojo.bindings.MessageHeader(
+                                    START_ADVERTISING_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 {
+    
+        private static final int STRUCT_SIZE = 24;
+        private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(24, 0)};
+        private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
+    
+        public String query;
+        public ScanHandler handler;
+    
+        private DiscoveryStartScanParams(int version) {
+            super(STRUCT_SIZE, version);
+        }
+    
+        public DiscoveryStartScanParams() {
+            this(0);
+        }
+    
+        public static DiscoveryStartScanParams 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) {
+            if (decoder0 == null) {
+                return null;
+            }
+            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
+            DiscoveryStartScanParams result = new DiscoveryStartScanParams(mainDataHeader.elementsOrVersion);
+            if (mainDataHeader.elementsOrVersion >= 0) {
+                result.query = decoder0.readString(8, false);
+            }
+            if (mainDataHeader.elementsOrVersion >= 0) {
+                result.handler = decoder0.readServiceInterface(16, false, ScanHandler.MANAGER);
+            }
+            return result;
+        }
+    
+        @SuppressWarnings("unchecked")
+        @Override
+        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
+            org.chromium.mojo.bindings.Encoder encoder0 = encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
+            encoder0.encode(query, 8, false);
+            encoder0.encode(handler, 16, false, ScanHandler.MANAGER);
+        }
+    
+        /**
+         * @see Object#equals(Object)
+         */
+        @Override
+        public boolean equals(Object object) {
+            if (object == this)
+                return true;
+            if (object == null)
+                return false;
+            if (getClass() != object.getClass())
+                return false;
+            DiscoveryStartScanParams other = (DiscoveryStartScanParams) object;
+            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.query, other.query))
+                return false;
+            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.handler, other.handler))
+                return false;
+            return true;
+        }
+    
+        /**
+         * @see Object#hashCode()
+         */
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = prime + getClass().hashCode();
+            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(query);
+            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(handler);
+            return result;
+        }
+    }
+
+    static final class DiscoveryStartScanResponseParams 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 Error err;
+    
+        private DiscoveryStartScanResponseParams(int version) {
+            super(STRUCT_SIZE, version);
+        }
+    
+        public DiscoveryStartScanResponseParams() {
+            this(0);
+        }
+    
+        public static DiscoveryStartScanResponseParams 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) {
+            if (decoder0 == null) {
+                return null;
+            }
+            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
+            DiscoveryStartScanResponseParams result = new DiscoveryStartScanResponseParams(mainDataHeader.elementsOrVersion);
+            if (mainDataHeader.elementsOrVersion >= 0) {
+                result.scanId = decoder0.readInt(8);
+            }
+            if (mainDataHeader.elementsOrVersion >= 0) {
+                org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(16, true);
+                result.err = Error.decode(decoder1);
+            }
+            return result;
+        }
+    
+        @SuppressWarnings("unchecked")
+        @Override
+        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
+            org.chromium.mojo.bindings.Encoder encoder0 = encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
+            encoder0.encode(scanId, 8);
+            encoder0.encode(err, 16, true);
+        }
+    
+        /**
+         * @see Object#equals(Object)
+         */
+        @Override
+        public boolean equals(Object object) {
+            if (object == this)
+                return true;
+            if (object == null)
+                return false;
+            if (getClass() != object.getClass())
+                return false;
+            DiscoveryStartScanResponseParams other = (DiscoveryStartScanResponseParams) object;
+            if (this.scanId != other.scanId)
+                return false;
+            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.err, other.err))
+                return false;
+            return true;
+        }
+    
+        /**
+         * @see Object#hashCode()
+         */
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = prime + getClass().hashCode();
+            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(scanId);
+            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(err);
+            return result;
+        }
+    }
+
+    static class DiscoveryStartScanResponseParamsForwardToCallback extends org.chromium.mojo.bindings.SideEffectFreeCloseable
+            implements org.chromium.mojo.bindings.MessageReceiver {
+        private final Discovery.StartScanResponse mCallback;
+
+        DiscoveryStartScanResponseParamsForwardToCallback(Discovery.StartScanResponse 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(START_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);
+                return true;
+            } catch (org.chromium.mojo.bindings.DeserializationException e) {
+                return false;
+            }
+        }
+    }
+
+    static class DiscoveryStartScanResponseParamsProxyToResponder implements Discovery.StartScanResponse {
+
+        private final org.chromium.mojo.system.Core mCore;
+        private final org.chromium.mojo.bindings.MessageReceiver mMessageReceiver;
+        private final long mRequestId;
+
+        DiscoveryStartScanResponseParamsProxyToResponder(
+                org.chromium.mojo.system.Core core,
+                org.chromium.mojo.bindings.MessageReceiver messageReceiver,
+                long requestId) {
+            mCore = core;
+            mMessageReceiver = messageReceiver;
+            mRequestId = requestId;
+        }
+
+        @Override
+        public void call(Integer scanId, Error err) {
+            DiscoveryStartScanResponseParams _response = new DiscoveryStartScanResponseParams();
+            _response.scanId = scanId;
+            _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,
+                                    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 642ea20..a401fa9 100644
--- a/java/generated-src/io/v/mojo/discovery/Error.java
+++ b/java/generated-src/io/v/mojo/discovery/Error.java
@@ -1,7 +1,3 @@
-// Copyright 2015 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
 // 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.
diff --git a/java/generated-src/io/v/mojo/discovery/ScanHandler.java b/java/generated-src/io/v/mojo/discovery/ScanHandler.java
index 08885bf..4042b8e 100644
--- a/java/generated-src/io/v/mojo/discovery/ScanHandler.java
+++ b/java/generated-src/io/v/mojo/discovery/ScanHandler.java
@@ -1,7 +1,3 @@
-// Copyright 2015 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
 // 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.
@@ -21,6 +17,6 @@
 
     NamedManager<ScanHandler, ScanHandler.Proxy> MANAGER = ScanHandler_Internal.MANAGER;
 
-    void update(Update update);
+    void update(ScanUpdate 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 477d0e7..d3c280d 100644
--- a/java/generated-src/io/v/mojo/discovery/ScanHandler_Internal.java
+++ b/java/generated-src/io/v/mojo/discovery/ScanHandler_Internal.java
@@ -1,7 +1,3 @@
-// Copyright 2015 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
 // 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.
@@ -51,7 +47,7 @@
         }
 
         @Override
-        public void update(Update update) {
+        public void update(ScanUpdate update) {
             ScanHandlerUpdateParams _message = new ScanHandlerUpdateParams();
             _message.update = update;
             getProxyHandler().getMessageReceiver().accept(
@@ -125,7 +121,7 @@
         private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(16, 0)};
         private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
     
-        public Update update;
+        public ScanUpdate update;
     
         private ScanHandlerUpdateParams(int version) {
             super(STRUCT_SIZE, version);
@@ -148,7 +144,7 @@
             ScanHandlerUpdateParams result = new ScanHandlerUpdateParams(mainDataHeader.elementsOrVersion);
             if (mainDataHeader.elementsOrVersion >= 0) {
                 org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(8, false);
-                result.update = Update.decode(decoder1);
+                result.update = ScanUpdate.decode(decoder1);
             }
             return result;
         }
diff --git a/java/generated-src/io/v/mojo/discovery/Update.java b/java/generated-src/io/v/mojo/discovery/ScanUpdate.java
similarity index 82%
rename from java/generated-src/io/v/mojo/discovery/Update.java
rename to java/generated-src/io/v/mojo/discovery/ScanUpdate.java
index 97a9bdc..52471d0 100644
--- a/java/generated-src/io/v/mojo/discovery/Update.java
+++ b/java/generated-src/io/v/mojo/discovery/ScanUpdate.java
@@ -1,7 +1,3 @@
-// Copyright 2015 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
 // 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.
@@ -14,7 +10,7 @@
 
 package io.v.mojo.discovery;
 
-public final class Update extends org.chromium.mojo.bindings.Struct {
+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)};
@@ -23,25 +19,25 @@
     public Service service;
     public int updateType;
 
-    private Update(int version) {
+    private ScanUpdate(int version) {
         super(STRUCT_SIZE, version);
     }
 
-    public Update() {
+    public ScanUpdate() {
         this(0);
     }
 
-    public static Update deserialize(org.chromium.mojo.bindings.Message message) {
+    public static ScanUpdate deserialize(org.chromium.mojo.bindings.Message message) {
         return decode(new org.chromium.mojo.bindings.Decoder(message));
     }
 
     @SuppressWarnings("unchecked")
-    public static Update decode(org.chromium.mojo.bindings.Decoder decoder0) {
+    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);
-        Update result = new Update(mainDataHeader.elementsOrVersion);
+        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);
@@ -71,7 +67,7 @@
             return false;
         if (getClass() != object.getClass())
             return false;
-        Update other = (Update) object;
+        ScanUpdate other = (ScanUpdate) object;
         if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.service, other.service))
             return false;
         if (this.updateType != other.updateType)
diff --git a/java/generated-src/io/v/mojo/discovery/Scanner.java b/java/generated-src/io/v/mojo/discovery/Scanner.java
deleted file mode 100644
index 514f956..0000000
--- a/java/generated-src/io/v/mojo/discovery/Scanner.java
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2015 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// 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 Scanner extends org.chromium.mojo.bindings.Interface {
-
-    public interface Proxy extends Scanner, org.chromium.mojo.bindings.Interface.Proxy {
-    }
-
-    NamedManager<Scanner, Scanner.Proxy> MANAGER = Scanner_Internal.MANAGER;
-
-    void scan(String query, ScanHandler scanHandler, ScanResponse callback);
-    interface ScanResponse extends org.chromium.mojo.bindings.Callbacks.Callback2<Integer, Error> { }
-
-    void stop(int h, StopResponse callback);
-    interface StopResponse extends org.chromium.mojo.bindings.Callbacks.Callback1<Error> { }
-}
-
diff --git a/java/generated-src/io/v/mojo/discovery/Scanner_Internal.java b/java/generated-src/io/v/mojo/discovery/Scanner_Internal.java
deleted file mode 100644
index f219dc8..0000000
--- a/java/generated-src/io/v/mojo/discovery/Scanner_Internal.java
+++ /dev/null
@@ -1,558 +0,0 @@
-// Copyright 2015 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// 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 Scanner_Internal {
-
-    public static final org.chromium.mojo.bindings.Interface.NamedManager<Scanner, Scanner.Proxy> MANAGER =
-            new org.chromium.mojo.bindings.Interface.NamedManager<Scanner, Scanner.Proxy>() {
-    
-        public String getName() {
-            return "v23::discovery::Scanner";
-        }
-    
-        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, Scanner impl) {
-            return new Stub(core, impl);
-        }
-    
-        public Scanner[] buildArray(int size) {
-          return new Scanner[size];
-        }
-    };
-
-    private static final int SCAN_ORDINAL = 0;
-    private static final int STOP_ORDINAL = 1;
-
-    static final class Proxy extends org.chromium.mojo.bindings.Interface.AbstractProxy implements Scanner.Proxy {
-
-        Proxy(org.chromium.mojo.system.Core core,
-              org.chromium.mojo.bindings.MessageReceiverWithResponder messageReceiver) {
-            super(core, messageReceiver);
-        }
-
-        @Override
-        public void scan(String query, ScanHandler scanHandler, ScanResponse callback) {
-            ScannerScanParams _message = new ScannerScanParams();
-            _message.query = query;
-            _message.scanHandler = scanHandler;
-            getProxyHandler().getMessageReceiver().acceptWithResponder(
-                    _message.serializeWithHeader(
-                            getProxyHandler().getCore(),
-                            new org.chromium.mojo.bindings.MessageHeader(
-                                    SCAN_ORDINAL,
-                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG,
-                                    0)),
-                    new ScannerScanResponseParamsForwardToCallback(callback));
-        }
-
-        @Override
-        public void stop(int h, StopResponse callback) {
-            ScannerStopParams _message = new ScannerStopParams();
-            _message.h = h;
-            getProxyHandler().getMessageReceiver().acceptWithResponder(
-                    _message.serializeWithHeader(
-                            getProxyHandler().getCore(),
-                            new org.chromium.mojo.bindings.MessageHeader(
-                                    STOP_ORDINAL,
-                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG,
-                                    0)),
-                    new ScannerStopResponseParamsForwardToCallback(callback));
-        }
-
-    }
-
-    static final class Stub extends org.chromium.mojo.bindings.Interface.Stub<Scanner> {
-
-        Stub(org.chromium.mojo.system.Core core, Scanner 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(
-                                Scanner_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(), Scanner_Internal.MANAGER, messageWithHeader, receiver);
-                    case SCAN_ORDINAL: {
-                        ScannerScanParams data =
-                                ScannerScanParams.deserialize(messageWithHeader.getPayload());
-                        getImpl().scan(data.query, data.scanHandler, new ScannerScanResponseParamsProxyToResponder(getCore(), receiver, header.getRequestId()));
-                        return true;
-                    }
-                    case STOP_ORDINAL: {
-                        ScannerStopParams data =
-                                ScannerStopParams.deserialize(messageWithHeader.getPayload());
-                        getImpl().stop(data.h, new ScannerStopResponseParamsProxyToResponder(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 ScannerScanParams extends org.chromium.mojo.bindings.Struct {
-    
-        private static final int STRUCT_SIZE = 24;
-        private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(24, 0)};
-        private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
-    
-        public String query;
-        public ScanHandler scanHandler;
-    
-        private ScannerScanParams(int version) {
-            super(STRUCT_SIZE, version);
-        }
-    
-        public ScannerScanParams() {
-            this(0);
-        }
-    
-        public static ScannerScanParams deserialize(org.chromium.mojo.bindings.Message message) {
-            return decode(new org.chromium.mojo.bindings.Decoder(message));
-        }
-    
-        @SuppressWarnings("unchecked")
-        public static ScannerScanParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
-            if (decoder0 == null) {
-                return null;
-            }
-            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-            ScannerScanParams result = new ScannerScanParams(mainDataHeader.elementsOrVersion);
-            if (mainDataHeader.elementsOrVersion >= 0) {
-                result.query = decoder0.readString(8, false);
-            }
-            if (mainDataHeader.elementsOrVersion >= 0) {
-                result.scanHandler = decoder0.readServiceInterface(16, false, ScanHandler.MANAGER);
-            }
-            return result;
-        }
-    
-        @SuppressWarnings("unchecked")
-        @Override
-        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
-            org.chromium.mojo.bindings.Encoder encoder0 = encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
-            encoder0.encode(query, 8, false);
-            encoder0.encode(scanHandler, 16, false, ScanHandler.MANAGER);
-        }
-    
-        /**
-         * @see Object#equals(Object)
-         */
-        @Override
-        public boolean equals(Object object) {
-            if (object == this)
-                return true;
-            if (object == null)
-                return false;
-            if (getClass() != object.getClass())
-                return false;
-            ScannerScanParams other = (ScannerScanParams) object;
-            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.query, other.query))
-                return false;
-            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.scanHandler, other.scanHandler))
-                return false;
-            return true;
-        }
-    
-        /**
-         * @see Object#hashCode()
-         */
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = prime + getClass().hashCode();
-            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(query);
-            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(scanHandler);
-            return result;
-        }
-    }
-
-    static final class ScannerScanResponseParams 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 handle;
-        public Error err;
-    
-        private ScannerScanResponseParams(int version) {
-            super(STRUCT_SIZE, version);
-        }
-    
-        public ScannerScanResponseParams() {
-            this(0);
-        }
-    
-        public static ScannerScanResponseParams deserialize(org.chromium.mojo.bindings.Message message) {
-            return decode(new org.chromium.mojo.bindings.Decoder(message));
-        }
-    
-        @SuppressWarnings("unchecked")
-        public static ScannerScanResponseParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
-            if (decoder0 == null) {
-                return null;
-            }
-            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-            ScannerScanResponseParams result = new ScannerScanResponseParams(mainDataHeader.elementsOrVersion);
-            if (mainDataHeader.elementsOrVersion >= 0) {
-                result.handle = decoder0.readInt(8);
-            }
-            if (mainDataHeader.elementsOrVersion >= 0) {
-                org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(16, true);
-                result.err = Error.decode(decoder1);
-            }
-            return result;
-        }
-    
-        @SuppressWarnings("unchecked")
-        @Override
-        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
-            org.chromium.mojo.bindings.Encoder encoder0 = encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
-            encoder0.encode(handle, 8);
-            encoder0.encode(err, 16, true);
-        }
-    
-        /**
-         * @see Object#equals(Object)
-         */
-        @Override
-        public boolean equals(Object object) {
-            if (object == this)
-                return true;
-            if (object == null)
-                return false;
-            if (getClass() != object.getClass())
-                return false;
-            ScannerScanResponseParams other = (ScannerScanResponseParams) object;
-            if (this.handle != other.handle)
-                return false;
-            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.err, other.err))
-                return false;
-            return true;
-        }
-    
-        /**
-         * @see Object#hashCode()
-         */
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = prime + getClass().hashCode();
-            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(handle);
-            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(err);
-            return result;
-        }
-    }
-
-    static class ScannerScanResponseParamsForwardToCallback extends org.chromium.mojo.bindings.SideEffectFreeCloseable
-            implements org.chromium.mojo.bindings.MessageReceiver {
-        private final Scanner.ScanResponse mCallback;
-
-        ScannerScanResponseParamsForwardToCallback(Scanner.ScanResponse callback) {
-            this.mCallback = callback;
-        }
-
-        @Override
-        public boolean accept(org.chromium.mojo.bindings.Message message) {
-            try {
-                org.chromium.mojo.bindings.ServiceMessage messageWithHeader =
-                        message.asServiceMessage();
-                org.chromium.mojo.bindings.MessageHeader header = messageWithHeader.getHeader();
-                if (!header.validateHeader(SCAN_ORDINAL,
-                                           org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG)) {
-                    return false;
-                }
-                ScannerScanResponseParams response = ScannerScanResponseParams.deserialize(messageWithHeader.getPayload());
-                mCallback.call(response.handle, response.err);
-                return true;
-            } catch (org.chromium.mojo.bindings.DeserializationException e) {
-                return false;
-            }
-        }
-    }
-
-    static class ScannerScanResponseParamsProxyToResponder implements Scanner.ScanResponse {
-
-        private final org.chromium.mojo.system.Core mCore;
-        private final org.chromium.mojo.bindings.MessageReceiver mMessageReceiver;
-        private final long mRequestId;
-
-        ScannerScanResponseParamsProxyToResponder(
-                org.chromium.mojo.system.Core core,
-                org.chromium.mojo.bindings.MessageReceiver messageReceiver,
-                long requestId) {
-            mCore = core;
-            mMessageReceiver = messageReceiver;
-            mRequestId = requestId;
-        }
-
-        @Override
-        public void call(Integer handle, Error err) {
-            ScannerScanResponseParams _response = new ScannerScanResponseParams();
-            _response.handle = handle;
-            _response.err = err;
-            org.chromium.mojo.bindings.ServiceMessage _message =
-                    _response.serializeWithHeader(
-                            mCore,
-                            new org.chromium.mojo.bindings.MessageHeader(
-                                    SCAN_ORDINAL,
-                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG,
-                                    mRequestId));
-            mMessageReceiver.accept(_message);
-        }
-    }
-
-    static final class ScannerStopParams 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 h;
-    
-        private ScannerStopParams(int version) {
-            super(STRUCT_SIZE, version);
-        }
-    
-        public ScannerStopParams() {
-            this(0);
-        }
-    
-        public static ScannerStopParams deserialize(org.chromium.mojo.bindings.Message message) {
-            return decode(new org.chromium.mojo.bindings.Decoder(message));
-        }
-    
-        @SuppressWarnings("unchecked")
-        public static ScannerStopParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
-            if (decoder0 == null) {
-                return null;
-            }
-            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-            ScannerStopParams result = new ScannerStopParams(mainDataHeader.elementsOrVersion);
-            if (mainDataHeader.elementsOrVersion >= 0) {
-                result.h = 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(h, 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;
-            ScannerStopParams other = (ScannerStopParams) object;
-            if (this.h != other.h)
-                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(h);
-            return result;
-        }
-    }
-
-    static final class ScannerStopResponseParams 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 ScannerStopResponseParams(int version) {
-            super(STRUCT_SIZE, version);
-        }
-    
-        public ScannerStopResponseParams() {
-            this(0);
-        }
-    
-        public static ScannerStopResponseParams deserialize(org.chromium.mojo.bindings.Message message) {
-            return decode(new org.chromium.mojo.bindings.Decoder(message));
-        }
-    
-        @SuppressWarnings("unchecked")
-        public static ScannerStopResponseParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
-            if (decoder0 == null) {
-                return null;
-            }
-            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
-            ScannerStopResponseParams result = new ScannerStopResponseParams(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;
-            ScannerStopResponseParams other = (ScannerStopResponseParams) 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 ScannerStopResponseParamsForwardToCallback extends org.chromium.mojo.bindings.SideEffectFreeCloseable
-            implements org.chromium.mojo.bindings.MessageReceiver {
-        private final Scanner.StopResponse mCallback;
-
-        ScannerStopResponseParamsForwardToCallback(Scanner.StopResponse 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_ORDINAL,
-                                           org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG)) {
-                    return false;
-                }
-                ScannerStopResponseParams response = ScannerStopResponseParams.deserialize(messageWithHeader.getPayload());
-                mCallback.call(response.err);
-                return true;
-            } catch (org.chromium.mojo.bindings.DeserializationException e) {
-                return false;
-            }
-        }
-    }
-
-    static class ScannerStopResponseParamsProxyToResponder implements Scanner.StopResponse {
-
-        private final org.chromium.mojo.system.Core mCore;
-        private final org.chromium.mojo.bindings.MessageReceiver mMessageReceiver;
-        private final long mRequestId;
-
-        ScannerStopResponseParamsProxyToResponder(
-                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) {
-            ScannerStopResponseParams _response = new ScannerStopResponseParams();
-            _response.err = err;
-            org.chromium.mojo.bindings.ServiceMessage _message =
-                    _response.serializeWithHeader(
-                            mCore,
-                            new org.chromium.mojo.bindings.MessageHeader(
-                                    STOP_ORDINAL,
-                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG,
-                                    mRequestId));
-            mMessageReceiver.accept(_message);
-        }
-    }
-
-}
-
diff --git a/java/generated-src/io/v/mojo/discovery/Service.java b/java/generated-src/io/v/mojo/discovery/Service.java
index cfae988..02b1510 100644
--- a/java/generated-src/io/v/mojo/discovery/Service.java
+++ b/java/generated-src/io/v/mojo/discovery/Service.java
@@ -1,7 +1,3 @@
-// Copyright 2015 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
 // 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.
@@ -16,8 +12,8 @@
 
 public final class Service extends org.chromium.mojo.bindings.Struct {
 
-    private static final int STRUCT_SIZE = 48;
-    private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(48, 0)};
+    private static final 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 org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
 
     public String instanceId;
@@ -25,6 +21,7 @@
     public String interfaceName;
     public java.util.Map<String, String> attrs;
     public String[] addrs;
+    public java.util.Map<String, byte[]> attachments;
 
     private Service(int version) {
         super(STRUCT_SIZE, version);
@@ -98,6 +95,40 @@
                 }
             }
         }
+        if (mainDataHeader.elementsOrVersion >= 0) {
+            org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(48, true);
+            if (decoder1 == null) {
+                result.attachments = null;
+            } else {
+                decoder1.readDataHeaderForMap();
+                String[] keys0;
+                byte[][] values0;
+                {
+                    org.chromium.mojo.bindings.Decoder decoder2 = decoder1.readPointer(org.chromium.mojo.bindings.DataHeader.HEADER_SIZE, false);
+                    {
+                        org.chromium.mojo.bindings.DataHeader si2 = decoder2.readDataHeaderForPointerArray(org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
+                        keys0 = new String[si2.elementsOrVersion];
+                        for (int i2 = 0; i2 < si2.elementsOrVersion; ++i2) {
+                            keys0[i2] = decoder2.readString(org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i2, false);
+                        }
+                    }
+                }
+                {
+                    org.chromium.mojo.bindings.Decoder decoder2 = decoder1.readPointer(org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE, false);
+                    {
+                        org.chromium.mojo.bindings.DataHeader si2 = decoder2.readDataHeaderForPointerArray(keys0.length);
+                        values0 = new byte[si2.elementsOrVersion][];
+                        for (int i2 = 0; i2 < si2.elementsOrVersion; ++i2) {
+                            values0[i2] = decoder2.readBytes(org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i2, org.chromium.mojo.bindings.BindingsHelper.NOTHING_NULLABLE, org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
+                        }
+                    }
+                }
+                result.attachments = new java.util.HashMap<String, byte[]>();
+                for (int index0 = 0; index0 < keys0.length; ++index0) {
+                    result.attachments.put(keys0[index0],  values0[index0]);
+                }
+            }
+        }
         return result;
     }
 
@@ -142,6 +173,32 @@
                 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);
+        } else {
+            org.chromium.mojo.bindings.Encoder encoder1 = encoder0.encoderForMap(48);
+            int size0 = attachments.size();
+            String[] keys0 = new String[size0];
+            byte[][] values0 = new byte[size0][];
+            int index0 = 0;
+            for (java.util.Map.Entry<String, byte[]> entry0 : attachments.entrySet()) {
+                keys0[index0] = entry0.getKey();
+                values0[index0] = entry0.getValue();
+                ++index0;
+            }
+            {
+                org.chromium.mojo.bindings.Encoder encoder2 = encoder1.encodePointerArray(keys0.length, org.chromium.mojo.bindings.DataHeader.HEADER_SIZE, org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
+                for (int i1 = 0; i1 < keys0.length; ++i1) {
+                    encoder2.encode(keys0[i1], org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i1, false);
+                }
+            }
+            {
+                org.chromium.mojo.bindings.Encoder encoder2 = encoder1.encodePointerArray(values0.length, org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE, org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
+                for (int i1 = 0; i1 < values0.length; ++i1) {
+                    encoder2.encode(values0[i1], org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i1, org.chromium.mojo.bindings.BindingsHelper.NOTHING_NULLABLE, org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
+                }
+            }
+        }
     }
 
     /**
@@ -166,6 +223,8 @@
             return false;
         if (!java.util.Arrays.deepEquals(this.addrs, other.addrs))
             return false;
+        if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.attachments, other.attachments))
+            return false;
         return true;
     }
 
@@ -181,6 +240,7 @@
         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 + org.chromium.mojo.bindings.BindingsHelper.hashCode(attachments);
         return result;
     }
 }
diff --git a/java/generated-src/io/v/mojo/discovery/UpdateType.java b/java/generated-src/io/v/mojo/discovery/UpdateType.java
index 279da0b..7533314 100644
--- a/java/generated-src/io/v/mojo/discovery/UpdateType.java
+++ b/java/generated-src/io/v/mojo/discovery/UpdateType.java
@@ -1,7 +1,3 @@
-// Copyright 2015 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
 // 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.
diff --git a/java/src/main/java/io/v/mojo/discovery/AdvertiserImpl.java b/java/src/main/java/io/v/mojo/discovery/AdvertiserImpl.java
deleted file mode 100644
index 7f5ff24..0000000
--- a/java/src/main/java/io/v/mojo/discovery/AdvertiserImpl.java
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright 2015 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package io.v.mojo.discovery;
-
-import android.app.admin.SystemUpdatePolicy;
-import android.util.Log;
-
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-
-import io.v.v23.discovery.Attachments;
-import org.chromium.mojo.system.MojoException;
-
-import java.lang.Override;
-import java.lang.String;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import io.v.v23.context.VContext;
-import io.v.v23.discovery.Attributes;
-import io.v.v23.discovery.VDiscovery;
-import io.v.v23.security.BlessingPattern;
-
-class AdvertiserImpl implements Advertiser {
-
-    private VDiscovery discovery;
-    private VContext rootCtx;
-
-    private final AtomicInteger nextAdvertiser = new AtomicInteger(0);
-
-    private final Map<Integer, VContext> contextMap = new HashMap<>();
-
-    public AdvertiserImpl(VDiscovery discovery, VContext rootCtx) {
-        this.discovery = discovery;
-        this.rootCtx = rootCtx;
-    }
-    @Override
-    public void advertise(Service service, String[] visibility, final AdvertiseResponse callback) {
-        synchronized (this) {
-            final Integer nextValue = nextAdvertiser.getAndAdd(1);
-            VContext ctx = rootCtx.withCancel();
-            contextMap.put(nextValue, ctx);
-            Attributes attrs = null;
-            final io.v.v23.discovery.Service vService = new io.v.v23.discovery.Service(
-                    service.instanceId, service.instanceName, service.interfaceName,
-                    new Attributes(service.attrs), Arrays.asList(service.addrs), new Attachments());
-            if (service.attrs == null) {
-                vService.setAttrs(new Attributes(new HashMap<String, String>()));
-            }
-            List<BlessingPattern> patterns;
-            if (visibility != null) {
-                patterns = new ArrayList<>(visibility.length);
-                for (String pattern : visibility) {
-                    patterns.add(new BlessingPattern(pattern));
-                }
-            } else {
-                patterns = new ArrayList<>(0);
-            }
-            ListenableFuture<ListenableFuture<Void>> done = discovery.advertise(ctx, vService, patterns);
-            Futures.addCallback(done, new FutureCallback<ListenableFuture<Void>>() {
-                @Override
-                public void onSuccess(ListenableFuture<Void> result) {
-                    callback.call(nextValue, vService.getInstanceId(), null);
-                }
-
-                @Override
-                public void onFailure(Throwable t) {
-                    System.out.println("Failed with " + t.toString());
-                    Error e = new Error();
-                    e.msg = t.toString();
-                    e.id = "unknown";
-                    callback.call(0, "", e);
-                }
-            });
-        }
-    }
-
-    @Override
-    public void stop(int h, StopResponse response) {
-        synchronized (this) {
-            VContext ctx = contextMap.get(h);
-            if (ctx != null) {
-                contextMap.remove(h);
-                ctx.cancel();
-            }
-            response.call(null);
-        }
-    }
-
-    @Override
-    public void close() {}
-
-    @Override
-    public void onConnectionError(MojoException e) {}
-
-}
diff --git a/java/src/main/java/io/v/mojo/discovery/DiscoveryImpl.java b/java/src/main/java/io/v/mojo/discovery/DiscoveryImpl.java
new file mode 100644
index 0000000..c0b8a45
--- /dev/null
+++ b/java/src/main/java/io/v/mojo/discovery/DiscoveryImpl.java
@@ -0,0 +1,160 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package io.v.mojo.discovery;
+
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+
+import io.v.v23.InputChannelCallback;
+import org.chromium.mojo.system.MojoException;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import io.v.v23.InputChannels;
+import io.v.v23.context.VContext;
+import io.v.v23.discovery.Attachments;
+import io.v.v23.discovery.Attributes;
+import io.v.v23.discovery.VDiscovery;
+import io.v.v23.rpc.Callback;
+import io.v.v23.security.BlessingPattern;
+import io.v.v23.verror.VException;
+
+class DiscoveryImpl implements Discovery {
+    private final VDiscovery discovery;
+    private final VContext rootCtx;
+
+    private final Map<Integer, VContext> contextMap  = new HashMap<>();
+    private final Map<String, VContext> advertiserContextMap = new HashMap<>();
+
+    private final AtomicInteger nextScanner = new AtomicInteger(0);
+
+    public DiscoveryImpl(VDiscovery discovery, VContext rootCtx) {
+        this.discovery = discovery;
+        this.rootCtx = rootCtx;
+    }
+    @Override
+    public void startScan(String query, final ScanHandler scanHandler, StartScanResponse callback) {
+        synchronized (this) {
+            System.out.println("Got a scan call");
+            int handle = nextScanner.getAndAdd(1);
+            VContext ctx = rootCtx.withCancel();
+            contextMap.put(handle, ctx);
+            ListenableFuture<Void> done = InputChannels.withCallback(discovery.scan(ctx, query),
+                    new InputChannelCallback<io.v.v23.discovery.Update>() {
+                        @Override
+                        public ListenableFuture<Void> onNext(io.v.v23.discovery.Update update) {
+                            if (update instanceof io.v.v23.discovery.Update.Found) {
+                                io.v.v23.discovery.Update.Found found = (io.v.v23.discovery.Update.Found) update;
+                                Service mService = toMojoService(found.getElem().getService());
+                                ScanUpdate mUpdate = new ScanUpdate();
+                                mUpdate.service = mService;
+                                mUpdate.updateType = UpdateType.FOUND;
+                                scanHandler.update(mUpdate);
+                            } else {
+                                io.v.v23.discovery.Update.Lost lost = (io.v.v23.discovery.Update.Lost) update;
+                                Service mService = toMojoService(lost.getElem().getService());
+                                ScanUpdate mUpdate = new ScanUpdate();
+                                mUpdate.service = mService;
+                                mUpdate.updateType = UpdateType.LOST;
+                                scanHandler.update(mUpdate);
+                            }
+
+                            return Futures.immediateFuture(null);
+                        }
+
+                    });
+            System.out.println("Returning a scan call");
+            callback.call(handle, null);
+        }
+    }
+
+    @Override
+    public void stopScan(int h, StopScanResponse response) {
+        synchronized (this) {
+            VContext ctx = contextMap.get(h);
+            if (ctx != null) {
+                contextMap.remove(h);
+                ctx.cancel();
+            }
+            response.call(null);
+        }
+    }
+
+    private static Service toMojoService(io.v.v23.discovery.Service vService) {
+      Service mService = new Service();
+      mService.instanceId = vService.getInstanceId();
+      mService.instanceName = vService.getInstanceName();
+      mService.interfaceName = vService.getInterfaceName();
+      mService.addrs = new String[vService.getAddrs().size()];
+      mService.addrs = vService.getAddrs().toArray(mService.addrs);
+      mService.attrs = vService.getAttrs();
+      return mService;
+    }
+
+    @Override
+    public void startAdvertising(Service service, String[] visibility, final StartAdvertisingResponse callback) {
+        synchronized (this) {
+            final VContext ctx = rootCtx.withCancel();
+            Attributes attrs = null;
+            final io.v.v23.discovery.Service vService = new io.v.v23.discovery.Service(
+                    service.instanceId, service.instanceName, service.interfaceName,
+                    new Attributes(service.attrs), Arrays.asList(service.addrs), new Attachments());
+            if (service.attrs == null) {
+                vService.setAttrs(new Attributes(new HashMap<String, String>()));
+            }
+            List<BlessingPattern> patterns;
+            if (visibility != null) {
+                patterns = new ArrayList<>(visibility.length);
+                for (String pattern : visibility) {
+                    patterns.add(new BlessingPattern(pattern));
+                }
+            } else {
+                patterns = new ArrayList<>(0);
+            }
+            ListenableFuture<ListenableFuture<Void>> done = discovery.advertise(ctx, vService, patterns);
+            Futures.addCallback(done, new FutureCallback<ListenableFuture<Void>>() {
+                @Override
+                public void onSuccess(ListenableFuture<Void> result) {
+                    String instanceId = vService.getInstanceId();
+                    callback.call(instanceId, null);
+                    advertiserContextMap.put(instanceId, ctx);
+                }
+
+                @Override
+                public void onFailure(Throwable t) {
+                    System.out.println("Failed with " + t.toString());
+                    Error e = new Error();
+                    e.msg = t.toString();
+                    e.id = "unknown";
+                    callback.call("", e);
+                }
+            });
+        }
+    }
+
+    @Override
+    public void stopAdvertising(String instanceId, StopAdvertisingResponse response) {
+        synchronized (this) {
+            VContext ctx = advertiserContextMap.get(instanceId);
+            if (ctx != null) {
+                advertiserContextMap.remove(instanceId);
+                ctx.cancel();
+            }
+            response.call(null);
+        }
+    }
+
+    @Override
+    public void close() {}
+
+    @Override
+    public void onConnectionError(MojoException e) {}
+}
diff --git a/java/src/main/java/io/v/mojo/discovery/ScannerImpl.java b/java/src/main/java/io/v/mojo/discovery/ScannerImpl.java
deleted file mode 100644
index fb2431e..0000000
--- a/java/src/main/java/io/v/mojo/discovery/ScannerImpl.java
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2015 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package io.v.mojo.discovery;
-
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-
-import io.v.v23.InputChannelCallback;
-import org.chromium.mojo.system.MojoException;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import io.v.v23.InputChannels;
-import io.v.v23.context.VContext;
-import io.v.v23.discovery.VDiscovery;
-import io.v.v23.rpc.Callback;
-import io.v.v23.verror.VException;
-
-class ScannerImpl implements Scanner{
-    private final VDiscovery discovery;
-    private final VContext rootCtx;
-
-
-    private final Map<Integer, VContext> contextMap  = new HashMap<>();
-
-    private final AtomicInteger nextScanner = new AtomicInteger(0);
-
-    public ScannerImpl(VDiscovery discovery, VContext rootCtx) {
-        this.discovery = discovery;
-        this.rootCtx = rootCtx;
-    }
-    @Override
-    public void scan(String query, final ScanHandler scanHandler, ScanResponse callback) {
-        synchronized (this) {
-            System.out.println("Got a scan call");
-            int handle = nextScanner.getAndAdd(1);
-            VContext ctx = rootCtx.withCancel();
-            contextMap.put(handle, ctx);
-            ListenableFuture<Void> done = InputChannels.withCallback(discovery.scan(ctx, query),
-                    new InputChannelCallback<io.v.v23.discovery.Update>() {
-                        @Override
-                        public ListenableFuture<Void> onNext(io.v.v23.discovery.Update update) {
-                            if (update instanceof io.v.v23.discovery.Update.Found) {
-                                io.v.v23.discovery.Update.Found found = (io.v.v23.discovery.Update.Found) update;
-                                Service mService = toMojoService(found.getElem().getService());
-                                Update mUpdate = new Update();
-                                mUpdate.service = mService;
-                                mUpdate.updateType = UpdateType.FOUND;
-                                scanHandler.update(mUpdate);
-                            } else {
-                                io.v.v23.discovery.Update.Lost lost = (io.v.v23.discovery.Update.Lost) update;
-                                Service mService = toMojoService(lost.getElem().getService());
-                                Update mUpdate = new Update();
-                                mUpdate.service = mService;
-                                mUpdate.updateType = UpdateType.LOST;
-                                scanHandler.update(mUpdate);
-                            }
-
-                            return Futures.immediateFuture(null);
-                        }
-
-                    });
-            System.out.println("Returning a scan call");
-            callback.call(handle, null);
-        }
-    }
-
-    @Override
-    public void stop(int h, StopResponse response) {
-        synchronized (this) {
-            VContext ctx = contextMap.get(h);
-            if (ctx != null) {
-                contextMap.remove(h);
-                ctx.cancel();
-            }
-            response.call(null);
-        }
-    }
-
-    @Override
-    public void close() {}
-
-    @Override
-    public void onConnectionError(MojoException e) {}
-
-    private static Service toMojoService(io.v.v23.discovery.Service vService) {
-      Service mService = new Service();
-      mService.instanceId = vService.getInstanceId();
-      mService.instanceName = vService.getInstanceName();
-      mService.interfaceName = vService.getInterfaceName();
-      mService.addrs = new String[vService.getAddrs().size()];
-      mService.addrs = vService.getAddrs().toArray(mService.addrs);
-      mService.attrs = vService.getAttrs();
-      return mService;
-    }
-}
diff --git a/java/src/main/java/io/v/mojo/discovery/VDiscoveryApp.java b/java/src/main/java/io/v/mojo/discovery/VDiscoveryApp.java
index 10a5219..4ca5eaf 100644
--- a/java/src/main/java/io/v/mojo/discovery/VDiscoveryApp.java
+++ b/java/src/main/java/io/v/mojo/discovery/VDiscoveryApp.java
@@ -34,30 +34,16 @@
 
     @Override
     public boolean configureIncomingConnection(ApplicationConnection applicationConnection) {
-        applicationConnection.addService(new ServiceFactoryBinder<Advertiser>() {
+        applicationConnection.addService(new ServiceFactoryBinder<Discovery>() {
             @Override
-            public void bind(InterfaceRequest<Advertiser> request) {
-                Advertiser.MANAGER.bind(new AdvertiserImpl(V.getDiscovery(rootCtx), rootCtx),
+            public void bind(InterfaceRequest<Discovery> request) {
+                Discovery.MANAGER.bind(new DiscoveryImpl(V.getDiscovery(rootCtx), rootCtx),
                         request);
             }
 
             @Override
             public String getInterfaceName() {
-                return Advertiser.MANAGER.getName();
-            }
-        });
-
-        applicationConnection.addService(new ServiceFactoryBinder<Scanner>() {
-            @Override
-            public void bind(InterfaceRequest<Scanner> request) {
-                Scanner.MANAGER.bind(new ScannerImpl(V.getDiscovery(rootCtx), rootCtx),
-                        request);
-
-            }
-
-            @Override
-            public String getInterfaceName() {
-                return Scanner.MANAGER.getName();
+                return Discovery.MANAGER.getName();
             }
         });
         return true;
diff --git a/lib/client_impl.dart b/lib/client_impl.dart
index 476cd19..8c5a0ff 100644
--- a/lib/client_impl.dart
+++ b/lib/client_impl.dart
@@ -6,49 +6,47 @@
 typedef Future _StopFunction();
 
 class _Client implements Client {
-  final AdvertiserProxy _advertiserProxy = new AdvertiserProxy.unbound();
-  final ScannerProxy _scannerProxy = new ScannerProxy.unbound();
+  final DiscoveryProxy _discoveryProxy = new DiscoveryProxy.unbound();
 
   _Client(ConnectToServiceFunction cts, String url) {
-    cts(url, _advertiserProxy);
-    cts(url, _scannerProxy);
+    cts(url, _discoveryProxy);
   }
 
   Future<Scanner> scan(String query) async {
-    StreamController<Update> onUpdate = new StreamController<Update>();
+    StreamController<ScanUpdate> onUpdate = new StreamController<ScanUpdate>();
     ScanHandlerStub handlerStub = new ScanHandlerStub.unbound();
     handlerStub.impl = new _ScanHandler(onUpdate);
 
-    ScannerScanResponseParams scanResponse =
-        await _scannerProxy.ptr.scan(query, handlerStub);
+    DiscoveryStartScanResponseParams scanResponse =
+        await _discoveryProxy.ptr.startScan(query, handlerStub);
     if (scanResponse.err != null) {
       throw scanResponse.err;
     }
 
     Future stop() {
-      return _scannerProxy.ptr.stop(scanResponse.handle);
+      return _discoveryProxy.ptr.stopScan(scanResponse.scanId);
     }
     return new _Scanner(stop, onUpdate.stream);
   }
 
   Future<Advertiser> advertise(Service service,
       {List<String> visibility: null}) async {
-    AdvertiserAdvertiseResponseParams advertiseResponse =
-        await _advertiserProxy.ptr.advertise(service, visibility);
+    DiscoveryStartAdvertisingResponseParams advertiseResponse =
+        await _discoveryProxy.ptr.startAdvertising(service, visibility);
 
     if (advertiseResponse.err != null) {
       throw advertiseResponse.err;
     }
 
     Future stop() {
-      return _advertiserProxy.ptr.stop(advertiseResponse.handle);
+      return _discoveryProxy.ptr.stopAdvertising(advertiseResponse.instanceId);
     }
     return new _Advertiser(stop);
   }
 }
 
 class _Scanner implements Scanner {
-  final Stream<Update> onUpdate;
+  final Stream<ScanUpdate> onUpdate;
 
   final _StopFunction _stop;
   _Scanner(this._stop, this.onUpdate) {}
@@ -68,11 +66,11 @@
 }
 
 class _ScanHandler extends ScanHandler {
-  StreamController<Update> _onUpdate;
+  StreamController<ScanUpdate> _onUpdate;
 
   _ScanHandler(this._onUpdate);
 
-  update(Update update) {
+  update(ScanUpdate update) {
     _onUpdate.add(update);
   }
 }
diff --git a/lib/discovery.dart b/lib/discovery.dart
index 0e5a38c..fefb827 100644
--- a/lib/discovery.dart
+++ b/lib/discovery.dart
@@ -9,7 +9,7 @@
 import 'gen/dart-gen/mojom/lib/discovery/discovery.mojom.dart';
 
 export 'gen/dart-gen/mojom/lib/discovery/discovery.mojom.dart'
-    show Service, Update, UpdateType;
+    show Service, ScanUpdate, UpdateType;
 
 part 'client_impl.dart';
 
@@ -63,7 +63,7 @@
 /// Handle to a scan call.
 abstract class Scanner {
   /// A stream of [Update] objects as services are found or lost by the scanner.
-  Stream<Update> get onUpdate;
+  Stream<ScanUpdate> get onUpdate;
 
   /// Stops scanning.
   Future stop();
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 4c20f51..55902c3 100644
--- a/lib/gen/dart-gen/mojom/lib/discovery/discovery.mojom.dart
+++ b/lib/gen/dart-gen/mojom/lib/discovery/discovery.mojom.dart
@@ -8,6 +8,8 @@
 
 import 'package:mojo/bindings.dart' as bindings;
 import 'package:mojo/core.dart' as core;
+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);
@@ -53,6 +55,8 @@
         return 'UpdateType.found';
       case lost:
         return 'UpdateType.lost';
+      default:
+        return null;
     }
   }
 
@@ -61,15 +65,18 @@
 
 
 
+
+
 class Service extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
-    const bindings.StructDataHeader(48, 0)
+    const bindings.StructDataHeader(56, 0)
   ];
   String instanceId = null;
   String instanceName = null;
   String interfaceName = null;
   Map<String, String> attrs = null;
   List<String> addrs = null;
+  Map<String, List<int>> attachments = null;
 
   Service() : super(kVersions.last.size);
 
@@ -167,6 +174,43 @@
         }
       }
     }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(48, true);
+      if (decoder1 == null) {
+        result.attachments = null;
+      } else {
+        decoder1.decodeDataHeaderForMap();
+        List<String> keys0;
+        List<List<int>> values0;
+        {
+          
+          var decoder2 = decoder1.decodePointer(bindings.ArrayDataHeader.kHeaderSize, false);
+          {
+            var si2 = decoder2.decodeDataHeaderForPointerArray(bindings.kUnspecifiedArrayLength);
+            keys0 = new List<String>(si2.numElements);
+            for (int i2 = 0; i2 < si2.numElements; ++i2) {
+              
+              keys0[i2] = decoder2.decodeString(bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i2, false);
+            }
+          }
+        }
+        {
+          
+          var decoder2 = decoder1.decodePointer(bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize, false);
+          {
+            var si2 = decoder2.decodeDataHeaderForPointerArray(keys0.length);
+            values0 = new List<List<int>>(si2.numElements);
+            for (int i2 = 0; i2 < si2.numElements; ++i2) {
+              
+              values0[i2] = decoder2.decodeUint8Array(bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i2, bindings.kNothingNullable, bindings.kUnspecifiedArrayLength);
+            }
+          }
+        }
+        result.attachments = new Map<String, List<int>>.fromIterables(
+            keys0, values0);
+      }
+    }
     return result;
   }
 
@@ -213,6 +257,31 @@
         encoder1.encodeString(addrs[i0], bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i0, false);
       }
     }
+    
+    if (attachments == null) {
+      encoder0.encodeNullPointer(48, true);
+    } else {
+      var encoder1 = encoder0.encoderForMap(48);
+      int size0 = attachments.length;
+      var keys0 = attachments.keys.toList();
+      var values0 = attachments.values.toList();
+      
+      {
+        var encoder2 = encoder1.encodePointerArray(keys0.length, bindings.ArrayDataHeader.kHeaderSize, bindings.kUnspecifiedArrayLength);
+        for (int i1 = 0; i1 < keys0.length; ++i1) {
+          
+          encoder2.encodeString(keys0[i1], bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i1, false);
+        }
+      }
+      
+      {
+        var encoder2 = encoder1.encodePointerArray(values0.length, bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize, bindings.kUnspecifiedArrayLength);
+        for (int i1 = 0; i1 < values0.length; ++i1) {
+          
+          encoder2.encodeUint8Array(values0[i1], bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i1, bindings.kNothingNullable, bindings.kUnspecifiedArrayLength);
+        }
+      }
+    }
   }
 
   String toString() {
@@ -221,7 +290,8 @@
            "instanceName: $instanceName" ", "
            "interfaceName: $interfaceName" ", "
            "attrs: $attrs" ", "
-           "addrs: $addrs" ")";
+           "addrs: $addrs" ", "
+           "attachments: $attachments" ")";
   }
 
   Map toJson() {
@@ -231,21 +301,24 @@
     map["interfaceName"] = interfaceName;
     map["attrs"] = attrs;
     map["addrs"] = addrs;
+    map["attachments"] = attachments;
     return map;
   }
 }
 
 
-class Update extends bindings.Struct {
+
+
+class ScanUpdate extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(24, 0)
   ];
   Service service = null;
   UpdateType updateType = null;
 
-  Update() : super(kVersions.last.size);
+  ScanUpdate() : super(kVersions.last.size);
 
-  static Update deserialize(bindings.Message message) {
+  static ScanUpdate deserialize(bindings.Message message) {
     var decoder = new bindings.Decoder(message);
     var result = decode(decoder);
     if (decoder.excessHandles != null) {
@@ -254,11 +327,11 @@
     return result;
   }
 
-  static Update decode(bindings.Decoder decoder0) {
+  static ScanUpdate decode(bindings.Decoder decoder0) {
     if (decoder0 == null) {
       return null;
     }
-    Update result = new Update();
+    ScanUpdate result = new ScanUpdate();
 
     var mainDataHeader = decoder0.decodeStructDataHeader();
     if (mainDataHeader.version <= kVersions.last.version) {
@@ -303,7 +376,7 @@
   }
 
   String toString() {
-    return "Update("
+    return "ScanUpdate("
            "service: $service" ", "
            "updateType: $updateType" ")";
   }
@@ -317,6 +390,8 @@
 }
 
 
+
+
 class Error extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(32, 0)
@@ -402,16 +477,18 @@
 }
 
 
-class _AdvertiserAdvertiseParams extends bindings.Struct {
+
+
+class _DiscoveryStartAdvertisingParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(24, 0)
   ];
   Service service = null;
   List<String> visibility = null;
 
-  _AdvertiserAdvertiseParams() : super(kVersions.last.size);
+  _DiscoveryStartAdvertisingParams() : super(kVersions.last.size);
 
-  static _AdvertiserAdvertiseParams deserialize(bindings.Message message) {
+  static _DiscoveryStartAdvertisingParams deserialize(bindings.Message message) {
     var decoder = new bindings.Decoder(message);
     var result = decode(decoder);
     if (decoder.excessHandles != null) {
@@ -420,11 +497,11 @@
     return result;
   }
 
-  static _AdvertiserAdvertiseParams decode(bindings.Decoder decoder0) {
+  static _DiscoveryStartAdvertisingParams decode(bindings.Decoder decoder0) {
     if (decoder0 == null) {
       return null;
     }
-    _AdvertiserAdvertiseParams result = new _AdvertiserAdvertiseParams();
+    _DiscoveryStartAdvertisingParams result = new _DiscoveryStartAdvertisingParams();
 
     var mainDataHeader = decoder0.decodeStructDataHeader();
     if (mainDataHeader.version <= kVersions.last.version) {
@@ -483,7 +560,7 @@
   }
 
   String toString() {
-    return "_AdvertiserAdvertiseParams("
+    return "_DiscoveryStartAdvertisingParams("
            "service: $service" ", "
            "visibility: $visibility" ")";
   }
@@ -497,17 +574,18 @@
 }
 
 
-class AdvertiserAdvertiseResponseParams extends bindings.Struct {
+
+
+class DiscoveryStartAdvertisingResponseParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
-    const bindings.StructDataHeader(32, 0)
+    const bindings.StructDataHeader(24, 0)
   ];
-  int handle = 0;
   String instanceId = null;
   Error err = null;
 
-  AdvertiserAdvertiseResponseParams() : super(kVersions.last.size);
+  DiscoveryStartAdvertisingResponseParams() : super(kVersions.last.size);
 
-  static AdvertiserAdvertiseResponseParams deserialize(bindings.Message message) {
+  static DiscoveryStartAdvertisingResponseParams deserialize(bindings.Message message) {
     var decoder = new bindings.Decoder(message);
     var result = decode(decoder);
     if (decoder.excessHandles != null) {
@@ -516,11 +594,11 @@
     return result;
   }
 
-  static AdvertiserAdvertiseResponseParams decode(bindings.Decoder decoder0) {
+  static DiscoveryStartAdvertisingResponseParams decode(bindings.Decoder decoder0) {
     if (decoder0 == null) {
       return null;
     }
-    AdvertiserAdvertiseResponseParams result = new AdvertiserAdvertiseResponseParams();
+    DiscoveryStartAdvertisingResponseParams result = new DiscoveryStartAdvertisingResponseParams();
 
     var mainDataHeader = decoder0.decodeStructDataHeader();
     if (mainDataHeader.version <= kVersions.last.version) {
@@ -542,15 +620,11 @@
     }
     if (mainDataHeader.version >= 0) {
       
-      result.handle = decoder0.decodeUint32(8);
+      result.instanceId = decoder0.decodeString(8, false);
     }
     if (mainDataHeader.version >= 0) {
       
-      result.instanceId = decoder0.decodeString(16, false);
-    }
-    if (mainDataHeader.version >= 0) {
-      
-      var decoder1 = decoder0.decodePointer(24, true);
+      var decoder1 = decoder0.decodePointer(16, true);
       result.err = Error.decode(decoder1);
     }
     return result;
@@ -559,23 +633,19 @@
   void encode(bindings.Encoder encoder) {
     var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
     
-    encoder0.encodeUint32(handle, 8);
+    encoder0.encodeString(instanceId, 8, false);
     
-    encoder0.encodeString(instanceId, 16, false);
-    
-    encoder0.encodeStruct(err, 24, true);
+    encoder0.encodeStruct(err, 16, true);
   }
 
   String toString() {
-    return "AdvertiserAdvertiseResponseParams("
-           "handle: $handle" ", "
+    return "DiscoveryStartAdvertisingResponseParams("
            "instanceId: $instanceId" ", "
            "err: $err" ")";
   }
 
   Map toJson() {
     Map map = new Map();
-    map["handle"] = handle;
     map["instanceId"] = instanceId;
     map["err"] = err;
     return map;
@@ -583,15 +653,17 @@
 }
 
 
-class _AdvertiserStopParams extends bindings.Struct {
+
+
+class _DiscoveryStopAdvertisingParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(16, 0)
   ];
-  int h = 0;
+  String instanceId = null;
 
-  _AdvertiserStopParams() : super(kVersions.last.size);
+  _DiscoveryStopAdvertisingParams() : super(kVersions.last.size);
 
-  static _AdvertiserStopParams deserialize(bindings.Message message) {
+  static _DiscoveryStopAdvertisingParams deserialize(bindings.Message message) {
     var decoder = new bindings.Decoder(message);
     var result = decode(decoder);
     if (decoder.excessHandles != null) {
@@ -600,11 +672,11 @@
     return result;
   }
 
-  static _AdvertiserStopParams decode(bindings.Decoder decoder0) {
+  static _DiscoveryStopAdvertisingParams decode(bindings.Decoder decoder0) {
     if (decoder0 == null) {
       return null;
     }
-    _AdvertiserStopParams result = new _AdvertiserStopParams();
+    _DiscoveryStopAdvertisingParams result = new _DiscoveryStopAdvertisingParams();
 
     var mainDataHeader = decoder0.decodeStructDataHeader();
     if (mainDataHeader.version <= kVersions.last.version) {
@@ -626,7 +698,7 @@
     }
     if (mainDataHeader.version >= 0) {
       
-      result.h = decoder0.decodeUint32(8);
+      result.instanceId = decoder0.decodeString(8, false);
     }
     return result;
   }
@@ -634,31 +706,33 @@
   void encode(bindings.Encoder encoder) {
     var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
     
-    encoder0.encodeUint32(h, 8);
+    encoder0.encodeString(instanceId, 8, false);
   }
 
   String toString() {
-    return "_AdvertiserStopParams("
-           "h: $h" ")";
+    return "_DiscoveryStopAdvertisingParams("
+           "instanceId: $instanceId" ")";
   }
 
   Map toJson() {
     Map map = new Map();
-    map["h"] = h;
+    map["instanceId"] = instanceId;
     return map;
   }
 }
 
 
-class AdvertiserStopResponseParams extends bindings.Struct {
+
+
+class DiscoveryStopAdvertisingResponseParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(16, 0)
   ];
   Error err = null;
 
-  AdvertiserStopResponseParams() : super(kVersions.last.size);
+  DiscoveryStopAdvertisingResponseParams() : super(kVersions.last.size);
 
-  static AdvertiserStopResponseParams deserialize(bindings.Message message) {
+  static DiscoveryStopAdvertisingResponseParams deserialize(bindings.Message message) {
     var decoder = new bindings.Decoder(message);
     var result = decode(decoder);
     if (decoder.excessHandles != null) {
@@ -667,11 +741,11 @@
     return result;
   }
 
-  static AdvertiserStopResponseParams decode(bindings.Decoder decoder0) {
+  static DiscoveryStopAdvertisingResponseParams decode(bindings.Decoder decoder0) {
     if (decoder0 == null) {
       return null;
     }
-    AdvertiserStopResponseParams result = new AdvertiserStopResponseParams();
+    DiscoveryStopAdvertisingResponseParams result = new DiscoveryStopAdvertisingResponseParams();
 
     var mainDataHeader = decoder0.decodeStructDataHeader();
     if (mainDataHeader.version <= kVersions.last.version) {
@@ -706,7 +780,7 @@
   }
 
   String toString() {
-    return "AdvertiserStopResponseParams("
+    return "DiscoveryStopAdvertisingResponseParams("
            "err: $err" ")";
   }
 
@@ -718,16 +792,18 @@
 }
 
 
-class _ScannerScanParams extends bindings.Struct {
+
+
+class _DiscoveryStartScanParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(24, 0)
   ];
   String query = null;
-  Object scanHandler = null;
+  Object handler = null;
 
-  _ScannerScanParams() : super(kVersions.last.size);
+  _DiscoveryStartScanParams() : super(kVersions.last.size);
 
-  static _ScannerScanParams deserialize(bindings.Message message) {
+  static _DiscoveryStartScanParams deserialize(bindings.Message message) {
     var decoder = new bindings.Decoder(message);
     var result = decode(decoder);
     if (decoder.excessHandles != null) {
@@ -736,11 +812,11 @@
     return result;
   }
 
-  static _ScannerScanParams decode(bindings.Decoder decoder0) {
+  static _DiscoveryStartScanParams decode(bindings.Decoder decoder0) {
     if (decoder0 == null) {
       return null;
     }
-    _ScannerScanParams result = new _ScannerScanParams();
+    _DiscoveryStartScanParams result = new _DiscoveryStartScanParams();
 
     var mainDataHeader = decoder0.decodeStructDataHeader();
     if (mainDataHeader.version <= kVersions.last.version) {
@@ -766,7 +842,7 @@
     }
     if (mainDataHeader.version >= 0) {
       
-      result.scanHandler = decoder0.decodeServiceInterface(16, false, ScanHandlerProxy.newFromEndpoint);
+      result.handler = decoder0.decodeServiceInterface(16, false, ScanHandlerProxy.newFromEndpoint);
     }
     return result;
   }
@@ -776,13 +852,13 @@
     
     encoder0.encodeString(query, 8, false);
     
-    encoder0.encodeInterface(scanHandler, 16, false);
+    encoder0.encodeInterface(handler, 16, false);
   }
 
   String toString() {
-    return "_ScannerScanParams("
+    return "_DiscoveryStartScanParams("
            "query: $query" ", "
-           "scanHandler: $scanHandler" ")";
+           "handler: $handler" ")";
   }
 
   Map toJson() {
@@ -792,16 +868,18 @@
 }
 
 
-class ScannerScanResponseParams extends bindings.Struct {
+
+
+class DiscoveryStartScanResponseParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(24, 0)
   ];
-  int handle = 0;
+  int scanId = 0;
   Error err = null;
 
-  ScannerScanResponseParams() : super(kVersions.last.size);
+  DiscoveryStartScanResponseParams() : super(kVersions.last.size);
 
-  static ScannerScanResponseParams deserialize(bindings.Message message) {
+  static DiscoveryStartScanResponseParams deserialize(bindings.Message message) {
     var decoder = new bindings.Decoder(message);
     var result = decode(decoder);
     if (decoder.excessHandles != null) {
@@ -810,11 +888,11 @@
     return result;
   }
 
-  static ScannerScanResponseParams decode(bindings.Decoder decoder0) {
+  static DiscoveryStartScanResponseParams decode(bindings.Decoder decoder0) {
     if (decoder0 == null) {
       return null;
     }
-    ScannerScanResponseParams result = new ScannerScanResponseParams();
+    DiscoveryStartScanResponseParams result = new DiscoveryStartScanResponseParams();
 
     var mainDataHeader = decoder0.decodeStructDataHeader();
     if (mainDataHeader.version <= kVersions.last.version) {
@@ -836,7 +914,7 @@
     }
     if (mainDataHeader.version >= 0) {
       
-      result.handle = decoder0.decodeUint32(8);
+      result.scanId = decoder0.decodeUint32(8);
     }
     if (mainDataHeader.version >= 0) {
       
@@ -849,35 +927,37 @@
   void encode(bindings.Encoder encoder) {
     var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
     
-    encoder0.encodeUint32(handle, 8);
+    encoder0.encodeUint32(scanId, 8);
     
     encoder0.encodeStruct(err, 16, true);
   }
 
   String toString() {
-    return "ScannerScanResponseParams("
-           "handle: $handle" ", "
+    return "DiscoveryStartScanResponseParams("
+           "scanId: $scanId" ", "
            "err: $err" ")";
   }
 
   Map toJson() {
     Map map = new Map();
-    map["handle"] = handle;
+    map["scanId"] = scanId;
     map["err"] = err;
     return map;
   }
 }
 
 
-class _ScannerStopParams extends bindings.Struct {
+
+
+class _DiscoveryStopScanParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(16, 0)
   ];
-  int h = 0;
+  int scanId = 0;
 
-  _ScannerStopParams() : super(kVersions.last.size);
+  _DiscoveryStopScanParams() : super(kVersions.last.size);
 
-  static _ScannerStopParams deserialize(bindings.Message message) {
+  static _DiscoveryStopScanParams deserialize(bindings.Message message) {
     var decoder = new bindings.Decoder(message);
     var result = decode(decoder);
     if (decoder.excessHandles != null) {
@@ -886,11 +966,11 @@
     return result;
   }
 
-  static _ScannerStopParams decode(bindings.Decoder decoder0) {
+  static _DiscoveryStopScanParams decode(bindings.Decoder decoder0) {
     if (decoder0 == null) {
       return null;
     }
-    _ScannerStopParams result = new _ScannerStopParams();
+    _DiscoveryStopScanParams result = new _DiscoveryStopScanParams();
 
     var mainDataHeader = decoder0.decodeStructDataHeader();
     if (mainDataHeader.version <= kVersions.last.version) {
@@ -912,7 +992,7 @@
     }
     if (mainDataHeader.version >= 0) {
       
-      result.h = decoder0.decodeUint32(8);
+      result.scanId = decoder0.decodeUint32(8);
     }
     return result;
   }
@@ -920,31 +1000,33 @@
   void encode(bindings.Encoder encoder) {
     var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
     
-    encoder0.encodeUint32(h, 8);
+    encoder0.encodeUint32(scanId, 8);
   }
 
   String toString() {
-    return "_ScannerStopParams("
-           "h: $h" ")";
+    return "_DiscoveryStopScanParams("
+           "scanId: $scanId" ")";
   }
 
   Map toJson() {
     Map map = new Map();
-    map["h"] = h;
+    map["scanId"] = scanId;
     return map;
   }
 }
 
 
-class ScannerStopResponseParams extends bindings.Struct {
+
+
+class DiscoveryStopScanResponseParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(16, 0)
   ];
   Error err = null;
 
-  ScannerStopResponseParams() : super(kVersions.last.size);
+  DiscoveryStopScanResponseParams() : super(kVersions.last.size);
 
-  static ScannerStopResponseParams deserialize(bindings.Message message) {
+  static DiscoveryStopScanResponseParams deserialize(bindings.Message message) {
     var decoder = new bindings.Decoder(message);
     var result = decode(decoder);
     if (decoder.excessHandles != null) {
@@ -953,11 +1035,11 @@
     return result;
   }
 
-  static ScannerStopResponseParams decode(bindings.Decoder decoder0) {
+  static DiscoveryStopScanResponseParams decode(bindings.Decoder decoder0) {
     if (decoder0 == null) {
       return null;
     }
-    ScannerStopResponseParams result = new ScannerStopResponseParams();
+    DiscoveryStopScanResponseParams result = new DiscoveryStopScanResponseParams();
 
     var mainDataHeader = decoder0.decodeStructDataHeader();
     if (mainDataHeader.version <= kVersions.last.version) {
@@ -992,7 +1074,7 @@
   }
 
   String toString() {
-    return "ScannerStopResponseParams("
+    return "DiscoveryStopScanResponseParams("
            "err: $err" ")";
   }
 
@@ -1004,11 +1086,13 @@
 }
 
 
+
+
 class _ScanHandlerUpdateParams extends bindings.Struct {
   static const List<bindings.StructDataHeader> kVersions = const [
     const bindings.StructDataHeader(16, 0)
   ];
-  Update update = null;
+  ScanUpdate update = null;
 
   _ScanHandlerUpdateParams() : super(kVersions.last.size);
 
@@ -1048,7 +1132,7 @@
     if (mainDataHeader.version >= 0) {
       
       var decoder1 = decoder0.decodePointer(8, false);
-      result.update = Update.decode(decoder1);
+      result.update = ScanUpdate.decode(decoder1);
     }
     return result;
   }
@@ -1071,35 +1155,55 @@
   }
 }
 
-const int _Advertiser_advertiseName = 0;
-const int _Advertiser_stopName = 1;
 
-abstract class Advertiser {
-  static const String serviceName = "v23::discovery::Advertiser";
-  dynamic advertise(Service service,List<String> visibility,[Function responseFactory = null]);
-  dynamic stop(int h,[Function responseFactory = null]);
+
+
+const int _Discovery_startAdvertisingName = 0;
+const int _Discovery_stopAdvertisingName = 1;
+const int _Discovery_startScanName = 2;
+const int _Discovery_stopScanName = 3;
+
+
+
+class _DiscoveryServiceDescription implements service_describer.ServiceDescription {
+  dynamic getTopLevelInterface([Function responseFactory]) => null;
+
+  dynamic getTypeDefinition(String typeKey, [Function responseFactory]) => null;
+
+  dynamic getAllTypeDefinitions([Function responseFactory]) => null;
+}
+
+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]);
 }
 
 
-class _AdvertiserProxyImpl extends bindings.Proxy {
-  _AdvertiserProxyImpl.fromEndpoint(
+class _DiscoveryProxyImpl extends bindings.Proxy {
+  _DiscoveryProxyImpl.fromEndpoint(
       core.MojoMessagePipeEndpoint endpoint) : super.fromEndpoint(endpoint);
 
-  _AdvertiserProxyImpl.fromHandle(core.MojoHandle handle) :
+  _DiscoveryProxyImpl.fromHandle(core.MojoHandle handle) :
       super.fromHandle(handle);
 
-  _AdvertiserProxyImpl.unbound() : super.unbound();
+  _DiscoveryProxyImpl.unbound() : super.unbound();
 
-  static _AdvertiserProxyImpl newFromEndpoint(
+  static _DiscoveryProxyImpl newFromEndpoint(
       core.MojoMessagePipeEndpoint endpoint) {
-    assert(endpoint.setDescription("For _AdvertiserProxyImpl"));
-    return new _AdvertiserProxyImpl.fromEndpoint(endpoint);
+    assert(endpoint.setDescription("For _DiscoveryProxyImpl"));
+    return new _DiscoveryProxyImpl.fromEndpoint(endpoint);
   }
 
+  service_describer.ServiceDescription get serviceDescription =>
+    new _DiscoveryServiceDescription();
+
   void handleResponse(bindings.ServiceMessage message) {
     switch (message.header.type) {
-      case _Advertiser_advertiseName:
-        var r = AdvertiserAdvertiseResponseParams.deserialize(
+      case _Discovery_startAdvertisingName:
+        var r = DiscoveryStartAdvertisingResponseParams.deserialize(
             message.payload);
         if (!message.header.hasRequestId) {
           proxyError("Expected a message with a valid request Id.");
@@ -1118,8 +1222,48 @@
         }
         c.complete(r);
         break;
-      case _Advertiser_stopName:
-        var r = AdvertiserStopResponseParams.deserialize(
+      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(
             message.payload);
         if (!message.header.hasRequestId) {
           proxyError("Expected a message with a valid request Id.");
@@ -1147,75 +1291,94 @@
 
   String toString() {
     var superString = super.toString();
-    return "_AdvertiserProxyImpl($superString)";
+    return "_DiscoveryProxyImpl($superString)";
   }
 }
 
 
-class _AdvertiserProxyCalls implements Advertiser {
-  _AdvertiserProxyImpl _proxyImpl;
+class _DiscoveryProxyCalls implements Discovery {
+  _DiscoveryProxyImpl _proxyImpl;
 
-  _AdvertiserProxyCalls(this._proxyImpl);
-    dynamic advertise(Service service,List<String> visibility,[Function responseFactory = null]) {
-      var params = new _AdvertiserAdvertiseParams();
+  _DiscoveryProxyCalls(this._proxyImpl);
+    dynamic startAdvertising(Service service,List<String> visibility,[Function responseFactory = null]) {
+      var params = new _DiscoveryStartAdvertisingParams();
       params.service = service;
       params.visibility = visibility;
       return _proxyImpl.sendMessageWithRequestId(
           params,
-          _Advertiser_advertiseName,
+          _Discovery_startAdvertisingName,
           -1,
           bindings.MessageHeader.kMessageExpectsResponse);
     }
-    dynamic stop(int h,[Function responseFactory = null]) {
-      var params = new _AdvertiserStopParams();
-      params.h = h;
+    dynamic stopAdvertising(String instanceId,[Function responseFactory = null]) {
+      var params = new _DiscoveryStopAdvertisingParams();
+      params.instanceId = instanceId;
       return _proxyImpl.sendMessageWithRequestId(
           params,
-          _Advertiser_stopName,
+          _Discovery_stopAdvertisingName,
+          -1,
+          bindings.MessageHeader.kMessageExpectsResponse);
+    }
+    dynamic startScan(String query,Object handler,[Function responseFactory = null]) {
+      var params = new _DiscoveryStartScanParams();
+      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,
           -1,
           bindings.MessageHeader.kMessageExpectsResponse);
     }
 }
 
 
-class AdvertiserProxy implements bindings.ProxyBase {
+class DiscoveryProxy implements bindings.ProxyBase {
   final bindings.Proxy impl;
-  Advertiser ptr;
+  Discovery ptr;
 
-  AdvertiserProxy(_AdvertiserProxyImpl proxyImpl) :
+  DiscoveryProxy(_DiscoveryProxyImpl proxyImpl) :
       impl = proxyImpl,
-      ptr = new _AdvertiserProxyCalls(proxyImpl);
+      ptr = new _DiscoveryProxyCalls(proxyImpl);
 
-  AdvertiserProxy.fromEndpoint(
+  DiscoveryProxy.fromEndpoint(
       core.MojoMessagePipeEndpoint endpoint) :
-      impl = new _AdvertiserProxyImpl.fromEndpoint(endpoint) {
-    ptr = new _AdvertiserProxyCalls(impl);
+      impl = new _DiscoveryProxyImpl.fromEndpoint(endpoint) {
+    ptr = new _DiscoveryProxyCalls(impl);
   }
 
-  AdvertiserProxy.fromHandle(core.MojoHandle handle) :
-      impl = new _AdvertiserProxyImpl.fromHandle(handle) {
-    ptr = new _AdvertiserProxyCalls(impl);
+  DiscoveryProxy.fromHandle(core.MojoHandle handle) :
+      impl = new _DiscoveryProxyImpl.fromHandle(handle) {
+    ptr = new _DiscoveryProxyCalls(impl);
   }
 
-  AdvertiserProxy.unbound() :
-      impl = new _AdvertiserProxyImpl.unbound() {
-    ptr = new _AdvertiserProxyCalls(impl);
+  DiscoveryProxy.unbound() :
+      impl = new _DiscoveryProxyImpl.unbound() {
+    ptr = new _DiscoveryProxyCalls(impl);
   }
 
-  factory AdvertiserProxy.connectToService(
+  factory DiscoveryProxy.connectToService(
       bindings.ServiceConnector s, String url, [String serviceName]) {
-    AdvertiserProxy p = new AdvertiserProxy.unbound();
+    DiscoveryProxy p = new DiscoveryProxy.unbound();
     s.connectToService(url, p, serviceName);
     return p;
   }
 
-  static AdvertiserProxy newFromEndpoint(
+  static DiscoveryProxy newFromEndpoint(
       core.MojoMessagePipeEndpoint endpoint) {
-    assert(endpoint.setDescription("For AdvertiserProxy"));
-    return new AdvertiserProxy.fromEndpoint(endpoint);
+    assert(endpoint.setDescription("For DiscoveryProxy"));
+    return new DiscoveryProxy.fromEndpoint(endpoint);
   }
 
-  String get serviceName => Advertiser.serviceName;
+  String get serviceName => Discovery.serviceName;
 
   Future close({bool immediate: false}) => impl.close(immediate: immediate);
 
@@ -1232,39 +1395,49 @@
   }
 
   String toString() {
-    return "AdvertiserProxy($impl)";
+    return "DiscoveryProxy($impl)";
   }
 }
 
 
-class AdvertiserStub extends bindings.Stub {
-  Advertiser _impl = null;
+class DiscoveryStub extends bindings.Stub {
+  Discovery _impl = null;
 
-  AdvertiserStub.fromEndpoint(
+  DiscoveryStub.fromEndpoint(
       core.MojoMessagePipeEndpoint endpoint, [this._impl])
       : super.fromEndpoint(endpoint);
 
-  AdvertiserStub.fromHandle(core.MojoHandle handle, [this._impl])
+  DiscoveryStub.fromHandle(core.MojoHandle handle, [this._impl])
       : super.fromHandle(handle);
 
-  AdvertiserStub.unbound() : super.unbound();
+  DiscoveryStub.unbound() : super.unbound();
 
-  static AdvertiserStub newFromEndpoint(
+  static DiscoveryStub newFromEndpoint(
       core.MojoMessagePipeEndpoint endpoint) {
-    assert(endpoint.setDescription("For AdvertiserStub"));
-    return new AdvertiserStub.fromEndpoint(endpoint);
+    assert(endpoint.setDescription("For DiscoveryStub"));
+    return new DiscoveryStub.fromEndpoint(endpoint);
   }
 
 
-  AdvertiserAdvertiseResponseParams _AdvertiserAdvertiseResponseParamsFactory(int handle, String instanceId, Error err) {
-    var mojo_factory_result = new AdvertiserAdvertiseResponseParams();
-    mojo_factory_result.handle = handle;
+  DiscoveryStartAdvertisingResponseParams _DiscoveryStartAdvertisingResponseParamsFactory(String instanceId, Error err) {
+    var mojo_factory_result = new DiscoveryStartAdvertisingResponseParams();
     mojo_factory_result.instanceId = instanceId;
     mojo_factory_result.err = err;
     return mojo_factory_result;
   }
-  AdvertiserStopResponseParams _AdvertiserStopResponseParamsFactory(Error err) {
-    var mojo_factory_result = new AdvertiserStopResponseParams();
+  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();
     mojo_factory_result.err = err;
     return mojo_factory_result;
   }
@@ -1277,16 +1450,16 @@
     }
     assert(_impl != null);
     switch (message.header.type) {
-      case _Advertiser_advertiseName:
-        var params = _AdvertiserAdvertiseParams.deserialize(
+      case _Discovery_startAdvertisingName:
+        var params = _DiscoveryStartAdvertisingParams.deserialize(
             message.payload);
-        var response = _impl.advertise(params.service,params.visibility,_AdvertiserAdvertiseResponseParamsFactory);
+        var response = _impl.startAdvertising(params.service,params.visibility,_DiscoveryStartAdvertisingResponseParamsFactory);
         if (response is Future) {
           return response.then((response) {
             if (response != null) {
               return buildResponseWithId(
                   response,
-                  _Advertiser_advertiseName,
+                  _Discovery_startAdvertisingName,
                   message.header.requestId,
                   bindings.MessageHeader.kMessageIsResponse);
             }
@@ -1294,21 +1467,21 @@
         } else if (response != null) {
           return buildResponseWithId(
               response,
-              _Advertiser_advertiseName,
+              _Discovery_startAdvertisingName,
               message.header.requestId,
               bindings.MessageHeader.kMessageIsResponse);
         }
         break;
-      case _Advertiser_stopName:
-        var params = _AdvertiserStopParams.deserialize(
+      case _Discovery_stopAdvertisingName:
+        var params = _DiscoveryStopAdvertisingParams.deserialize(
             message.payload);
-        var response = _impl.stop(params.h,_AdvertiserStopResponseParamsFactory);
+        var response = _impl.stopAdvertising(params.instanceId,_DiscoveryStopAdvertisingResponseParamsFactory);
         if (response is Future) {
           return response.then((response) {
             if (response != null) {
               return buildResponseWithId(
                   response,
-                  _Advertiser_stopName,
+                  _Discovery_stopAdvertisingName,
                   message.header.requestId,
                   bindings.MessageHeader.kMessageIsResponse);
             }
@@ -1316,7 +1489,51 @@
         } else if (response != null) {
           return buildResponseWithId(
               response,
-              _Advertiser_stopName,
+              _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,
               message.header.requestId,
               bindings.MessageHeader.kMessageIsResponse);
         }
@@ -1328,295 +1545,38 @@
     return null;
   }
 
-  Advertiser get impl => _impl;
-  set impl(Advertiser d) {
+  Discovery get impl => _impl;
+  set impl(Discovery d) {
     assert(_impl == null);
     _impl = d;
   }
 
   String toString() {
     var superString = super.toString();
-    return "AdvertiserStub($superString)";
+    return "DiscoveryStub($superString)";
   }
 
   int get version => 0;
-}
 
-const int _Scanner_scanName = 0;
-const int _Scanner_stopName = 1;
-
-abstract class Scanner {
-  static const String serviceName = "v23::discovery::Scanner";
-  dynamic scan(String query,Object scanHandler,[Function responseFactory = null]);
-  dynamic stop(int h,[Function responseFactory = null]);
-}
-
-
-class _ScannerProxyImpl extends bindings.Proxy {
-  _ScannerProxyImpl.fromEndpoint(
-      core.MojoMessagePipeEndpoint endpoint) : super.fromEndpoint(endpoint);
-
-  _ScannerProxyImpl.fromHandle(core.MojoHandle handle) :
-      super.fromHandle(handle);
-
-  _ScannerProxyImpl.unbound() : super.unbound();
-
-  static _ScannerProxyImpl newFromEndpoint(
-      core.MojoMessagePipeEndpoint endpoint) {
-    assert(endpoint.setDescription("For _ScannerProxyImpl"));
-    return new _ScannerProxyImpl.fromEndpoint(endpoint);
-  }
-
-  void handleResponse(bindings.ServiceMessage message) {
-    switch (message.header.type) {
-      case _Scanner_scanName:
-        var r = ScannerScanResponseParams.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 _Scanner_stopName:
-        var r = ScannerStopResponseParams.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 "_ScannerProxyImpl($superString)";
-  }
-}
-
-
-class _ScannerProxyCalls implements Scanner {
-  _ScannerProxyImpl _proxyImpl;
-
-  _ScannerProxyCalls(this._proxyImpl);
-    dynamic scan(String query,Object scanHandler,[Function responseFactory = null]) {
-      var params = new _ScannerScanParams();
-      params.query = query;
-      params.scanHandler = scanHandler;
-      return _proxyImpl.sendMessageWithRequestId(
-          params,
-          _Scanner_scanName,
-          -1,
-          bindings.MessageHeader.kMessageExpectsResponse);
-    }
-    dynamic stop(int h,[Function responseFactory = null]) {
-      var params = new _ScannerStopParams();
-      params.h = h;
-      return _proxyImpl.sendMessageWithRequestId(
-          params,
-          _Scanner_stopName,
-          -1,
-          bindings.MessageHeader.kMessageExpectsResponse);
-    }
-}
-
-
-class ScannerProxy implements bindings.ProxyBase {
-  final bindings.Proxy impl;
-  Scanner ptr;
-
-  ScannerProxy(_ScannerProxyImpl proxyImpl) :
-      impl = proxyImpl,
-      ptr = new _ScannerProxyCalls(proxyImpl);
-
-  ScannerProxy.fromEndpoint(
-      core.MojoMessagePipeEndpoint endpoint) :
-      impl = new _ScannerProxyImpl.fromEndpoint(endpoint) {
-    ptr = new _ScannerProxyCalls(impl);
-  }
-
-  ScannerProxy.fromHandle(core.MojoHandle handle) :
-      impl = new _ScannerProxyImpl.fromHandle(handle) {
-    ptr = new _ScannerProxyCalls(impl);
-  }
-
-  ScannerProxy.unbound() :
-      impl = new _ScannerProxyImpl.unbound() {
-    ptr = new _ScannerProxyCalls(impl);
-  }
-
-  factory ScannerProxy.connectToService(
-      bindings.ServiceConnector s, String url, [String serviceName]) {
-    ScannerProxy p = new ScannerProxy.unbound();
-    s.connectToService(url, p, serviceName);
-    return p;
-  }
-
-  static ScannerProxy newFromEndpoint(
-      core.MojoMessagePipeEndpoint endpoint) {
-    assert(endpoint.setDescription("For ScannerProxy"));
-    return new ScannerProxy.fromEndpoint(endpoint);
-  }
-
-  String get serviceName => Scanner.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 "ScannerProxy($impl)";
-  }
-}
-
-
-class ScannerStub extends bindings.Stub {
-  Scanner _impl = null;
-
-  ScannerStub.fromEndpoint(
-      core.MojoMessagePipeEndpoint endpoint, [this._impl])
-      : super.fromEndpoint(endpoint);
-
-  ScannerStub.fromHandle(core.MojoHandle handle, [this._impl])
-      : super.fromHandle(handle);
-
-  ScannerStub.unbound() : super.unbound();
-
-  static ScannerStub newFromEndpoint(
-      core.MojoMessagePipeEndpoint endpoint) {
-    assert(endpoint.setDescription("For ScannerStub"));
-    return new ScannerStub.fromEndpoint(endpoint);
-  }
-
-
-  ScannerScanResponseParams _ScannerScanResponseParamsFactory(int handle, Error err) {
-    var mojo_factory_result = new ScannerScanResponseParams();
-    mojo_factory_result.handle = handle;
-    mojo_factory_result.err = err;
-    return mojo_factory_result;
-  }
-  ScannerStopResponseParams _ScannerStopResponseParamsFactory(Error err) {
-    var mojo_factory_result = new ScannerStopResponseParams();
-    mojo_factory_result.err = err;
-    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 _Scanner_scanName:
-        var params = _ScannerScanParams.deserialize(
-            message.payload);
-        var response = _impl.scan(params.query,params.scanHandler,_ScannerScanResponseParamsFactory);
-        if (response is Future) {
-          return response.then((response) {
-            if (response != null) {
-              return buildResponseWithId(
-                  response,
-                  _Scanner_scanName,
-                  message.header.requestId,
-                  bindings.MessageHeader.kMessageIsResponse);
-            }
-          });
-        } else if (response != null) {
-          return buildResponseWithId(
-              response,
-              _Scanner_scanName,
-              message.header.requestId,
-              bindings.MessageHeader.kMessageIsResponse);
-        }
-        break;
-      case _Scanner_stopName:
-        var params = _ScannerStopParams.deserialize(
-            message.payload);
-        var response = _impl.stop(params.h,_ScannerStopResponseParamsFactory);
-        if (response is Future) {
-          return response.then((response) {
-            if (response != null) {
-              return buildResponseWithId(
-                  response,
-                  _Scanner_stopName,
-                  message.header.requestId,
-                  bindings.MessageHeader.kMessageIsResponse);
-            }
-          });
-        } else if (response != null) {
-          return buildResponseWithId(
-              response,
-              _Scanner_stopName,
-              message.header.requestId,
-              bindings.MessageHeader.kMessageIsResponse);
-        }
-        break;
-      default:
-        throw new bindings.MojoCodecError("Unexpected message name");
-        break;
-    }
-    return null;
-  }
-
-  Scanner get impl => _impl;
-  set impl(Scanner d) {
-    assert(_impl == null);
-    _impl = d;
-  }
-
-  String toString() {
-    var superString = super.toString();
-    return "ScannerStub($superString)";
-  }
-
-  int get version => 0;
+  service_describer.ServiceDescription get serviceDescription =>
+    new _DiscoveryServiceDescription();
 }
 
 const int _ScanHandler_updateName = 0;
 
+
+
+class _ScanHandlerServiceDescription implements service_describer.ServiceDescription {
+  dynamic getTopLevelInterface([Function responseFactory]) => null;
+
+  dynamic getTypeDefinition(String typeKey, [Function responseFactory]) => null;
+
+  dynamic getAllTypeDefinitions([Function responseFactory]) => null;
+}
+
 abstract class ScanHandler {
   static const String serviceName = "v23::discovery::ScanHandler";
-  void update(Update update);
+  void update(ScanUpdate update);
 }
 
 
@@ -1635,6 +1595,9 @@
     return new _ScanHandlerProxyImpl.fromEndpoint(endpoint);
   }
 
+  service_describer.ServiceDescription get serviceDescription =>
+    new _ScanHandlerServiceDescription();
+
   void handleResponse(bindings.ServiceMessage message) {
     switch (message.header.type) {
       default:
@@ -1655,7 +1618,7 @@
   _ScanHandlerProxyImpl _proxyImpl;
 
   _ScanHandlerProxyCalls(this._proxyImpl);
-    void update(Update update) {
+    void update(ScanUpdate update) {
       if (!_proxyImpl.isBound) {
         _proxyImpl.proxyError("The Proxy is closed.");
         return;
@@ -1778,6 +1741,10 @@
   }
 
   int get version => 0;
+
+  service_describer.ServiceDescription get serviceDescription =>
+    new _ScanHandlerServiceDescription();
 }
 
 
+
diff --git a/mojom/vanadium/discovery.mojom b/mojom/vanadium/discovery.mojom
index f9c5443..0ae5c2d 100644
--- a/mojom/vanadium/discovery.mojom
+++ b/mojom/vanadium/discovery.mojom
@@ -31,7 +31,7 @@
   lost,
 };
 
-struct Update {
+struct ScanUpdate {
   Service service;
   UpdateType update_type;
 };
@@ -80,5 +80,5 @@
 [ServiceName="v23::discovery::ScanHandler"]
 interface ScanHandler {
   // Update will be called when a Service is found or lost.
-  Update(Update update);
+  Update(ScanUpdate update);
 };
diff --git a/pubspec.yaml b/pubspec.yaml
index fdc8235..d6f5a84 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -2,7 +2,7 @@
 description: Discovery is a discovery system for developers that makes it easy to advertise apps and scan for them. It works over MDNS and BLE.
 homepage: https://github.com/vanadium/mojo.discovery
 name: v23discovery
-version: 0.0.12
+version: 0.0.13
 dependencies:
   mojo_sdk: 0.2.11
 dev_dependencies: