diff --git a/.gitignore b/.gitignore
index d1b26e4..0530729 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,10 @@
 /.jiri
 #TODO(nlacasse): Get rid of .v23 below once v23->jiri transition is complete.
 /.v23
-gen
+/gen
+/lib/gen/dart-pkg
+/lib/gen/mojom
+/packages
+/.packages
+/.pub
+/pubspec.lock
diff --git a/.jiriignore b/.jiriignore
index 0cb2b99..ed981e9 100644
--- a/.jiriignore
+++ b/.jiriignore
@@ -1 +1,2 @@
 go/src/mojom/vanadium/discovery/discovery.mojom.go
+lib/gen/dart-gen/mojom/lib/discovery/discovery.mojom.dart
diff --git a/Makefile b/Makefile
index c5e7152..c2acbc4 100644
--- a/Makefile
+++ b/Makefile
@@ -22,13 +22,23 @@
 endef
 all: $(DISCOVERY_BUILD_DIR)/discovery.mojo
 
+# Installs dart dependencies.
+.PHONY: packages
+packages:
+	pub upgrade
 
 go/src/mojom/vanadium/discovery/discovery.mojom.go: mojom/vanadium/discovery.mojom | mojo-env-check
 	$(call MOJOM_GEN,$<,.,.,go)
 	gofmt -w $@
 
+go/src/mojom/vanadium/discovery/discovery.mojom.dart: mojom/vanadium/discovery.mojom packages | mojo-env-check
+	$(call MOJOM_GEN,$<,.,lib/gen,dart)
+	# TODO(nlacasse): mojom_bindings_generator creates bad symlinks on dart
+	# files, so we delete them.  Stop doing this once the generator is fixed.
+	# See https://github.com/domokit/mojo/issues/386
+	rm -f lib/gen/mojom/$(notdir $@)
 
-$(DISCOVERY_BUILD_DIR)/discovery.mojo: $(V23_GO_FILES) $(MOJO_SHARED_LIB) go/src/mojom/vanadium/discovery/discovery.mojom.go | mojo-env-check
+$(DISCOVERY_BUILD_DIR)/discovery.mojo: $(V23_GO_FILES) $(MOJO_SHARED_LIB) go/src/mojom/vanadium/discovery/discovery.mojom.go go/src/mojom/vanadium/discovery/discovery.mojom.dart | mojo-env-check
 	$(call MOGO_BUILD,vanadium/discovery,$@)
 
 $(DISCOVERY_BUILD_DIR)/advertiser.mojo: $(V23_GO_FILES) $(MOJO_SHARED_LIB) go/src/mojom/vanadium/discovery/discovery.mojom.go | mojo-env-check
diff --git a/go/src/mojom/vanadium/discovery/discovery.mojom.go b/go/src/mojom/vanadium/discovery/discovery.mojom.go
index 0c0393f..6d35293 100644
--- a/go/src/mojom/vanadium/discovery/discovery.mojom.go
+++ b/go/src/mojom/vanadium/discovery/discovery.mojom.go
@@ -14,9 +14,77 @@
 	"fmt"
 	"mojo/public/go/bindings"
 	"mojo/public/go/system"
+	"mojo/public/interfaces/bindings/mojom_types"
+	"mojo/public/interfaces/bindings/service_describer"
 	"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_Service__ string = "discovery_Service__"
+var ID_discovery_Error__ string = "discovery_Error__"
+var ID_discovery_Advertiser__ string = "discovery_Advertiser__"
+var ID_discovery_Scanner__ string = "discovery_Scanner__"
+var ID_discovery_ScanHandler__ string = "discovery_ScanHandler__"
+
+var discoveryDesc__ = make(map[string]mojom_types.UserDefinedType)
+
+func init() {
+	discoveryDesc__["discovery_Service__"] = &mojom_types.UserDefinedTypeStructType{
+		Value: discovery_Service__(),
+	}
+
+	discoveryDesc__["discovery_Error__"] = &mojom_types.UserDefinedTypeStructType{
+		Value: discovery_Error__(),
+	}
+
+	discoveryDesc__["discovery_Advertiser__"] = &mojom_types.UserDefinedTypeInterfaceType{
+		Value: discovery_Advertiser__(),
+	}
+	discoveryDesc__["discovery_Advertiser_Advertise_Params__"] = &mojom_types.UserDefinedTypeStructType{
+		Value: discovery_Advertiser_Advertise_Params__(),
+	}
+
+	discoveryDesc__["discovery_Advertiser_Advertise_ResponseParams__"] = &mojom_types.UserDefinedTypeStructType{
+		Value: discovery_Advertiser_Advertise_ResponseParams__(),
+	}
+
+	discoveryDesc__["discovery_Advertiser_Stop_Params__"] = &mojom_types.UserDefinedTypeStructType{
+		Value: discovery_Advertiser_Stop_Params__(),
+	}
+
+	discoveryDesc__["discovery_Scanner__"] = &mojom_types.UserDefinedTypeInterfaceType{
+		Value: discovery_Scanner__(),
+	}
+	discoveryDesc__["discovery_Scanner_Scan_Params__"] = &mojom_types.UserDefinedTypeStructType{
+		Value: discovery_Scanner_Scan_Params__(),
+	}
+
+	discoveryDesc__["discovery_ScanHandler__"] = &mojom_types.UserDefinedTypeInterfaceType{
+		Value: discovery_ScanHandler__(),
+	}
+	discoveryDesc__["discovery_ScanHandler_Found_Params__"] = &mojom_types.UserDefinedTypeStructType{
+		Value: discovery_ScanHandler_Found_Params__(),
+	}
+
+	discoveryDesc__["discovery_ScanHandler_Lost_Params__"] = &mojom_types.UserDefinedTypeStructType{
+		Value: discovery_ScanHandler_Lost_Params__(),
+	}
+
+	discoveryDesc__["discovery_Scanner_Scan_ResponseParams__"] = &mojom_types.UserDefinedTypeStructType{
+		Value: discovery_Scanner_Scan_ResponseParams__(),
+	}
+
+	discoveryDesc__["discovery_Scanner_Stop_Params__"] = &mojom_types.UserDefinedTypeStructType{
+		Value: discovery_Scanner_Stop_Params__(),
+	}
+
+}
+func GetAllMojomTypeDefinitions() map[string]mojom_types.UserDefinedType {
+	return discoveryDesc__
+}
+
 type Advertiser interface {
 	Advertise(inS Service, inVisibility []string) (outHandle uint32, outErr *Error, err error)
 	Stop(inH uint32) (err error)
@@ -48,6 +116,10 @@
 	return advertiser_Name
 }
 
+func (f *Advertiser_ServiceFactory) ServiceDescription() service_describer.ServiceDescription {
+	return &Advertiser_ServiceDescription{}
+}
+
 func (f *Advertiser_ServiceFactory) Create(messagePipe system.MessagePipeHandle) {
 	request := Advertiser_Request{bindings.NewMessagePipeHandleOwner(messagePipe)}
 	f.Delegate.Create(request)
@@ -188,6 +260,36 @@
 	return nil
 }
 
+// String names and labels used by the MojomStruct types.
+var (
+	structName_AdvertiserAdvertiseParams                   = "AdvertiserAdvertiseParams"
+	structFieldName_AdvertiserAdvertiseParams_InS          = "InS"
+	structFieldName_AdvertiserAdvertiseParams_InVisibility = "InVisibility"
+)
+
+func discovery_Advertiser_Advertise_Params__() mojom_types.MojomStruct {
+	return mojom_types.MojomStruct{
+		DeclData: &mojom_types.DeclarationData{
+			ShortName: &structName_AdvertiserAdvertiseParams,
+		}, Fields: []mojom_types.StructField{mojom_types.StructField{
+			DeclData: &mojom_types.DeclarationData{
+				ShortName: &structFieldName_AdvertiserAdvertiseParams_InS,
+			},
+			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_AdvertiserAdvertiseParams_InVisibility,
+			},
+			Type: &mojom_types.TypeArrayType{
+				Value: mojom_types.ArrayType{ElementType: &mojom_types.TypeStringType{mojom_types.StringType{false}}},
+			},
+		}},
+	}
+}
+
 type advertiser_Advertise_ResponseParams struct {
 	outHandle uint32
 	outErr    *Error
@@ -264,6 +366,34 @@
 	return nil
 }
 
+// String names and labels used by the MojomStruct types.
+var (
+	structName_AdvertiserAdvertiseResponseParams                = "AdvertiserAdvertiseResponseParams"
+	structFieldName_AdvertiserAdvertiseResponseParams_OutHandle = "OutHandle"
+	structFieldName_AdvertiserAdvertiseResponseParams_OutErr    = "OutErr"
+)
+
+func discovery_Advertiser_Advertise_ResponseParams__() mojom_types.MojomStruct {
+	return mojom_types.MojomStruct{
+		DeclData: &mojom_types.DeclarationData{
+			ShortName: &structName_AdvertiserAdvertiseResponseParams,
+		}, Fields: []mojom_types.StructField{mojom_types.StructField{
+			DeclData: &mojom_types.DeclarationData{
+				ShortName: &structFieldName_AdvertiserAdvertiseResponseParams_OutHandle,
+			},
+			Type: &mojom_types.TypeSimpleType{mojom_types.SimpleType_UinT32},
+		}, mojom_types.StructField{
+			DeclData: &mojom_types.DeclarationData{
+				ShortName: &structFieldName_AdvertiserAdvertiseResponseParams_OutErr,
+			},
+			Type: &mojom_types.TypeTypeReference{
+				Value: mojom_types.TypeReference{Nullable: true, Identifier: &ID_discovery_Error__,
+					TypeKey: &ID_discovery_Error__},
+			},
+		}},
+	}
+}
+
 func (p *Advertiser_Proxy) Advertise(inS Service, inVisibility []string) (outHandle uint32, outErr *Error, err error) {
 	payload := &advertiser_Advertise_Params{
 		inS,
@@ -358,6 +488,25 @@
 	return nil
 }
 
+// String names and labels used by the MojomStruct types.
+var (
+	structName_AdvertiserStopParams          = "AdvertiserStopParams"
+	structFieldName_AdvertiserStopParams_InH = "InH"
+)
+
+func discovery_Advertiser_Stop_Params__() mojom_types.MojomStruct {
+	return mojom_types.MojomStruct{
+		DeclData: &mojom_types.DeclarationData{
+			ShortName: &structName_AdvertiserStopParams,
+		}, Fields: []mojom_types.StructField{mojom_types.StructField{
+			DeclData: &mojom_types.DeclarationData{
+				ShortName: &structFieldName_AdvertiserStopParams_InH,
+			},
+			Type: &mojom_types.TypeSimpleType{mojom_types.SimpleType_UinT32},
+		}},
+	}
+}
+
 func (p *Advertiser_Proxy) Stop(inH uint32) (err error) {
 	payload := &advertiser_Stop_Params{
 		inH,
@@ -389,6 +538,61 @@
 	return bindings.NewStub(connector, &advertiser_Stub{connector, impl})
 }
 
+var (
+	interfaceName_Advertiser                 = "Advertiser"
+	interfaceMethodName_Advertiser_Advertise = "Advertise"
+	interfaceMethodName_Advertiser_Stop      = "Stop"
+)
+
+func discovery_Advertiser__() mojom_types.MojomInterface {
+	responseParamsMap := make(map[string]*mojom_types.MojomStruct)
+	_ = responseParamsMap // To avoid the declared but unused compiler error
+	mstruct_Advertise := discovery_Advertiser_Advertise_ResponseParams__()
+	responseParamsMap[interfaceMethodName_Advertiser_Advertise] = &mstruct_Advertise
+	return mojom_types.MojomInterface{
+		DeclData: &mojom_types.DeclarationData{
+			ShortName: &interfaceName_Advertiser,
+		},
+		Methods: map[uint32]mojom_types.MojomMethod{advertiser_Advertise_Name: mojom_types.MojomMethod{
+			DeclData: &mojom_types.DeclarationData{
+				ShortName: &interfaceMethodName_Advertiser_Advertise,
+			},
+			Parameters:     discovery_Advertiser_Advertise_Params__(),
+			ResponseParams: responseParamsMap[interfaceMethodName_Advertiser_Advertise],
+		}, advertiser_Stop_Name: mojom_types.MojomMethod{
+			DeclData: &mojom_types.DeclarationData{
+				ShortName: &interfaceMethodName_Advertiser_Stop,
+			},
+			Parameters:     discovery_Advertiser_Stop_Params__(),
+			ResponseParams: responseParamsMap[interfaceMethodName_Advertiser_Stop],
+		}},
+	}
+}
+
+func (f *Advertiser_Request) ServiceDescription() service_describer.ServiceDescription {
+	return &Advertiser_ServiceDescription{}
+}
+
+type Advertiser_ServiceDescription struct{}
+
+func (sd *Advertiser_ServiceDescription) GetTopLevelInterface() (outMojomInterface mojom_types.MojomInterface, err error) {
+	return discovery_Advertiser__(), nil
+}
+
+func (sd *Advertiser_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", "Advertiser", inTypeKey)
+}
+
+func (sd *Advertiser_ServiceDescription) GetAllTypeDefinitions() (outDefinitions *map[string]mojom_types.UserDefinedType, err error) {
+	o := GetAllMojomTypeDefinitions()
+	return &o, nil
+}
+
+var _ service_describer.ServiceDescription = (*Advertiser_ServiceDescription)(nil)
+
 func (s *advertiser_Stub) Accept(message *bindings.Message) (err error) {
 	switch message.Header.Type {
 	case advertiser_Advertise_Name:
@@ -470,6 +674,10 @@
 	return scanner_Name
 }
 
+func (f *Scanner_ServiceFactory) ServiceDescription() service_describer.ServiceDescription {
+	return &Scanner_ServiceDescription{}
+}
+
 func (f *Scanner_ServiceFactory) Create(messagePipe system.MessagePipeHandle) {
 	request := Scanner_Request{bindings.NewMessagePipeHandleOwner(messagePipe)}
 	f.Delegate.Create(request)
@@ -579,6 +787,34 @@
 	return nil
 }
 
+// String names and labels used by the MojomStruct types.
+var (
+	structName_ScannerScanParams                    = "ScannerScanParams"
+	structFieldName_ScannerScanParams_InQuery       = "InQuery"
+	structFieldName_ScannerScanParams_InScanHandler = "InScanHandler"
+)
+
+func discovery_Scanner_Scan_Params__() mojom_types.MojomStruct {
+	return mojom_types.MojomStruct{
+		DeclData: &mojom_types.DeclarationData{
+			ShortName: &structName_ScannerScanParams,
+		}, Fields: []mojom_types.StructField{mojom_types.StructField{
+			DeclData: &mojom_types.DeclarationData{
+				ShortName: &structFieldName_ScannerScanParams_InQuery,
+			},
+			Type: &mojom_types.TypeStringType{mojom_types.StringType{false}},
+		}, mojom_types.StructField{
+			DeclData: &mojom_types.DeclarationData{
+				ShortName: &structFieldName_ScannerScanParams_InScanHandler,
+			},
+			Type: &mojom_types.TypeTypeReference{
+				Value: mojom_types.TypeReference{Identifier: &ID_discovery_ScanHandler__,
+					TypeKey: &ID_discovery_ScanHandler__},
+			},
+		}},
+	}
+}
+
 type scanner_Scan_ResponseParams struct {
 	outHandle uint32
 	outErr    *Error
@@ -655,6 +891,34 @@
 	return nil
 }
 
+// String names and labels used by the MojomStruct types.
+var (
+	structName_ScannerScanResponseParams                = "ScannerScanResponseParams"
+	structFieldName_ScannerScanResponseParams_OutHandle = "OutHandle"
+	structFieldName_ScannerScanResponseParams_OutErr    = "OutErr"
+)
+
+func discovery_Scanner_Scan_ResponseParams__() mojom_types.MojomStruct {
+	return mojom_types.MojomStruct{
+		DeclData: &mojom_types.DeclarationData{
+			ShortName: &structName_ScannerScanResponseParams,
+		}, Fields: []mojom_types.StructField{mojom_types.StructField{
+			DeclData: &mojom_types.DeclarationData{
+				ShortName: &structFieldName_ScannerScanResponseParams_OutHandle,
+			},
+			Type: &mojom_types.TypeSimpleType{mojom_types.SimpleType_UinT32},
+		}, mojom_types.StructField{
+			DeclData: &mojom_types.DeclarationData{
+				ShortName: &structFieldName_ScannerScanResponseParams_OutErr,
+			},
+			Type: &mojom_types.TypeTypeReference{
+				Value: mojom_types.TypeReference{Nullable: true, Identifier: &ID_discovery_Error__,
+					TypeKey: &ID_discovery_Error__},
+			},
+		}},
+	}
+}
+
 func (p *Scanner_Proxy) Scan(inQuery string, inScanHandler ScanHandler_Pointer) (outHandle uint32, outErr *Error, err error) {
 	payload := &scanner_Scan_Params{
 		inQuery,
@@ -749,6 +1013,25 @@
 	return nil
 }
 
+// String names and labels used by the MojomStruct types.
+var (
+	structName_ScannerStopParams          = "ScannerStopParams"
+	structFieldName_ScannerStopParams_InH = "InH"
+)
+
+func discovery_Scanner_Stop_Params__() mojom_types.MojomStruct {
+	return mojom_types.MojomStruct{
+		DeclData: &mojom_types.DeclarationData{
+			ShortName: &structName_ScannerStopParams,
+		}, Fields: []mojom_types.StructField{mojom_types.StructField{
+			DeclData: &mojom_types.DeclarationData{
+				ShortName: &structFieldName_ScannerStopParams_InH,
+			},
+			Type: &mojom_types.TypeSimpleType{mojom_types.SimpleType_UinT32},
+		}},
+	}
+}
+
 func (p *Scanner_Proxy) Stop(inH uint32) (err error) {
 	payload := &scanner_Stop_Params{
 		inH,
@@ -780,6 +1063,61 @@
 	return bindings.NewStub(connector, &scanner_Stub{connector, impl})
 }
 
+var (
+	interfaceName_Scanner            = "Scanner"
+	interfaceMethodName_Scanner_Scan = "Scan"
+	interfaceMethodName_Scanner_Stop = "Stop"
+)
+
+func discovery_Scanner__() mojom_types.MojomInterface {
+	responseParamsMap := make(map[string]*mojom_types.MojomStruct)
+	_ = responseParamsMap // To avoid the declared but unused compiler error
+	mstruct_Scan := discovery_Scanner_Scan_ResponseParams__()
+	responseParamsMap[interfaceMethodName_Scanner_Scan] = &mstruct_Scan
+	return mojom_types.MojomInterface{
+		DeclData: &mojom_types.DeclarationData{
+			ShortName: &interfaceName_Scanner,
+		},
+		Methods: map[uint32]mojom_types.MojomMethod{scanner_Scan_Name: mojom_types.MojomMethod{
+			DeclData: &mojom_types.DeclarationData{
+				ShortName: &interfaceMethodName_Scanner_Scan,
+			},
+			Parameters:     discovery_Scanner_Scan_Params__(),
+			ResponseParams: responseParamsMap[interfaceMethodName_Scanner_Scan],
+		}, scanner_Stop_Name: mojom_types.MojomMethod{
+			DeclData: &mojom_types.DeclarationData{
+				ShortName: &interfaceMethodName_Scanner_Stop,
+			},
+			Parameters:     discovery_Scanner_Stop_Params__(),
+			ResponseParams: responseParamsMap[interfaceMethodName_Scanner_Stop],
+		}},
+	}
+}
+
+func (f *Scanner_Request) ServiceDescription() service_describer.ServiceDescription {
+	return &Scanner_ServiceDescription{}
+}
+
+type Scanner_ServiceDescription struct{}
+
+func (sd *Scanner_ServiceDescription) GetTopLevelInterface() (outMojomInterface mojom_types.MojomInterface, err error) {
+	return discovery_Scanner__(), nil
+}
+
+func (sd *Scanner_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", "Scanner", inTypeKey)
+}
+
+func (sd *Scanner_ServiceDescription) GetAllTypeDefinitions() (outDefinitions *map[string]mojom_types.UserDefinedType, err error) {
+	o := GetAllMojomTypeDefinitions()
+	return &o, nil
+}
+
+var _ service_describer.ServiceDescription = (*Scanner_ServiceDescription)(nil)
+
 func (s *scanner_Stub) Accept(message *bindings.Message) (err error) {
 	switch message.Header.Type {
 	case scanner_Scan_Name:
@@ -861,6 +1199,10 @@
 	return scanHandler_Name
 }
 
+func (f *ScanHandler_ServiceFactory) ServiceDescription() service_describer.ServiceDescription {
+	return &ScanHandler_ServiceDescription{}
+}
+
 func (f *ScanHandler_ServiceFactory) Create(messagePipe system.MessagePipeHandle) {
 	request := ScanHandler_Request{bindings.NewMessagePipeHandleOwner(messagePipe)}
 	f.Delegate.Create(request)
@@ -952,6 +1294,28 @@
 	return nil
 }
 
+// String names and labels used by the MojomStruct types.
+var (
+	structName_ScanHandlerFoundParams          = "ScanHandlerFoundParams"
+	structFieldName_ScanHandlerFoundParams_InS = "InS"
+)
+
+func discovery_ScanHandler_Found_Params__() mojom_types.MojomStruct {
+	return mojom_types.MojomStruct{
+		DeclData: &mojom_types.DeclarationData{
+			ShortName: &structName_ScanHandlerFoundParams,
+		}, Fields: []mojom_types.StructField{mojom_types.StructField{
+			DeclData: &mojom_types.DeclarationData{
+				ShortName: &structFieldName_ScanHandlerFoundParams_InS,
+			},
+			Type: &mojom_types.TypeTypeReference{
+				Value: mojom_types.TypeReference{Identifier: &ID_discovery_Service__,
+					TypeKey: &ID_discovery_Service__},
+			},
+		}},
+	}
+}
+
 func (p *ScanHandler_Proxy) Found(inS Service) (err error) {
 	payload := &scanHandler_Found_Params{
 		inS,
@@ -1051,6 +1415,27 @@
 	return nil
 }
 
+// String names and labels used by the MojomStruct types.
+var (
+	structName_ScanHandlerLostParams                   = "ScanHandlerLostParams"
+	structFieldName_ScanHandlerLostParams_InInstanceId = "InInstanceId"
+)
+
+func discovery_ScanHandler_Lost_Params__() mojom_types.MojomStruct {
+	return mojom_types.MojomStruct{
+		DeclData: &mojom_types.DeclarationData{
+			ShortName: &structName_ScanHandlerLostParams,
+		}, Fields: []mojom_types.StructField{mojom_types.StructField{
+			DeclData: &mojom_types.DeclarationData{
+				ShortName: &structFieldName_ScanHandlerLostParams_InInstanceId,
+			},
+			Type: &mojom_types.TypeArrayType{
+				Value: mojom_types.ArrayType{ElementType: &mojom_types.TypeSimpleType{mojom_types.SimpleType_UinT8}},
+			},
+		}},
+	}
+}
+
 func (p *ScanHandler_Proxy) Lost(inInstanceId []uint8) (err error) {
 	payload := &scanHandler_Lost_Params{
 		inInstanceId,
@@ -1082,6 +1467,59 @@
 	return bindings.NewStub(connector, &scanHandler_Stub{connector, impl})
 }
 
+var (
+	interfaceName_ScanHandler             = "ScanHandler"
+	interfaceMethodName_ScanHandler_Found = "Found"
+	interfaceMethodName_ScanHandler_Lost  = "Lost"
+)
+
+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,
+		},
+		Methods: map[uint32]mojom_types.MojomMethod{scanHandler_Found_Name: mojom_types.MojomMethod{
+			DeclData: &mojom_types.DeclarationData{
+				ShortName: &interfaceMethodName_ScanHandler_Found,
+			},
+			Parameters:     discovery_ScanHandler_Found_Params__(),
+			ResponseParams: responseParamsMap[interfaceMethodName_ScanHandler_Found],
+		}, scanHandler_Lost_Name: mojom_types.MojomMethod{
+			DeclData: &mojom_types.DeclarationData{
+				ShortName: &interfaceMethodName_ScanHandler_Lost,
+			},
+			Parameters:     discovery_ScanHandler_Lost_Params__(),
+			ResponseParams: responseParamsMap[interfaceMethodName_ScanHandler_Lost],
+		}},
+	}
+}
+
+func (f *ScanHandler_Request) ServiceDescription() service_describer.ServiceDescription {
+	return &ScanHandler_ServiceDescription{}
+}
+
+type ScanHandler_ServiceDescription struct{}
+
+func (sd *ScanHandler_ServiceDescription) GetTopLevelInterface() (outMojomInterface mojom_types.MojomInterface, err error) {
+	return discovery_ScanHandler__(), nil
+}
+
+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)
+}
+
+func (sd *ScanHandler_ServiceDescription) GetAllTypeDefinitions() (outDefinitions *map[string]mojom_types.UserDefinedType, err error) {
+	o := GetAllMojomTypeDefinitions()
+	return &o, nil
+}
+
+var _ service_describer.ServiceDescription = (*ScanHandler_ServiceDescription)(nil)
+
 func (s *scanHandler_Stub) Accept(message *bindings.Message) (err error) {
 	switch message.Header.Type {
 	case scanHandler_Found_Name:
@@ -1433,6 +1871,57 @@
 	return nil
 }
 
+// String names and labels used by the MojomStruct types.
+var (
+	structName_Service                    = "Service"
+	structFieldName_Service_InstanceUuid  = "InstanceUuid"
+	structFieldName_Service_InstanceName  = "InstanceName"
+	structFieldName_Service_InterfaceName = "InterfaceName"
+	structFieldName_Service_Attrs         = "Attrs"
+	structFieldName_Service_Addrs         = "Addrs"
+)
+
+func discovery_Service__() mojom_types.MojomStruct {
+	return mojom_types.MojomStruct{
+		DeclData: &mojom_types.DeclarationData{
+			ShortName: &structName_Service,
+		}, Fields: []mojom_types.StructField{mojom_types.StructField{
+			DeclData: &mojom_types.DeclarationData{
+				ShortName: &structFieldName_Service_InstanceUuid,
+			},
+			Type: &mojom_types.TypeArrayType{
+				Value: mojom_types.ArrayType{ElementType: &mojom_types.TypeSimpleType{mojom_types.SimpleType_UinT8}},
+			},
+		}, mojom_types.StructField{
+			DeclData: &mojom_types.DeclarationData{
+				ShortName: &structFieldName_Service_InstanceName,
+			},
+			Type: &mojom_types.TypeStringType{mojom_types.StringType{false}},
+		}, 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{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}}},
+			},
+		}},
+	}
+}
+
 type Error struct {
 	Id     string
 	Action int32
@@ -1527,3 +2016,34 @@
 	}
 	return nil
 }
+
+// String names and labels used by the MojomStruct types.
+var (
+	structName_Error             = "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,
+		}, 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/discovery.go b/go/src/vanadium/discovery/discovery.go
index 62d27d8..a9cd6b8 100644
--- a/go/src/vanadium/discovery/discovery.go
+++ b/go/src/vanadium/discovery/discovery.go
@@ -43,6 +43,10 @@
 	// will be in its own process.
 	ctx, shutdown := v23.Init()
 
+	if len(c.Args() <= 2) {
+		ctx.Fatalf("Not enough arguments passed to discovery.mojo. Given: %v. Pass a name to advertise, followed by 1+ discovery protocols.", c)
+	}
+	// TODO(bjornick): Change this to use the factory to determine which protocols to use.
 	inst, err := discovery_factory.New(c.Args()[2:]...)
 	if err != nil {
 		ctx.Fatalf("failed to initalize discovery: %v", err)
diff --git a/lib/discovery.dart b/lib/discovery.dart
new file mode 100644
index 0000000..ad37fb7
--- /dev/null
+++ b/lib/discovery.dart
@@ -0,0 +1,8 @@
+// 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.
+
+library discovery;
+
+// Export everything from discovery.mojom.
+export 'gen/dart-gen/mojom/lib/discovery/discovery.mojom.dart';
\ No newline at end of file
diff --git a/lib/gen/dart-gen/mojom/lib/discovery/discovery.mojom.dart b/lib/gen/dart-gen/mojom/lib/discovery/discovery.mojom.dart
new file mode 100644
index 0000000..89d46bb
--- /dev/null
+++ b/lib/gen/dart-gen/mojom/lib/discovery/discovery.mojom.dart
@@ -0,0 +1,1466 @@
+// 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.
+
+library discovery_mojom;
+
+import 'dart:async';
+
+import 'package:mojo/bindings.dart' as bindings;
+import 'package:mojo/core.dart' as core;
+
+
+
+class Service extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(48, 0)
+  ];
+  List<int> instanceUuid = null;
+  String instanceName = null;
+  String interfaceName = null;
+  Map<String, String> attrs = null;
+  List<String> addrs = null;
+
+  Service() : super(kVersions.last.size);
+
+  static Service deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    decoder.excessHandles.forEach((h) => h.close());
+    return result;
+  }
+
+  static Service decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    Service result = new Service();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.instanceUuid = decoder0.decodeUint8Array(8, bindings.kNothingNullable, bindings.kUnspecifiedArrayLength);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.instanceName = decoder0.decodeString(16, false);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.interfaceName = decoder0.decodeString(24, false);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(32, false);
+      {
+        decoder1.decodeDataHeaderForMap();
+        List<String> keys0;
+        List<String> 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<String>(si2.numElements);
+            for (int i2 = 0; i2 < si2.numElements; ++i2) {
+              
+              values0[i2] = decoder2.decodeString(bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i2, false);
+            }
+          }
+        }
+        result.attrs = new Map<String, String>.fromIterables(
+            keys0, values0);
+      }
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(40, false);
+      {
+        var si1 = decoder1.decodeDataHeaderForPointerArray(bindings.kUnspecifiedArrayLength);
+        result.addrs = new List<String>(si1.numElements);
+        for (int i1 = 0; i1 < si1.numElements; ++i1) {
+          
+          result.addrs[i1] = decoder1.decodeString(bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i1, false);
+        }
+      }
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeUint8Array(instanceUuid, 8, bindings.kNothingNullable, bindings.kUnspecifiedArrayLength);
+    
+    encoder0.encodeString(instanceName, 16, false);
+    
+    encoder0.encodeString(interfaceName, 24, false);
+    
+    if (attrs == null) {
+      encoder0.encodeNullPointer(32, false);
+    } else {
+      var encoder1 = encoder0.encoderForMap(32);
+      int size0 = attrs.length;
+      var keys0 = attrs.keys.toList();
+      var values0 = attrs.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.encodeString(values0[i1], bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i1, false);
+        }
+      }
+    }
+    
+    if (addrs == null) {
+      encoder0.encodeNullPointer(40, false);
+    } else {
+      var encoder1 = encoder0.encodePointerArray(addrs.length, 40, bindings.kUnspecifiedArrayLength);
+      for (int i0 = 0; i0 < addrs.length; ++i0) {
+        
+        encoder1.encodeString(addrs[i0], bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i0, false);
+      }
+    }
+  }
+
+  String toString() {
+    return "Service("
+           "instanceUuid: $instanceUuid" ", "
+           "instanceName: $instanceName" ", "
+           "interfaceName: $interfaceName" ", "
+           "attrs: $attrs" ", "
+           "addrs: $addrs" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["instanceUuid"] = instanceUuid;
+    map["instanceName"] = instanceName;
+    map["interfaceName"] = interfaceName;
+    map["attrs"] = attrs;
+    map["addrs"] = addrs;
+    return map;
+  }
+}
+
+
+class Error extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(32, 0)
+  ];
+  String id = null;
+  int action = 0;
+  String msg = null;
+
+  Error() : super(kVersions.last.size);
+
+  static Error deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    decoder.excessHandles.forEach((h) => h.close());
+    return result;
+  }
+
+  static Error decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    Error result = new Error();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.id = decoder0.decodeString(8, false);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.action = decoder0.decodeInt32(16);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.msg = decoder0.decodeString(24, false);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeString(id, 8, false);
+    
+    encoder0.encodeInt32(action, 16);
+    
+    encoder0.encodeString(msg, 24, false);
+  }
+
+  String toString() {
+    return "Error("
+           "id: $id" ", "
+           "action: $action" ", "
+           "msg: $msg" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["id"] = id;
+    map["action"] = action;
+    map["msg"] = msg;
+    return map;
+  }
+}
+
+
+class AdvertiserAdvertiseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(24, 0)
+  ];
+  Service s = null;
+  List<String> visibility = null;
+
+  AdvertiserAdvertiseParams() : super(kVersions.last.size);
+
+  static AdvertiserAdvertiseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    decoder.excessHandles.forEach((h) => h.close());
+    return result;
+  }
+
+  static AdvertiserAdvertiseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    AdvertiserAdvertiseParams result = new AdvertiserAdvertiseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(8, false);
+      result.s = Service.decode(decoder1);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(16, false);
+      {
+        var si1 = decoder1.decodeDataHeaderForPointerArray(bindings.kUnspecifiedArrayLength);
+        result.visibility = new List<String>(si1.numElements);
+        for (int i1 = 0; i1 < si1.numElements; ++i1) {
+          
+          result.visibility[i1] = decoder1.decodeString(bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i1, false);
+        }
+      }
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeStruct(s, 8, false);
+    
+    if (visibility == null) {
+      encoder0.encodeNullPointer(16, false);
+    } else {
+      var encoder1 = encoder0.encodePointerArray(visibility.length, 16, bindings.kUnspecifiedArrayLength);
+      for (int i0 = 0; i0 < visibility.length; ++i0) {
+        
+        encoder1.encodeString(visibility[i0], bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i0, false);
+      }
+    }
+  }
+
+  String toString() {
+    return "AdvertiserAdvertiseParams("
+           "s: $s" ", "
+           "visibility: $visibility" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["s"] = s;
+    map["visibility"] = visibility;
+    return map;
+  }
+}
+
+
+class AdvertiserAdvertiseResponseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(24, 0)
+  ];
+  int handle = 0;
+  Error err = null;
+
+  AdvertiserAdvertiseResponseParams() : super(kVersions.last.size);
+
+  static AdvertiserAdvertiseResponseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    decoder.excessHandles.forEach((h) => h.close());
+    return result;
+  }
+
+  static AdvertiserAdvertiseResponseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    AdvertiserAdvertiseResponseParams result = new AdvertiserAdvertiseResponseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.handle = decoder0.decodeUint32(8);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(16, true);
+      result.err = Error.decode(decoder1);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeUint32(handle, 8);
+    
+    encoder0.encodeStruct(err, 16, true);
+  }
+
+  String toString() {
+    return "AdvertiserAdvertiseResponseParams("
+           "handle: $handle" ", "
+           "err: $err" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["handle"] = handle;
+    map["err"] = err;
+    return map;
+  }
+}
+
+
+class AdvertiserStopParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  int h = 0;
+
+  AdvertiserStopParams() : super(kVersions.last.size);
+
+  static AdvertiserStopParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    decoder.excessHandles.forEach((h) => h.close());
+    return result;
+  }
+
+  static AdvertiserStopParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    AdvertiserStopParams result = new AdvertiserStopParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.h = decoder0.decodeUint32(8);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeUint32(h, 8);
+  }
+
+  String toString() {
+    return "AdvertiserStopParams("
+           "h: $h" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["h"] = h;
+    return map;
+  }
+}
+
+
+class ScannerScanParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(24, 0)
+  ];
+  String query = null;
+  Object scanHandler = null;
+
+  ScannerScanParams() : super(kVersions.last.size);
+
+  static ScannerScanParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    decoder.excessHandles.forEach((h) => h.close());
+    return result;
+  }
+
+  static ScannerScanParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    ScannerScanParams result = new ScannerScanParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.query = decoder0.decodeString(8, false);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.scanHandler = decoder0.decodeServiceInterface(16, false, ScanHandlerProxy.newFromEndpoint);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeString(query, 8, false);
+    
+    encoder0.encodeInterface(scanHandler, 16, false);
+  }
+
+  String toString() {
+    return "ScannerScanParams("
+           "query: $query" ", "
+           "scanHandler: $scanHandler" ")";
+  }
+
+  Map toJson() {
+    throw new bindings.MojoCodecError(
+        'Object containing handles cannot be encoded to JSON.');
+  }
+}
+
+
+class ScannerScanResponseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(24, 0)
+  ];
+  int handle = 0;
+  Error err = null;
+
+  ScannerScanResponseParams() : super(kVersions.last.size);
+
+  static ScannerScanResponseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    decoder.excessHandles.forEach((h) => h.close());
+    return result;
+  }
+
+  static ScannerScanResponseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    ScannerScanResponseParams result = new ScannerScanResponseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.handle = decoder0.decodeUint32(8);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(16, true);
+      result.err = Error.decode(decoder1);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeUint32(handle, 8);
+    
+    encoder0.encodeStruct(err, 16, true);
+  }
+
+  String toString() {
+    return "ScannerScanResponseParams("
+           "handle: $handle" ", "
+           "err: $err" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["handle"] = handle;
+    map["err"] = err;
+    return map;
+  }
+}
+
+
+class ScannerStopParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  int h = 0;
+
+  ScannerStopParams() : super(kVersions.last.size);
+
+  static ScannerStopParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    decoder.excessHandles.forEach((h) => h.close());
+    return result;
+  }
+
+  static ScannerStopParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    ScannerStopParams result = new ScannerStopParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.h = decoder0.decodeUint32(8);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeUint32(h, 8);
+  }
+
+  String toString() {
+    return "ScannerStopParams("
+           "h: $h" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["h"] = h;
+    return map;
+  }
+}
+
+
+class ScanHandlerFoundParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  Service s = null;
+
+  ScanHandlerFoundParams() : super(kVersions.last.size);
+
+  static ScanHandlerFoundParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    decoder.excessHandles.forEach((h) => h.close());
+    return result;
+  }
+
+  static ScanHandlerFoundParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    ScanHandlerFoundParams result = new ScanHandlerFoundParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(8, false);
+      result.s = Service.decode(decoder1);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeStruct(s, 8, false);
+  }
+
+  String toString() {
+    return "ScanHandlerFoundParams("
+           "s: $s" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["s"] = s;
+    return map;
+  }
+}
+
+
+class ScanHandlerLostParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  List<int> instanceId = null;
+
+  ScanHandlerLostParams() : super(kVersions.last.size);
+
+  static ScanHandlerLostParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    decoder.excessHandles.forEach((h) => h.close());
+    return result;
+  }
+
+  static ScanHandlerLostParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    ScanHandlerLostParams result = new ScanHandlerLostParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.instanceId = decoder0.decodeUint8Array(8, bindings.kNothingNullable, bindings.kUnspecifiedArrayLength);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeUint8Array(instanceId, 8, bindings.kNothingNullable, bindings.kUnspecifiedArrayLength);
+  }
+
+  String toString() {
+    return "ScanHandlerLostParams("
+           "instanceId: $instanceId" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["instanceId"] = instanceId;
+    return map;
+  }
+}
+
+const int kAdvertiser_advertise_name = 0;
+const int kAdvertiser_stop_name = 1;
+
+const String AdvertiserName =
+      'discovery::Advertiser';
+
+abstract class Advertiser {
+  dynamic advertise(Service s,List<String> visibility,[Function responseFactory = null]);
+  void stop(int h);
+
+}
+
+
+class AdvertiserProxyImpl extends bindings.Proxy {
+  AdvertiserProxyImpl.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) : super.fromEndpoint(endpoint);
+
+  AdvertiserProxyImpl.fromHandle(core.MojoHandle handle) :
+      super.fromHandle(handle);
+
+  AdvertiserProxyImpl.unbound() : super.unbound();
+
+  static AdvertiserProxyImpl newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For AdvertiserProxyImpl"));
+    return new AdvertiserProxyImpl.fromEndpoint(endpoint);
+  }
+
+  String get name => AdvertiserName;
+
+  void handleResponse(bindings.ServiceMessage message) {
+    switch (message.header.type) {
+      case kAdvertiser_advertise_name:
+        var r = AdvertiserAdvertiseResponseParams.deserialize(
+            message.payload);
+        if (!message.header.hasRequestId) {
+          throw 'Expected a message with a valid request Id.';
+        }
+        Completer c = completerMap[message.header.requestId];
+        if (c == null) {
+          throw 'Message had unknown request Id: ${message.header.requestId}';
+        }
+        completerMap.remove(message.header.requestId);
+        assert(!c.isCompleted);
+        c.complete(r);
+        break;
+      default:
+        throw new bindings.MojoCodecError("Unexpected message name");
+        break;
+    }
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "AdvertiserProxyImpl($superString)";
+  }
+}
+
+
+class _AdvertiserProxyCalls implements Advertiser {
+  AdvertiserProxyImpl _proxyImpl;
+
+  _AdvertiserProxyCalls(this._proxyImpl);
+    dynamic advertise(Service s,List<String> visibility,[Function responseFactory = null]) {
+      assert(_proxyImpl.isBound);
+      var params = new AdvertiserAdvertiseParams();
+      params.s = s;
+      params.visibility = visibility;
+      return _proxyImpl.sendMessageWithRequestId(
+          params,
+          kAdvertiser_advertise_name,
+          -1,
+          bindings.MessageHeader.kMessageExpectsResponse);
+    }
+    void stop(int h) {
+      assert(_proxyImpl.isBound);
+      var params = new AdvertiserStopParams();
+      params.h = h;
+      _proxyImpl.sendMessage(params, kAdvertiser_stop_name);
+    }
+  
+}
+
+
+class AdvertiserProxy implements bindings.ProxyBase {
+  final bindings.Proxy impl;
+  Advertiser ptr;
+  final String name = AdvertiserName;
+
+  AdvertiserProxy(AdvertiserProxyImpl proxyImpl) :
+      impl = proxyImpl,
+      ptr = new _AdvertiserProxyCalls(proxyImpl);
+
+  AdvertiserProxy.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) :
+      impl = new AdvertiserProxyImpl.fromEndpoint(endpoint) {
+    ptr = new _AdvertiserProxyCalls(impl);
+  }
+
+  AdvertiserProxy.fromHandle(core.MojoHandle handle) :
+      impl = new AdvertiserProxyImpl.fromHandle(handle) {
+    ptr = new _AdvertiserProxyCalls(impl);
+  }
+
+  AdvertiserProxy.unbound() :
+      impl = new AdvertiserProxyImpl.unbound() {
+    ptr = new _AdvertiserProxyCalls(impl);
+  }
+
+  factory AdvertiserProxy.connectToService(
+      bindings.ServiceConnector s, String url) {
+    AdvertiserProxy p = new AdvertiserProxy.unbound();
+    s.connectToService(url, p);
+    return p;
+  }
+
+  static AdvertiserProxy newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For AdvertiserProxy"));
+    return new AdvertiserProxy.fromEndpoint(endpoint);
+  }
+
+  Future close({bool immediate: false}) => impl.close(immediate: immediate);
+
+  int get version => impl.version;
+
+  Future<int> queryVersion() => impl.queryVersion();
+
+  void requireVersion(int requiredVersion) {
+    impl.requireVersion(requiredVersion);
+  }
+
+  String toString() {
+    return "AdvertiserProxy($impl)";
+  }
+}
+
+
+class AdvertiserStub extends bindings.Stub {
+  Advertiser _impl = null;
+
+  AdvertiserStub.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint, [this._impl])
+      : super.fromEndpoint(endpoint);
+
+  AdvertiserStub.fromHandle(core.MojoHandle handle, [this._impl])
+      : super.fromHandle(handle);
+
+  AdvertiserStub.unbound() : super.unbound();
+
+  static AdvertiserStub newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For AdvertiserStub"));
+    return new AdvertiserStub.fromEndpoint(endpoint);
+  }
+
+  static const String name = AdvertiserName;
+
+
+  AdvertiserAdvertiseResponseParams _AdvertiserAdvertiseResponseParamsFactory(int handle, Error err) {
+    var result = new AdvertiserAdvertiseResponseParams();
+    result.handle = handle;
+    result.err = err;
+    return 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 kAdvertiser_advertise_name:
+        var params = AdvertiserAdvertiseParams.deserialize(
+            message.payload);
+        var response = _impl.advertise(params.s,params.visibility,_AdvertiserAdvertiseResponseParamsFactory);
+        if (response is Future) {
+          return response.then((response) {
+            if (response != null) {
+              return buildResponseWithId(
+                  response,
+                  kAdvertiser_advertise_name,
+                  message.header.requestId,
+                  bindings.MessageHeader.kMessageIsResponse);
+            }
+          });
+        } else if (response != null) {
+          return buildResponseWithId(
+              response,
+              kAdvertiser_advertise_name,
+              message.header.requestId,
+              bindings.MessageHeader.kMessageIsResponse);
+        }
+        break;
+      case kAdvertiser_stop_name:
+        var params = AdvertiserStopParams.deserialize(
+            message.payload);
+        _impl.stop(params.h);
+        break;
+      default:
+        throw new bindings.MojoCodecError("Unexpected message name");
+        break;
+    }
+    return null;
+  }
+
+  Advertiser get impl => _impl;
+  set impl(Advertiser d) {
+    assert(_impl == null);
+    _impl = d;
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "AdvertiserStub($superString)";
+  }
+
+  int get version => 0;
+}
+
+const int kScanner_scan_name = 0;
+const int kScanner_stop_name = 1;
+
+const String ScannerName =
+      'discovery::Scanner';
+
+abstract class Scanner {
+  dynamic scan(String query,Object scanHandler,[Function responseFactory = null]);
+  void stop(int h);
+
+}
+
+
+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);
+  }
+
+  String get name => ScannerName;
+
+  void handleResponse(bindings.ServiceMessage message) {
+    switch (message.header.type) {
+      case kScanner_scan_name:
+        var r = ScannerScanResponseParams.deserialize(
+            message.payload);
+        if (!message.header.hasRequestId) {
+          throw 'Expected a message with a valid request Id.';
+        }
+        Completer c = completerMap[message.header.requestId];
+        if (c == null) {
+          throw 'Message had unknown request Id: ${message.header.requestId}';
+        }
+        completerMap.remove(message.header.requestId);
+        assert(!c.isCompleted);
+        c.complete(r);
+        break;
+      default:
+        throw new bindings.MojoCodecError("Unexpected message name");
+        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]) {
+      assert(_proxyImpl.isBound);
+      var params = new ScannerScanParams();
+      params.query = query;
+      params.scanHandler = scanHandler;
+      return _proxyImpl.sendMessageWithRequestId(
+          params,
+          kScanner_scan_name,
+          -1,
+          bindings.MessageHeader.kMessageExpectsResponse);
+    }
+    void stop(int h) {
+      assert(_proxyImpl.isBound);
+      var params = new ScannerStopParams();
+      params.h = h;
+      _proxyImpl.sendMessage(params, kScanner_stop_name);
+    }
+  
+}
+
+
+class ScannerProxy implements bindings.ProxyBase {
+  final bindings.Proxy impl;
+  Scanner ptr;
+  final String name = ScannerName;
+
+  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) {
+    ScannerProxy p = new ScannerProxy.unbound();
+    s.connectToService(url, p);
+    return p;
+  }
+
+  static ScannerProxy newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For ScannerProxy"));
+    return new ScannerProxy.fromEndpoint(endpoint);
+  }
+
+  Future close({bool immediate: false}) => impl.close(immediate: immediate);
+
+  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);
+  }
+
+  static const String name = ScannerName;
+
+
+  ScannerScanResponseParams _ScannerScanResponseParamsFactory(int handle, Error err) {
+    var result = new ScannerScanResponseParams();
+    result.handle = handle;
+    result.err = err;
+    return 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 kScanner_scan_name:
+        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,
+                  kScanner_scan_name,
+                  message.header.requestId,
+                  bindings.MessageHeader.kMessageIsResponse);
+            }
+          });
+        } else if (response != null) {
+          return buildResponseWithId(
+              response,
+              kScanner_scan_name,
+              message.header.requestId,
+              bindings.MessageHeader.kMessageIsResponse);
+        }
+        break;
+      case kScanner_stop_name:
+        var params = ScannerStopParams.deserialize(
+            message.payload);
+        _impl.stop(params.h);
+        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;
+}
+
+const int kScanHandler_found_name = 0;
+const int kScanHandler_lost_name = 1;
+
+const String ScanHandlerName =
+      'discovery::ScanHandler';
+
+abstract class ScanHandler {
+  void found(Service s);
+  void lost(List<int> instanceId);
+
+}
+
+
+class ScanHandlerProxyImpl extends bindings.Proxy {
+  ScanHandlerProxyImpl.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) : super.fromEndpoint(endpoint);
+
+  ScanHandlerProxyImpl.fromHandle(core.MojoHandle handle) :
+      super.fromHandle(handle);
+
+  ScanHandlerProxyImpl.unbound() : super.unbound();
+
+  static ScanHandlerProxyImpl newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For ScanHandlerProxyImpl"));
+    return new ScanHandlerProxyImpl.fromEndpoint(endpoint);
+  }
+
+  String get name => ScanHandlerName;
+
+  void handleResponse(bindings.ServiceMessage message) {
+    switch (message.header.type) {
+      default:
+        throw new bindings.MojoCodecError("Unexpected message name");
+        break;
+    }
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "ScanHandlerProxyImpl($superString)";
+  }
+}
+
+
+class _ScanHandlerProxyCalls implements ScanHandler {
+  ScanHandlerProxyImpl _proxyImpl;
+
+  _ScanHandlerProxyCalls(this._proxyImpl);
+    void found(Service s) {
+      assert(_proxyImpl.isBound);
+      var params = new ScanHandlerFoundParams();
+      params.s = s;
+      _proxyImpl.sendMessage(params, kScanHandler_found_name);
+    }
+  
+    void lost(List<int> instanceId) {
+      assert(_proxyImpl.isBound);
+      var params = new ScanHandlerLostParams();
+      params.instanceId = instanceId;
+      _proxyImpl.sendMessage(params, kScanHandler_lost_name);
+    }
+  
+}
+
+
+class ScanHandlerProxy implements bindings.ProxyBase {
+  final bindings.Proxy impl;
+  ScanHandler ptr;
+  final String name = ScanHandlerName;
+
+  ScanHandlerProxy(ScanHandlerProxyImpl proxyImpl) :
+      impl = proxyImpl,
+      ptr = new _ScanHandlerProxyCalls(proxyImpl);
+
+  ScanHandlerProxy.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) :
+      impl = new ScanHandlerProxyImpl.fromEndpoint(endpoint) {
+    ptr = new _ScanHandlerProxyCalls(impl);
+  }
+
+  ScanHandlerProxy.fromHandle(core.MojoHandle handle) :
+      impl = new ScanHandlerProxyImpl.fromHandle(handle) {
+    ptr = new _ScanHandlerProxyCalls(impl);
+  }
+
+  ScanHandlerProxy.unbound() :
+      impl = new ScanHandlerProxyImpl.unbound() {
+    ptr = new _ScanHandlerProxyCalls(impl);
+  }
+
+  factory ScanHandlerProxy.connectToService(
+      bindings.ServiceConnector s, String url) {
+    ScanHandlerProxy p = new ScanHandlerProxy.unbound();
+    s.connectToService(url, p);
+    return p;
+  }
+
+  static ScanHandlerProxy newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For ScanHandlerProxy"));
+    return new ScanHandlerProxy.fromEndpoint(endpoint);
+  }
+
+  Future close({bool immediate: false}) => impl.close(immediate: immediate);
+
+  int get version => impl.version;
+
+  Future<int> queryVersion() => impl.queryVersion();
+
+  void requireVersion(int requiredVersion) {
+    impl.requireVersion(requiredVersion);
+  }
+
+  String toString() {
+    return "ScanHandlerProxy($impl)";
+  }
+}
+
+
+class ScanHandlerStub extends bindings.Stub {
+  ScanHandler _impl = null;
+
+  ScanHandlerStub.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint, [this._impl])
+      : super.fromEndpoint(endpoint);
+
+  ScanHandlerStub.fromHandle(core.MojoHandle handle, [this._impl])
+      : super.fromHandle(handle);
+
+  ScanHandlerStub.unbound() : super.unbound();
+
+  static ScanHandlerStub newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For ScanHandlerStub"));
+    return new ScanHandlerStub.fromEndpoint(endpoint);
+  }
+
+  static const String name = ScanHandlerName;
+
+
+
+  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 kScanHandler_found_name:
+        var params = ScanHandlerFoundParams.deserialize(
+            message.payload);
+        _impl.found(params.s);
+        break;
+      case kScanHandler_lost_name:
+        var params = ScanHandlerLostParams.deserialize(
+            message.payload);
+        _impl.lost(params.instanceId);
+        break;
+      default:
+        throw new bindings.MojoCodecError("Unexpected message name");
+        break;
+    }
+    return null;
+  }
+
+  ScanHandler get impl => _impl;
+  set impl(ScanHandler d) {
+    assert(_impl == null);
+    _impl = d;
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "ScanHandlerStub($superString)";
+  }
+
+  int get version => 0;
+}
+
+
diff --git a/mojom/vanadium/discovery.mojom b/mojom/vanadium/discovery.mojom
index 884d129..b5c960c 100644
--- a/mojom/vanadium/discovery.mojom
+++ b/mojom/vanadium/discovery.mojom
@@ -43,7 +43,7 @@
 
 // Scanner provides methods to scan for Vanadium advertisements.
 interface Scanner {
-	// Scan scans for services matching the query passed nad calls ScanHandler with updates.
+	// Scan scans for services matching the query passed and calls ScanHandler with updates.
 	// Returns a handle to the active scanner that can be used to stop the scanning.
 	Scan(string query, ScanHandler scanHandler) => (uint32 Handle, Error? Err);
 
diff --git a/pubspec.yaml b/pubspec.yaml
new file mode 100644
index 0000000..7ff04d8
--- /dev/null
+++ b/pubspec.yaml
@@ -0,0 +1,12 @@
+author: Vanadium Authors
+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: discovery
+version: 0.0.1
+dependencies:
+  mojo: '>=0.3.0 <0.4.0'
+dev_dependencies:
+  dart_style: any
+  test: any
+environment:
+  sdk: '>=1.12.0 <2.0.0'
\ No newline at end of file
