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:
