diff --git a/.gitignore b/.gitignore
index c2296ef..d1b26e4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
 /.jiri
 #TODO(nlacasse): Get rid of .v23 below once v23->jiri transition is complete.
-/.v23
\ No newline at end of file
+/.v23
+gen
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..c54ae5c
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,50 @@
+include ../shared/mojo.mk
+V23_GO_FILES := $(shell find $(JIRI_ROOT) -name "*.go")
+
+
+ifdef ANDROID
+	DISCOVERY_BUILD_DIR := $(PWD)/gen/mojo/android
+else
+	DISCOVERY_BUILD_DIR := $(PWD)/gen/mojo/linux_amd64
+endif
+
+MOJO_SHELL_FLAGS := $(MOJO_SHELL_FLAGS) \
+	--config-alias DISCOVERY_DIR=$(PWD) \
+	--config-alias DISCOVERY_BUILD_DIR=$(DISCOVERY_BUILD_DIR)
+
+define CGO_TEST
+	GOPATH="$(GOPATH)" \
+	CGO_CFLAGS="-I$(MOJO_DIR)/src $(CGO_CFLAGS)" \
+	CGO_CXXFLAGS="-I$(MOJO_DIR)/src $(CGO_CXXFLAGS)" \
+	CGO_LDFLAGS="-L$(dir $(MOJO_SHARED_LIB)) -lsystem_thunk $(CGO_LDFLAGS)" \
+	$(GOROOT)/bin/go test -v $1
+
+endef
+all: $(DISCOVERY_BUILD_DIR)/discovery.mojo
+
+
+go/src/mojom/vanadium/discovery/discovery.mojom.go: mojom/vanadium/discovery.mojom | mojo-env-check
+	$(call MOJOM_GEN,$<,.,go)
+	gofmt -w $@
+
+
+$(DISCOVERY_BUILD_DIR)/discovery.mojo: $(V23_GO_FILES) $(MOJO_SHARED_LIB) go/src/mojom/vanadium/discovery/discovery.mojom.go | 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
+	$(call MOGO_BUILD,examples/advertiser,$@)
+
+$(DISCOVERY_BUILD_DIR)/scanner.mojo: $(V23_GO_FILES) $(MOJO_SHARED_LIB) go/src/mojom/vanadium/discovery/discovery.mojom.go | mojo-env-check
+	$(call MOGO_BUILD,examples/scanner,$@)
+
+discovery_test: $(V23_GO_FILES) $(MOJO_SHARED_LIB) go/src/mojom/vanadium/discovery/discovery.mojom.go | mojo-env-check
+	echo $(GOPATH)
+	$(call CGO_TEST,vanadium/discovery/internal)
+
+run-advertiser: $(DISCOVERY_BUILD_DIR)/advertiser.mojo $(DISCOVERY_BUILD_DIR)/discovery.mojo
+	sudo $(MOJO_DIR)/src/mojo/devtools/common/mojo_run --config-file $(PWD)/mojoconfig $(MOJO_SHELL_FLAGS) $(MOJO_ANDROID_FLAGS) https://mojo.v.io/advertiser.mojo \
+	--args-for="https://mojo.v.io/discovery.mojo host1 ble mdns"
+
+run-scanner: $(DISCOVERY_BUILD_DIR)/scanner.mojo $(DISCOVERY_BUILD_DIR)/discovery.mojo
+	sudo $(MOJO_DIR)/src/mojo/devtools/common/mojo_run --config-file $(PWD)/mojoconfig $(MOJO_SHELL_FLAGS) $(MOJO_ANDROID_FLAGS) https://mojo.v.io/scanner.mojo \
+	--args-for="https://mojo.v.io/discovery.mojo host2 ble mdns"
\ No newline at end of file
diff --git a/go/src/examples/advertiser/advertiser.go b/go/src/examples/advertiser/advertiser.go
new file mode 100644
index 0000000..f428fae
--- /dev/null
+++ b/go/src/examples/advertiser/advertiser.go
@@ -0,0 +1,58 @@
+// 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 main
+
+import (
+	"log"
+
+	"mojo/public/go/application"
+	"mojo/public/go/bindings"
+	"mojo/public/go/system"
+
+	"mojom/vanadium/discovery"
+)
+
+//#include "mojo/public/c/system/types.h"
+import "C"
+
+type advDelegate struct {
+	id    uint32
+	proxy *discovery.Advertiser_Proxy
+}
+
+func (a *advDelegate) Initialize(ctx application.Context) {
+	req, ptr := discovery.CreateMessagePipeForAdvertiser()
+	ctx.ConnectToApplication("https://mojo.v.io/discovery.mojo").ConnectToService(&req)
+	a.proxy = discovery.NewAdvertiserProxy(ptr, bindings.GetAsyncWaiter())
+	s := discovery.Service{
+		InterfaceName: "v.io/discovery.T",
+		Addrs:         []string{"localhost:1000", "localhost:2000"},
+		Attrs:         map[string]string{"foo": "bar"},
+	}
+	id, e1, e2 := a.proxy.Advertise(s, nil)
+	if e1 != nil || e2 != nil {
+		log.Println("Error occurred", e1, e2)
+		return
+	}
+
+	a.id = id
+}
+
+func (*advDelegate) AcceptConnection(connection *application.Connection) {
+	connection.Close()
+}
+
+func (s *advDelegate) Quit() {
+	s.proxy.Stop(s.id)
+}
+
+//export MojoMain
+func MojoMain(handle C.MojoHandle) C.MojoResult {
+	application.Run(&advDelegate{}, system.MojoHandle(handle))
+	return C.MOJO_RESULT_OK
+}
+
+func main() {
+}
diff --git a/go/src/examples/scanner/scanner.go b/go/src/examples/scanner/scanner.go
new file mode 100644
index 0000000..1fded60
--- /dev/null
+++ b/go/src/examples/scanner/scanner.go
@@ -0,0 +1,80 @@
+// 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 main
+
+import (
+	"log"
+
+	"mojo/public/go/application"
+	"mojo/public/go/bindings"
+	"mojo/public/go/system"
+
+	"mojom/vanadium/discovery"
+)
+
+//#include "mojo/public/c/system/types.h"
+import "C"
+
+type handler struct{}
+
+func (*handler) Found(s discovery.Service) error {
+	log.Println("Found a new service", s)
+	return nil
+}
+
+func (*handler) Lost(s []uint8) error {
+	log.Println("Lost a new service", s)
+	return nil
+}
+
+type scannerDelegate struct {
+	id    uint32
+	proxy *discovery.Scanner_Proxy
+	stub  *bindings.Stub
+}
+
+func (s *scannerDelegate) Initialize(ctx application.Context) {
+	req, ptr := discovery.CreateMessagePipeForScanner()
+	ctx.ConnectToApplication("https://mojo.v.io/discovery.mojo").ConnectToService(&req)
+	s.proxy = discovery.NewScannerProxy(ptr, bindings.GetAsyncWaiter())
+	scanReq, scanPtr := discovery.CreateMessagePipeForScanHandler()
+	s.stub = discovery.NewScanHandlerStub(scanReq, &handler{}, bindings.GetAsyncWaiter())
+	id, e1, e2 := s.proxy.Scan("v.io/discovery.T", scanPtr)
+	if e1 != nil || e2 != nil {
+		log.Println("Error occurred", e1, e2)
+		return
+	}
+
+	s.id = id
+	go func() {
+		for {
+			if err := s.stub.ServeRequest(); err != nil {
+				connectionError, ok := err.(*bindings.ConnectionError)
+				if !ok || !connectionError.Closed() {
+					log.Println(err)
+				}
+				break
+			}
+		}
+	}()
+}
+
+func (*scannerDelegate) AcceptConnection(connection *application.Connection) {
+	connection.Close()
+}
+
+func (s *scannerDelegate) Quit() {
+	s.proxy.Stop(s.id)
+	s.stub.Close()
+}
+
+//export MojoMain
+func MojoMain(handle C.MojoHandle) C.MojoResult {
+	application.Run(&scannerDelegate{}, system.MojoHandle(handle))
+	return C.MOJO_RESULT_OK
+}
+
+func main() {
+}
diff --git a/go/src/mojom/vanadium/discovery/discovery.mojom.go b/go/src/mojom/vanadium/discovery/discovery.mojom.go
new file mode 100644
index 0000000..c2147c0
--- /dev/null
+++ b/go/src/mojom/vanadium/discovery/discovery.mojom.go
@@ -0,0 +1,1507 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file is autogenerated by:
+//     mojo/public/tools/bindings/mojom_bindings_generator.py
+// For:
+//     mojom/vanadium/discovery.mojom
+//
+
+package discovery
+
+import (
+	"fmt"
+	"mojo/public/go/bindings"
+	"mojo/public/go/system"
+	"sort"
+)
+
+type Advertiser interface {
+	Advertise(inS Service, inVisibility []string) (outHandle uint32, outErr *Error, err error)
+	Stop(inH uint32) (err error)
+}
+
+var advertiser_Name = "discovery::Advertiser"
+
+type Advertiser_Request bindings.InterfaceRequest
+
+func (r *Advertiser_Request) Name() string {
+	return advertiser_Name
+}
+
+type Advertiser_Pointer bindings.InterfacePointer
+
+func (p *Advertiser_Pointer) Name() string {
+	return advertiser_Name
+}
+
+type Advertiser_ServiceFactory struct {
+	Delegate Advertiser_Factory
+}
+
+type Advertiser_Factory interface {
+	Create(request Advertiser_Request)
+}
+
+func (f *Advertiser_ServiceFactory) Name() string {
+	return advertiser_Name
+}
+
+func (f *Advertiser_ServiceFactory) Create(messagePipe system.MessagePipeHandle) {
+	request := Advertiser_Request{bindings.NewMessagePipeHandleOwner(messagePipe)}
+	f.Delegate.Create(request)
+}
+
+// CreateMessagePipeForAdvertiser creates a message pipe for use with the
+// Advertiser interface with a Advertiser_Request on one end and a Advertiser_Pointer on the other.
+func CreateMessagePipeForAdvertiser() (Advertiser_Request, Advertiser_Pointer) {
+	r, p := bindings.CreateMessagePipeForMojoInterface()
+	return Advertiser_Request(r), Advertiser_Pointer(p)
+}
+
+const advertiser_Advertise_Name uint32 = 0
+const advertiser_Stop_Name uint32 = 1
+
+type Advertiser_Proxy struct {
+	router *bindings.Router
+	ids    bindings.Counter
+}
+
+func NewAdvertiserProxy(p Advertiser_Pointer, waiter bindings.AsyncWaiter) *Advertiser_Proxy {
+	return &Advertiser_Proxy{
+		bindings.NewRouter(p.PassMessagePipe(), waiter),
+		bindings.NewCounter(),
+	}
+}
+
+func (p *Advertiser_Proxy) Close_Proxy() {
+	p.router.Close()
+}
+
+type advertiser_Advertise_Params struct {
+	inS          Service
+	inVisibility []string
+}
+
+func (s *advertiser_Advertise_Params) Encode(encoder *bindings.Encoder) error {
+	encoder.StartStruct(16, 0)
+	if err := encoder.WritePointer(); err != nil {
+		return err
+	}
+	if err := s.inS.Encode(encoder); err != nil {
+		return err
+	}
+	if err := encoder.WritePointer(); err != nil {
+		return err
+	}
+	encoder.StartArray(uint32(len(s.inVisibility)), 64)
+	for _, elem0 := range s.inVisibility {
+		if err := encoder.WritePointer(); err != nil {
+			return err
+		}
+		if err := encoder.WriteString(elem0); err != nil {
+			return err
+		}
+	}
+	if err := encoder.Finish(); err != nil {
+		return err
+	}
+	if err := encoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+var advertiser_Advertise_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
+	bindings.DataHeader{24, 0},
+}
+
+func (s *advertiser_Advertise_Params) Decode(decoder *bindings.Decoder) error {
+	header, err := decoder.StartStruct()
+	if err != nil {
+		return err
+	}
+	index := sort.Search(len(advertiser_Advertise_Params_Versions), func(i int) bool {
+		return advertiser_Advertise_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
+	})
+	if index < len(advertiser_Advertise_Params_Versions) {
+		if advertiser_Advertise_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
+			index--
+		}
+		expectedSize := advertiser_Advertise_Params_Versions[index].Size
+		if expectedSize != header.Size {
+			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
+				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
+			}
+		}
+	}
+	if header.ElementsOrVersion >= 0 {
+		pointer0, err := decoder.ReadPointer()
+		if err != nil {
+			return err
+		}
+		if pointer0 == 0 {
+			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
+		} else {
+			if err := s.inS.Decode(decoder); err != nil {
+				return err
+			}
+		}
+	}
+	if header.ElementsOrVersion >= 0 {
+		pointer0, err := decoder.ReadPointer()
+		if err != nil {
+			return err
+		}
+		if pointer0 == 0 {
+			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
+		} else {
+			len0, err := decoder.StartArray(64)
+			if err != nil {
+				return err
+			}
+			s.inVisibility = make([]string, len0)
+			for i0 := uint32(0); i0 < len0; i0++ {
+				pointer1, err := decoder.ReadPointer()
+				if err != nil {
+					return err
+				}
+				if pointer1 == 0 {
+					return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
+				} else {
+					value1, err := decoder.ReadString()
+					if err != nil {
+						return err
+					}
+					s.inVisibility[i0] = value1
+				}
+			}
+			if err := decoder.Finish(); err != nil {
+				return err
+			}
+		}
+	}
+	if err := decoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+type advertiser_Advertise_ResponseParams struct {
+	outHandle uint32
+	outErr    *Error
+}
+
+func (s *advertiser_Advertise_ResponseParams) Encode(encoder *bindings.Encoder) error {
+	encoder.StartStruct(16, 0)
+	if err := encoder.WriteUint32(s.outHandle); err != nil {
+		return err
+	}
+	if s.outErr == nil {
+		encoder.WriteNullPointer()
+	} else {
+		if err := encoder.WritePointer(); err != nil {
+			return err
+		}
+		if err := (*s.outErr).Encode(encoder); err != nil {
+			return err
+		}
+	}
+	if err := encoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+var advertiser_Advertise_ResponseParams_Versions []bindings.DataHeader = []bindings.DataHeader{
+	bindings.DataHeader{24, 0},
+}
+
+func (s *advertiser_Advertise_ResponseParams) Decode(decoder *bindings.Decoder) error {
+	header, err := decoder.StartStruct()
+	if err != nil {
+		return err
+	}
+	index := sort.Search(len(advertiser_Advertise_ResponseParams_Versions), func(i int) bool {
+		return advertiser_Advertise_ResponseParams_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
+	})
+	if index < len(advertiser_Advertise_ResponseParams_Versions) {
+		if advertiser_Advertise_ResponseParams_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
+			index--
+		}
+		expectedSize := advertiser_Advertise_ResponseParams_Versions[index].Size
+		if expectedSize != header.Size {
+			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
+				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
+			}
+		}
+	}
+	if header.ElementsOrVersion >= 0 {
+		value0, err := decoder.ReadUint32()
+		if err != nil {
+			return err
+		}
+		s.outHandle = value0
+	}
+	if header.ElementsOrVersion >= 0 {
+		pointer0, err := decoder.ReadPointer()
+		if err != nil {
+			return err
+		}
+		if pointer0 == 0 {
+			s.outErr = nil
+		} else {
+			s.outErr = new(Error)
+			if err := (*s.outErr).Decode(decoder); err != nil {
+				return err
+			}
+		}
+	}
+	if err := decoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (p *Advertiser_Proxy) Advertise(inS Service, inVisibility []string) (outHandle uint32, outErr *Error, err error) {
+	payload := &advertiser_Advertise_Params{
+		inS,
+		inVisibility,
+	}
+	header := bindings.MessageHeader{
+		Type:      advertiser_Advertise_Name,
+		Flags:     bindings.MessageExpectsResponseFlag,
+		RequestId: p.ids.Count(),
+	}
+	var message *bindings.Message
+	if message, err = bindings.EncodeMessage(header, payload); err != nil {
+		err = fmt.Errorf("can't encode request: %v", err.Error())
+		p.Close_Proxy()
+		return
+	}
+	readResult := <-p.router.AcceptWithResponse(message)
+	if err = readResult.Error; err != nil {
+		p.Close_Proxy()
+		return
+	}
+	if readResult.Message.Header.Flags != bindings.MessageIsResponseFlag {
+		err = &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
+			fmt.Sprintf("invalid message header flag: %v", readResult.Message.Header.Flags),
+		}
+		return
+	}
+	if got, want := readResult.Message.Header.Type, advertiser_Advertise_Name; got != want {
+		err = &bindings.ValidationError{bindings.MessageHeaderUnknownMethod,
+			fmt.Sprintf("invalid method in response: expected %v, got %v", want, got),
+		}
+		return
+	}
+	var response advertiser_Advertise_ResponseParams
+	if err = readResult.Message.DecodePayload(&response); err != nil {
+		p.Close_Proxy()
+		return
+	}
+	outHandle = response.outHandle
+	outErr = response.outErr
+	return
+}
+
+type advertiser_Stop_Params struct {
+	inH uint32
+}
+
+func (s *advertiser_Stop_Params) Encode(encoder *bindings.Encoder) error {
+	encoder.StartStruct(8, 0)
+	if err := encoder.WriteUint32(s.inH); err != nil {
+		return err
+	}
+	if err := encoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+var advertiser_Stop_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
+	bindings.DataHeader{16, 0},
+}
+
+func (s *advertiser_Stop_Params) Decode(decoder *bindings.Decoder) error {
+	header, err := decoder.StartStruct()
+	if err != nil {
+		return err
+	}
+	index := sort.Search(len(advertiser_Stop_Params_Versions), func(i int) bool {
+		return advertiser_Stop_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
+	})
+	if index < len(advertiser_Stop_Params_Versions) {
+		if advertiser_Stop_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
+			index--
+		}
+		expectedSize := advertiser_Stop_Params_Versions[index].Size
+		if expectedSize != header.Size {
+			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
+				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
+			}
+		}
+	}
+	if header.ElementsOrVersion >= 0 {
+		value0, err := decoder.ReadUint32()
+		if err != nil {
+			return err
+		}
+		s.inH = value0
+	}
+	if err := decoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (p *Advertiser_Proxy) Stop(inH uint32) (err error) {
+	payload := &advertiser_Stop_Params{
+		inH,
+	}
+	header := bindings.MessageHeader{
+		Type:  advertiser_Stop_Name,
+		Flags: bindings.MessageNoFlag,
+	}
+	var message *bindings.Message
+	if message, err = bindings.EncodeMessage(header, payload); err != nil {
+		err = fmt.Errorf("can't encode request: %v", err.Error())
+		p.Close_Proxy()
+		return
+	}
+	if err = p.router.Accept(message); err != nil {
+		p.Close_Proxy()
+		return
+	}
+	return
+}
+
+type advertiser_Stub struct {
+	connector *bindings.Connector
+	impl      Advertiser
+}
+
+func NewAdvertiserStub(r Advertiser_Request, impl Advertiser, waiter bindings.AsyncWaiter) *bindings.Stub {
+	connector := bindings.NewConnector(r.PassMessagePipe(), waiter)
+	return bindings.NewStub(connector, &advertiser_Stub{connector, impl})
+}
+
+func (s *advertiser_Stub) Accept(message *bindings.Message) (err error) {
+	switch message.Header.Type {
+	case advertiser_Advertise_Name:
+		if message.Header.Flags != bindings.MessageExpectsResponseFlag {
+			return &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
+				fmt.Sprintf("invalid message header flag: %v", message.Header.Flags),
+			}
+		}
+		var request advertiser_Advertise_Params
+		if err := message.DecodePayload(&request); err != nil {
+			return err
+		}
+		var response advertiser_Advertise_ResponseParams
+		response.outHandle, response.outErr, err = s.impl.Advertise(request.inS, request.inVisibility)
+		if err != nil {
+			return
+		}
+		header := bindings.MessageHeader{
+			Type:      advertiser_Advertise_Name,
+			Flags:     bindings.MessageIsResponseFlag,
+			RequestId: message.Header.RequestId,
+		}
+		message, err = bindings.EncodeMessage(header, &response)
+		if err != nil {
+			return err
+		}
+		return s.connector.WriteMessage(message)
+	case advertiser_Stop_Name:
+		if message.Header.Flags != bindings.MessageNoFlag {
+			return &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
+				fmt.Sprintf("invalid message header flag: %v", message.Header.Flags),
+			}
+		}
+		var request advertiser_Stop_Params
+		if err := message.DecodePayload(&request); err != nil {
+			return err
+		}
+		err = s.impl.Stop(request.inH)
+		if err != nil {
+			return
+		}
+	default:
+		return &bindings.ValidationError{
+			bindings.MessageHeaderUnknownMethod,
+			fmt.Sprintf("unknown method %v", message.Header.Type),
+		}
+	}
+	return
+}
+
+type Scanner interface {
+	Scan(inQuery string, inScanHandler ScanHandler_Pointer) (outHandle uint32, outErr *Error, err error)
+	Stop(inH uint32) (err error)
+}
+
+var scanner_Name = "discovery::Scanner"
+
+type Scanner_Request bindings.InterfaceRequest
+
+func (r *Scanner_Request) Name() string {
+	return scanner_Name
+}
+
+type Scanner_Pointer bindings.InterfacePointer
+
+func (p *Scanner_Pointer) Name() string {
+	return scanner_Name
+}
+
+type Scanner_ServiceFactory struct {
+	Delegate Scanner_Factory
+}
+
+type Scanner_Factory interface {
+	Create(request Scanner_Request)
+}
+
+func (f *Scanner_ServiceFactory) Name() string {
+	return scanner_Name
+}
+
+func (f *Scanner_ServiceFactory) Create(messagePipe system.MessagePipeHandle) {
+	request := Scanner_Request{bindings.NewMessagePipeHandleOwner(messagePipe)}
+	f.Delegate.Create(request)
+}
+
+// CreateMessagePipeForScanner creates a message pipe for use with the
+// Scanner interface with a Scanner_Request on one end and a Scanner_Pointer on the other.
+func CreateMessagePipeForScanner() (Scanner_Request, Scanner_Pointer) {
+	r, p := bindings.CreateMessagePipeForMojoInterface()
+	return Scanner_Request(r), Scanner_Pointer(p)
+}
+
+const scanner_Scan_Name uint32 = 0
+const scanner_Stop_Name uint32 = 1
+
+type Scanner_Proxy struct {
+	router *bindings.Router
+	ids    bindings.Counter
+}
+
+func NewScannerProxy(p Scanner_Pointer, waiter bindings.AsyncWaiter) *Scanner_Proxy {
+	return &Scanner_Proxy{
+		bindings.NewRouter(p.PassMessagePipe(), waiter),
+		bindings.NewCounter(),
+	}
+}
+
+func (p *Scanner_Proxy) Close_Proxy() {
+	p.router.Close()
+}
+
+type scanner_Scan_Params struct {
+	inQuery       string
+	inScanHandler ScanHandler_Pointer
+}
+
+func (s *scanner_Scan_Params) Encode(encoder *bindings.Encoder) error {
+	encoder.StartStruct(16, 0)
+	if err := encoder.WritePointer(); err != nil {
+		return err
+	}
+	if err := encoder.WriteString(s.inQuery); err != nil {
+		return err
+	}
+	if err := encoder.WriteInterface(s.inScanHandler.PassMessagePipe()); err != nil {
+		return err
+	}
+	if err := encoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+var scanner_Scan_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
+	bindings.DataHeader{24, 0},
+}
+
+func (s *scanner_Scan_Params) Decode(decoder *bindings.Decoder) error {
+	header, err := decoder.StartStruct()
+	if err != nil {
+		return err
+	}
+	index := sort.Search(len(scanner_Scan_Params_Versions), func(i int) bool {
+		return scanner_Scan_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
+	})
+	if index < len(scanner_Scan_Params_Versions) {
+		if scanner_Scan_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
+			index--
+		}
+		expectedSize := scanner_Scan_Params_Versions[index].Size
+		if expectedSize != header.Size {
+			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
+				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
+			}
+		}
+	}
+	if header.ElementsOrVersion >= 0 {
+		pointer0, err := decoder.ReadPointer()
+		if err != nil {
+			return err
+		}
+		if pointer0 == 0 {
+			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
+		} else {
+			value0, err := decoder.ReadString()
+			if err != nil {
+				return err
+			}
+			s.inQuery = value0
+		}
+	}
+	if header.ElementsOrVersion >= 0 {
+		handle0, err := decoder.ReadInterface()
+		if err != nil {
+			return err
+		}
+		if handle0.IsValid() {
+			handleOwner := bindings.NewMessagePipeHandleOwner(handle0)
+			s.inScanHandler = ScanHandler_Pointer{handleOwner}
+		} else {
+			return &bindings.ValidationError{bindings.UnexpectedInvalidHandle, "unexpected invalid handle"}
+		}
+	}
+	if err := decoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+type scanner_Scan_ResponseParams struct {
+	outHandle uint32
+	outErr    *Error
+}
+
+func (s *scanner_Scan_ResponseParams) Encode(encoder *bindings.Encoder) error {
+	encoder.StartStruct(16, 0)
+	if err := encoder.WriteUint32(s.outHandle); err != nil {
+		return err
+	}
+	if s.outErr == nil {
+		encoder.WriteNullPointer()
+	} else {
+		if err := encoder.WritePointer(); err != nil {
+			return err
+		}
+		if err := (*s.outErr).Encode(encoder); err != nil {
+			return err
+		}
+	}
+	if err := encoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+var scanner_Scan_ResponseParams_Versions []bindings.DataHeader = []bindings.DataHeader{
+	bindings.DataHeader{24, 0},
+}
+
+func (s *scanner_Scan_ResponseParams) Decode(decoder *bindings.Decoder) error {
+	header, err := decoder.StartStruct()
+	if err != nil {
+		return err
+	}
+	index := sort.Search(len(scanner_Scan_ResponseParams_Versions), func(i int) bool {
+		return scanner_Scan_ResponseParams_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
+	})
+	if index < len(scanner_Scan_ResponseParams_Versions) {
+		if scanner_Scan_ResponseParams_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
+			index--
+		}
+		expectedSize := scanner_Scan_ResponseParams_Versions[index].Size
+		if expectedSize != header.Size {
+			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
+				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
+			}
+		}
+	}
+	if header.ElementsOrVersion >= 0 {
+		value0, err := decoder.ReadUint32()
+		if err != nil {
+			return err
+		}
+		s.outHandle = value0
+	}
+	if header.ElementsOrVersion >= 0 {
+		pointer0, err := decoder.ReadPointer()
+		if err != nil {
+			return err
+		}
+		if pointer0 == 0 {
+			s.outErr = nil
+		} else {
+			s.outErr = new(Error)
+			if err := (*s.outErr).Decode(decoder); err != nil {
+				return err
+			}
+		}
+	}
+	if err := decoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (p *Scanner_Proxy) Scan(inQuery string, inScanHandler ScanHandler_Pointer) (outHandle uint32, outErr *Error, err error) {
+	payload := &scanner_Scan_Params{
+		inQuery,
+		inScanHandler,
+	}
+	header := bindings.MessageHeader{
+		Type:      scanner_Scan_Name,
+		Flags:     bindings.MessageExpectsResponseFlag,
+		RequestId: p.ids.Count(),
+	}
+	var message *bindings.Message
+	if message, err = bindings.EncodeMessage(header, payload); err != nil {
+		err = fmt.Errorf("can't encode request: %v", err.Error())
+		p.Close_Proxy()
+		return
+	}
+	readResult := <-p.router.AcceptWithResponse(message)
+	if err = readResult.Error; err != nil {
+		p.Close_Proxy()
+		return
+	}
+	if readResult.Message.Header.Flags != bindings.MessageIsResponseFlag {
+		err = &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
+			fmt.Sprintf("invalid message header flag: %v", readResult.Message.Header.Flags),
+		}
+		return
+	}
+	if got, want := readResult.Message.Header.Type, scanner_Scan_Name; got != want {
+		err = &bindings.ValidationError{bindings.MessageHeaderUnknownMethod,
+			fmt.Sprintf("invalid method in response: expected %v, got %v", want, got),
+		}
+		return
+	}
+	var response scanner_Scan_ResponseParams
+	if err = readResult.Message.DecodePayload(&response); err != nil {
+		p.Close_Proxy()
+		return
+	}
+	outHandle = response.outHandle
+	outErr = response.outErr
+	return
+}
+
+type scanner_Stop_Params struct {
+	inH uint32
+}
+
+func (s *scanner_Stop_Params) Encode(encoder *bindings.Encoder) error {
+	encoder.StartStruct(8, 0)
+	if err := encoder.WriteUint32(s.inH); err != nil {
+		return err
+	}
+	if err := encoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+var scanner_Stop_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
+	bindings.DataHeader{16, 0},
+}
+
+func (s *scanner_Stop_Params) Decode(decoder *bindings.Decoder) error {
+	header, err := decoder.StartStruct()
+	if err != nil {
+		return err
+	}
+	index := sort.Search(len(scanner_Stop_Params_Versions), func(i int) bool {
+		return scanner_Stop_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
+	})
+	if index < len(scanner_Stop_Params_Versions) {
+		if scanner_Stop_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
+			index--
+		}
+		expectedSize := scanner_Stop_Params_Versions[index].Size
+		if expectedSize != header.Size {
+			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
+				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
+			}
+		}
+	}
+	if header.ElementsOrVersion >= 0 {
+		value0, err := decoder.ReadUint32()
+		if err != nil {
+			return err
+		}
+		s.inH = value0
+	}
+	if err := decoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (p *Scanner_Proxy) Stop(inH uint32) (err error) {
+	payload := &scanner_Stop_Params{
+		inH,
+	}
+	header := bindings.MessageHeader{
+		Type:  scanner_Stop_Name,
+		Flags: bindings.MessageNoFlag,
+	}
+	var message *bindings.Message
+	if message, err = bindings.EncodeMessage(header, payload); err != nil {
+		err = fmt.Errorf("can't encode request: %v", err.Error())
+		p.Close_Proxy()
+		return
+	}
+	if err = p.router.Accept(message); err != nil {
+		p.Close_Proxy()
+		return
+	}
+	return
+}
+
+type scanner_Stub struct {
+	connector *bindings.Connector
+	impl      Scanner
+}
+
+func NewScannerStub(r Scanner_Request, impl Scanner, waiter bindings.AsyncWaiter) *bindings.Stub {
+	connector := bindings.NewConnector(r.PassMessagePipe(), waiter)
+	return bindings.NewStub(connector, &scanner_Stub{connector, impl})
+}
+
+func (s *scanner_Stub) Accept(message *bindings.Message) (err error) {
+	switch message.Header.Type {
+	case scanner_Scan_Name:
+		if message.Header.Flags != bindings.MessageExpectsResponseFlag {
+			return &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
+				fmt.Sprintf("invalid message header flag: %v", message.Header.Flags),
+			}
+		}
+		var request scanner_Scan_Params
+		if err := message.DecodePayload(&request); err != nil {
+			return err
+		}
+		var response scanner_Scan_ResponseParams
+		response.outHandle, response.outErr, err = s.impl.Scan(request.inQuery, request.inScanHandler)
+		if err != nil {
+			return
+		}
+		header := bindings.MessageHeader{
+			Type:      scanner_Scan_Name,
+			Flags:     bindings.MessageIsResponseFlag,
+			RequestId: message.Header.RequestId,
+		}
+		message, err = bindings.EncodeMessage(header, &response)
+		if err != nil {
+			return err
+		}
+		return s.connector.WriteMessage(message)
+	case scanner_Stop_Name:
+		if message.Header.Flags != bindings.MessageNoFlag {
+			return &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
+				fmt.Sprintf("invalid message header flag: %v", message.Header.Flags),
+			}
+		}
+		var request scanner_Stop_Params
+		if err := message.DecodePayload(&request); err != nil {
+			return err
+		}
+		err = s.impl.Stop(request.inH)
+		if err != nil {
+			return
+		}
+	default:
+		return &bindings.ValidationError{
+			bindings.MessageHeaderUnknownMethod,
+			fmt.Sprintf("unknown method %v", message.Header.Type),
+		}
+	}
+	return
+}
+
+type ScanHandler interface {
+	Found(inS Service) (err error)
+	Lost(inInstanceId []uint8) (err error)
+}
+
+var scanHandler_Name = "discovery::ScanHandler"
+
+type ScanHandler_Request bindings.InterfaceRequest
+
+func (r *ScanHandler_Request) Name() string {
+	return scanHandler_Name
+}
+
+type ScanHandler_Pointer bindings.InterfacePointer
+
+func (p *ScanHandler_Pointer) Name() string {
+	return scanHandler_Name
+}
+
+type ScanHandler_ServiceFactory struct {
+	Delegate ScanHandler_Factory
+}
+
+type ScanHandler_Factory interface {
+	Create(request ScanHandler_Request)
+}
+
+func (f *ScanHandler_ServiceFactory) Name() string {
+	return scanHandler_Name
+}
+
+func (f *ScanHandler_ServiceFactory) Create(messagePipe system.MessagePipeHandle) {
+	request := ScanHandler_Request{bindings.NewMessagePipeHandleOwner(messagePipe)}
+	f.Delegate.Create(request)
+}
+
+// CreateMessagePipeForScanHandler creates a message pipe for use with the
+// ScanHandler interface with a ScanHandler_Request on one end and a ScanHandler_Pointer on the other.
+func CreateMessagePipeForScanHandler() (ScanHandler_Request, ScanHandler_Pointer) {
+	r, p := bindings.CreateMessagePipeForMojoInterface()
+	return ScanHandler_Request(r), ScanHandler_Pointer(p)
+}
+
+const scanHandler_Found_Name uint32 = 0
+const scanHandler_Lost_Name uint32 = 1
+
+type ScanHandler_Proxy struct {
+	router *bindings.Router
+	ids    bindings.Counter
+}
+
+func NewScanHandlerProxy(p ScanHandler_Pointer, waiter bindings.AsyncWaiter) *ScanHandler_Proxy {
+	return &ScanHandler_Proxy{
+		bindings.NewRouter(p.PassMessagePipe(), waiter),
+		bindings.NewCounter(),
+	}
+}
+
+func (p *ScanHandler_Proxy) Close_Proxy() {
+	p.router.Close()
+}
+
+type scanHandler_Found_Params struct {
+	inS Service
+}
+
+func (s *scanHandler_Found_Params) Encode(encoder *bindings.Encoder) error {
+	encoder.StartStruct(8, 0)
+	if err := encoder.WritePointer(); err != nil {
+		return err
+	}
+	if err := s.inS.Encode(encoder); err != nil {
+		return err
+	}
+	if err := encoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+var scanHandler_Found_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
+	bindings.DataHeader{16, 0},
+}
+
+func (s *scanHandler_Found_Params) Decode(decoder *bindings.Decoder) error {
+	header, err := decoder.StartStruct()
+	if err != nil {
+		return err
+	}
+	index := sort.Search(len(scanHandler_Found_Params_Versions), func(i int) bool {
+		return scanHandler_Found_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
+	})
+	if index < len(scanHandler_Found_Params_Versions) {
+		if scanHandler_Found_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
+			index--
+		}
+		expectedSize := scanHandler_Found_Params_Versions[index].Size
+		if expectedSize != header.Size {
+			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
+				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
+			}
+		}
+	}
+	if header.ElementsOrVersion >= 0 {
+		pointer0, err := decoder.ReadPointer()
+		if err != nil {
+			return err
+		}
+		if pointer0 == 0 {
+			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
+		} else {
+			if err := s.inS.Decode(decoder); err != nil {
+				return err
+			}
+		}
+	}
+	if err := decoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (p *ScanHandler_Proxy) Found(inS Service) (err error) {
+	payload := &scanHandler_Found_Params{
+		inS,
+	}
+	header := bindings.MessageHeader{
+		Type:  scanHandler_Found_Name,
+		Flags: bindings.MessageNoFlag,
+	}
+	var message *bindings.Message
+	if message, err = bindings.EncodeMessage(header, payload); err != nil {
+		err = fmt.Errorf("can't encode request: %v", err.Error())
+		p.Close_Proxy()
+		return
+	}
+	if err = p.router.Accept(message); err != nil {
+		p.Close_Proxy()
+		return
+	}
+	return
+}
+
+type scanHandler_Lost_Params struct {
+	inInstanceId []uint8
+}
+
+func (s *scanHandler_Lost_Params) Encode(encoder *bindings.Encoder) error {
+	encoder.StartStruct(8, 0)
+	if err := encoder.WritePointer(); err != nil {
+		return err
+	}
+	encoder.StartArray(uint32(len(s.inInstanceId)), 8)
+	for _, elem0 := range s.inInstanceId {
+		if err := encoder.WriteUint8(elem0); err != nil {
+			return err
+		}
+	}
+	if err := encoder.Finish(); err != nil {
+		return err
+	}
+	if err := encoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+var scanHandler_Lost_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
+	bindings.DataHeader{16, 0},
+}
+
+func (s *scanHandler_Lost_Params) Decode(decoder *bindings.Decoder) error {
+	header, err := decoder.StartStruct()
+	if err != nil {
+		return err
+	}
+	index := sort.Search(len(scanHandler_Lost_Params_Versions), func(i int) bool {
+		return scanHandler_Lost_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
+	})
+	if index < len(scanHandler_Lost_Params_Versions) {
+		if scanHandler_Lost_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
+			index--
+		}
+		expectedSize := scanHandler_Lost_Params_Versions[index].Size
+		if expectedSize != header.Size {
+			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
+				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
+			}
+		}
+	}
+	if header.ElementsOrVersion >= 0 {
+		pointer0, err := decoder.ReadPointer()
+		if err != nil {
+			return err
+		}
+		if pointer0 == 0 {
+			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
+		} else {
+			len0, err := decoder.StartArray(8)
+			if err != nil {
+				return err
+			}
+			s.inInstanceId = make([]uint8, len0)
+			for i0 := uint32(0); i0 < len0; i0++ {
+				value1, err := decoder.ReadUint8()
+				if err != nil {
+					return err
+				}
+				s.inInstanceId[i0] = value1
+			}
+			if err := decoder.Finish(); err != nil {
+				return err
+			}
+		}
+	}
+	if err := decoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (p *ScanHandler_Proxy) Lost(inInstanceId []uint8) (err error) {
+	payload := &scanHandler_Lost_Params{
+		inInstanceId,
+	}
+	header := bindings.MessageHeader{
+		Type:  scanHandler_Lost_Name,
+		Flags: bindings.MessageNoFlag,
+	}
+	var message *bindings.Message
+	if message, err = bindings.EncodeMessage(header, payload); err != nil {
+		err = fmt.Errorf("can't encode request: %v", err.Error())
+		p.Close_Proxy()
+		return
+	}
+	if err = p.router.Accept(message); err != nil {
+		p.Close_Proxy()
+		return
+	}
+	return
+}
+
+type scanHandler_Stub struct {
+	connector *bindings.Connector
+	impl      ScanHandler
+}
+
+func NewScanHandlerStub(r ScanHandler_Request, impl ScanHandler, waiter bindings.AsyncWaiter) *bindings.Stub {
+	connector := bindings.NewConnector(r.PassMessagePipe(), waiter)
+	return bindings.NewStub(connector, &scanHandler_Stub{connector, impl})
+}
+
+func (s *scanHandler_Stub) Accept(message *bindings.Message) (err error) {
+	switch message.Header.Type {
+	case scanHandler_Found_Name:
+		if message.Header.Flags != bindings.MessageNoFlag {
+			return &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
+				fmt.Sprintf("invalid message header flag: %v", message.Header.Flags),
+			}
+		}
+		var request scanHandler_Found_Params
+		if err := message.DecodePayload(&request); err != nil {
+			return err
+		}
+		err = s.impl.Found(request.inS)
+		if err != nil {
+			return
+		}
+	case scanHandler_Lost_Name:
+		if message.Header.Flags != bindings.MessageNoFlag {
+			return &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
+				fmt.Sprintf("invalid message header flag: %v", message.Header.Flags),
+			}
+		}
+		var request scanHandler_Lost_Params
+		if err := message.DecodePayload(&request); err != nil {
+			return err
+		}
+		err = s.impl.Lost(request.inInstanceId)
+		if err != nil {
+			return
+		}
+	default:
+		return &bindings.ValidationError{
+			bindings.MessageHeaderUnknownMethod,
+			fmt.Sprintf("unknown method %v", message.Header.Type),
+		}
+	}
+	return
+}
+
+type Service struct {
+	InstanceUuid  []uint8
+	InterfaceName string
+	Attrs         map[string]string
+	Addrs         []string
+}
+
+func (s *Service) Encode(encoder *bindings.Encoder) error {
+	encoder.StartStruct(32, 0)
+	if err := encoder.WritePointer(); err != nil {
+		return err
+	}
+	encoder.StartArray(uint32(len(s.InstanceUuid)), 8)
+	for _, elem0 := range s.InstanceUuid {
+		if err := encoder.WriteUint8(elem0); err != nil {
+			return err
+		}
+	}
+	if err := encoder.Finish(); err != nil {
+		return err
+	}
+	if err := encoder.WritePointer(); err != nil {
+		return err
+	}
+	if err := encoder.WriteString(s.InterfaceName); err != nil {
+		return err
+	}
+	if err := encoder.WritePointer(); err != nil {
+		return err
+	}
+	encoder.StartMap()
+	{
+		var keys0 []string
+		var values0 []string
+		for key0, value0 := range s.Attrs {
+			keys0 = append(keys0, key0)
+			values0 = append(values0, value0)
+		}
+		if err := encoder.WritePointer(); err != nil {
+			return err
+		}
+		encoder.StartArray(uint32(len(keys0)), 64)
+		for _, elem1 := range keys0 {
+			if err := encoder.WritePointer(); err != nil {
+				return err
+			}
+			if err := encoder.WriteString(elem1); err != nil {
+				return err
+			}
+		}
+		if err := encoder.Finish(); err != nil {
+			return err
+		}
+		if err := encoder.WritePointer(); err != nil {
+			return err
+		}
+		encoder.StartArray(uint32(len(values0)), 64)
+		for _, elem1 := range values0 {
+			if err := encoder.WritePointer(); err != nil {
+				return err
+			}
+			if err := encoder.WriteString(elem1); err != nil {
+				return err
+			}
+		}
+		if err := encoder.Finish(); err != nil {
+			return err
+		}
+	}
+	if err := encoder.Finish(); err != nil {
+		return err
+	}
+	if err := encoder.WritePointer(); err != nil {
+		return err
+	}
+	encoder.StartArray(uint32(len(s.Addrs)), 64)
+	for _, elem0 := range s.Addrs {
+		if err := encoder.WritePointer(); err != nil {
+			return err
+		}
+		if err := encoder.WriteString(elem0); err != nil {
+			return err
+		}
+	}
+	if err := encoder.Finish(); err != nil {
+		return err
+	}
+	if err := encoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+var service_Versions []bindings.DataHeader = []bindings.DataHeader{
+	bindings.DataHeader{40, 0},
+}
+
+func (s *Service) Decode(decoder *bindings.Decoder) error {
+	header, err := decoder.StartStruct()
+	if err != nil {
+		return err
+	}
+	index := sort.Search(len(service_Versions), func(i int) bool {
+		return service_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
+	})
+	if index < len(service_Versions) {
+		if service_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
+			index--
+		}
+		expectedSize := service_Versions[index].Size
+		if expectedSize != header.Size {
+			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
+				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
+			}
+		}
+	}
+	if header.ElementsOrVersion >= 0 {
+		pointer0, err := decoder.ReadPointer()
+		if err != nil {
+			return err
+		}
+		if pointer0 == 0 {
+			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
+		} else {
+			len0, err := decoder.StartArray(8)
+			if err != nil {
+				return err
+			}
+			s.InstanceUuid = make([]uint8, len0)
+			for i0 := uint32(0); i0 < len0; i0++ {
+				value1, err := decoder.ReadUint8()
+				if err != nil {
+					return err
+				}
+				s.InstanceUuid[i0] = value1
+			}
+			if err := decoder.Finish(); err != nil {
+				return err
+			}
+		}
+	}
+	if header.ElementsOrVersion >= 0 {
+		pointer0, err := decoder.ReadPointer()
+		if err != nil {
+			return err
+		}
+		if pointer0 == 0 {
+			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
+		} else {
+			value0, err := decoder.ReadString()
+			if err != nil {
+				return err
+			}
+			s.InterfaceName = value0
+		}
+	}
+	if header.ElementsOrVersion >= 0 {
+		pointer0, err := decoder.ReadPointer()
+		if err != nil {
+			return err
+		}
+		if pointer0 == 0 {
+			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
+		} else {
+			if err := decoder.StartMap(); err != nil {
+				return err
+			}
+			var keys0 []string
+			{
+				pointer1, err := decoder.ReadPointer()
+				if err != nil {
+					return err
+				}
+				if pointer1 == 0 {
+					return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
+				} else {
+					len1, err := decoder.StartArray(64)
+					if err != nil {
+						return err
+					}
+					keys0 = make([]string, len1)
+					for i1 := uint32(0); i1 < len1; i1++ {
+						pointer2, err := decoder.ReadPointer()
+						if err != nil {
+							return err
+						}
+						if pointer2 == 0 {
+							return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
+						} else {
+							value2, err := decoder.ReadString()
+							if err != nil {
+								return err
+							}
+							keys0[i1] = value2
+						}
+					}
+					if err := decoder.Finish(); err != nil {
+						return err
+					}
+				}
+			}
+			var values0 []string
+			{
+				pointer1, err := decoder.ReadPointer()
+				if err != nil {
+					return err
+				}
+				if pointer1 == 0 {
+					return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
+				} else {
+					len1, err := decoder.StartArray(64)
+					if err != nil {
+						return err
+					}
+					values0 = make([]string, len1)
+					for i1 := uint32(0); i1 < len1; i1++ {
+						pointer2, err := decoder.ReadPointer()
+						if err != nil {
+							return err
+						}
+						if pointer2 == 0 {
+							return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
+						} else {
+							value2, err := decoder.ReadString()
+							if err != nil {
+								return err
+							}
+							values0[i1] = value2
+						}
+					}
+					if err := decoder.Finish(); err != nil {
+						return err
+					}
+				}
+			}
+			if len(keys0) != len(values0) {
+				return &bindings.ValidationError{bindings.DifferentSizedArraysInMap,
+					fmt.Sprintf("Number of keys %d is different from number of values %d", len(keys0), len(values0)),
+				}
+			}
+			if err := decoder.Finish(); err != nil {
+				return err
+			}
+			len0 := len(keys0)
+			map0 := make(map[string]string)
+			for i0 := 0; i0 < len0; i0++ {
+				map0[keys0[i0]] = values0[i0]
+			}
+			s.Attrs = map0
+		}
+	}
+	if header.ElementsOrVersion >= 0 {
+		pointer0, err := decoder.ReadPointer()
+		if err != nil {
+			return err
+		}
+		if pointer0 == 0 {
+			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
+		} else {
+			len0, err := decoder.StartArray(64)
+			if err != nil {
+				return err
+			}
+			s.Addrs = make([]string, len0)
+			for i0 := uint32(0); i0 < len0; i0++ {
+				pointer1, err := decoder.ReadPointer()
+				if err != nil {
+					return err
+				}
+				if pointer1 == 0 {
+					return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
+				} else {
+					value1, err := decoder.ReadString()
+					if err != nil {
+						return err
+					}
+					s.Addrs[i0] = value1
+				}
+			}
+			if err := decoder.Finish(); err != nil {
+				return err
+			}
+		}
+	}
+	if err := decoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+type Error struct {
+	Id     string
+	Action int32
+	Msg    string
+}
+
+func (s *Error) Encode(encoder *bindings.Encoder) error {
+	encoder.StartStruct(24, 0)
+	if err := encoder.WritePointer(); err != nil {
+		return err
+	}
+	if err := encoder.WriteString(s.Id); err != nil {
+		return err
+	}
+	if err := encoder.WriteInt32(s.Action); err != nil {
+		return err
+	}
+	if err := encoder.WritePointer(); err != nil {
+		return err
+	}
+	if err := encoder.WriteString(s.Msg); err != nil {
+		return err
+	}
+	if err := encoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+var error_Versions []bindings.DataHeader = []bindings.DataHeader{
+	bindings.DataHeader{32, 0},
+}
+
+func (s *Error) Decode(decoder *bindings.Decoder) error {
+	header, err := decoder.StartStruct()
+	if err != nil {
+		return err
+	}
+	index := sort.Search(len(error_Versions), func(i int) bool {
+		return error_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
+	})
+	if index < len(error_Versions) {
+		if error_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
+			index--
+		}
+		expectedSize := error_Versions[index].Size
+		if expectedSize != header.Size {
+			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
+				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
+			}
+		}
+	}
+	if header.ElementsOrVersion >= 0 {
+		pointer0, err := decoder.ReadPointer()
+		if err != nil {
+			return err
+		}
+		if pointer0 == 0 {
+			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
+		} else {
+			value0, err := decoder.ReadString()
+			if err != nil {
+				return err
+			}
+			s.Id = value0
+		}
+	}
+	if header.ElementsOrVersion >= 0 {
+		value0, err := decoder.ReadInt32()
+		if err != nil {
+			return err
+		}
+		s.Action = value0
+	}
+	if header.ElementsOrVersion >= 0 {
+		pointer0, err := decoder.ReadPointer()
+		if err != nil {
+			return err
+		}
+		if pointer0 == 0 {
+			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
+		} else {
+			value0, err := decoder.ReadString()
+			if err != nil {
+				return err
+			}
+			s.Msg = value0
+		}
+	}
+	if err := decoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
diff --git a/go/src/vanadium/discovery/discovery.go b/go/src/vanadium/discovery/discovery.go
new file mode 100644
index 0000000..62d27d8
--- /dev/null
+++ b/go/src/vanadium/discovery/discovery.go
@@ -0,0 +1,116 @@
+// 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 main
+
+import (
+	"v.io/v23"
+	discovery_factory "v.io/x/ref/lib/discovery/factory"
+
+	_ "v.io/x/ref/runtime/factories/generic"
+
+	mojom "mojom/vanadium/discovery"
+	"vanadium/discovery/internal"
+
+	"mojo/public/go/application"
+	"mojo/public/go/bindings"
+	"mojo/public/go/system"
+	"sync"
+	"v.io/v23/context"
+)
+
+//#include "mojo/public/c/system/types.h"
+import "C"
+
+type discoveryDelegate struct {
+	// mu protects stubs.  All calls to methods on the delegate by
+	// mojo will be done in the same goroutine.  We need mu so
+	// we can clean up stubs that fail because of pipe errors because
+	// each stub serves all its requests in its own goroutine.
+	mu    sync.Mutex
+	stubs map[*bindings.Stub]struct{}
+
+	ctx      *context.T
+	impl     *internal.DiscoveryService
+	shutdown v23.Shutdown
+}
+
+func (d *discoveryDelegate) Initialize(c application.Context) {
+	// TODO(bjornick): Calling init multiple times in the same process
+	// will be bad.  For now, this is ok because this is the only
+	// vanadium service that will be used in the demos and each go library
+	// will be in its own process.
+	ctx, shutdown := v23.Init()
+
+	inst, err := discovery_factory.New(c.Args()[2:]...)
+	if err != nil {
+		ctx.Fatalf("failed to initalize discovery: %v", err)
+	}
+
+	d.impl = internal.NewDiscoveryService(ctx, inst)
+	d.shutdown = shutdown
+}
+
+func (d *discoveryDelegate) addAndServeStub(stub *bindings.Stub) {
+	d.mu.Lock()
+	d.stubs[stub] = struct{}{}
+	d.mu.Unlock()
+	go func() {
+		for {
+			if err := stub.ServeRequest(); err != nil {
+				connectionErr, ok := err.(*bindings.ConnectionError)
+				if !ok || !connectionErr.Closed() {
+					d.ctx.Error(err)
+				}
+				break
+			}
+		}
+		d.mu.Lock()
+		delete(d.stubs, stub)
+		d.mu.Unlock()
+	}()
+}
+
+type advertiseFactory struct {
+	d *discoveryDelegate
+}
+
+func (a *advertiseFactory) Create(request mojom.Advertiser_Request) {
+	stub := mojom.NewAdvertiserStub(request, a.d.impl, bindings.GetAsyncWaiter())
+	a.d.addAndServeStub(stub)
+}
+
+type scannerFactory struct {
+	d *discoveryDelegate
+}
+
+func (s *scannerFactory) Create(request mojom.Scanner_Request) {
+	stub := mojom.NewScannerStub(request, s.d.impl, bindings.GetAsyncWaiter())
+	s.d.addAndServeStub(stub)
+}
+
+func (d *discoveryDelegate) AcceptConnection(connection *application.Connection) {
+	advFactory := &advertiseFactory{d: d}
+	scanFactory := &scannerFactory{d: d}
+	connection.ProvideServices(&mojom.Advertiser_ServiceFactory{advFactory}, &mojom.Scanner_ServiceFactory{scanFactory})
+}
+
+func (d *discoveryDelegate) Quit() {
+	d.impl.StopAll()
+	d.shutdown()
+	d.mu.Lock()
+	for stub := range d.stubs {
+		stub.Close()
+	}
+	d.mu.Unlock()
+}
+
+//export MojoMain
+func MojoMain(handle C.MojoHandle) C.MojoResult {
+	application.Run(&discoveryDelegate{stubs: map[*bindings.Stub]struct{}{}}, system.MojoHandle(handle))
+	return C.MOJO_RESULT_OK
+}
+
+func main() {
+}
diff --git a/go/src/vanadium/discovery/internal/discovery.go b/go/src/vanadium/discovery/internal/discovery.go
new file mode 100644
index 0000000..59da5fa
--- /dev/null
+++ b/go/src/vanadium/discovery/internal/discovery.go
@@ -0,0 +1,169 @@
+// 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 internal
+
+import (
+	"sync"
+
+	"v.io/v23/context"
+	"v.io/v23/discovery"
+	"v.io/v23/verror"
+
+	"mojo/public/go/bindings"
+	mojom "mojom/vanadium/discovery"
+	"v.io/v23/security"
+)
+
+type id uint32
+
+// DiscoveryService implements the mojom interface mojom/vanadium/discovery.DiscoveryService.  It
+// is basically a thin wrapper around the Vanadium Discovery API.
+type DiscoveryService struct {
+	ctx *context.T
+	s   discovery.T
+
+	// mu protects pending* and next*
+	mu sync.Mutex
+
+	// The id to assign the next advertisement.
+	nextAdv id
+	// A map of advertisement ids to the cancellation function.
+	activeAdvs map[id]func()
+	// The id to assign to the next scan.
+	nextScan id
+	// A map of scan id to the cancellataion func()
+	activeScans map[id]func()
+}
+
+func v2mError(err error) *mojom.Error {
+	return &mojom.Error{
+		Id:     string(verror.ErrorID(err)),
+		Action: int32(verror.Action(err)),
+		Msg:    err.Error(),
+	}
+}
+
+// NewDiscoveryService returns a new DiscoveryService bound to the context and the Vanadium
+// Discovery implementation passed in.
+func NewDiscoveryService(ctx *context.T, vDiscovery discovery.T) *DiscoveryService {
+	return &DiscoveryService{
+		ctx:         ctx,
+		s:           vDiscovery,
+		nextAdv:     1,
+		activeAdvs:  map[id]func(){},
+		activeScans: map[id]func(){},
+	}
+}
+
+// Advertise advertises the mojom service passed only to the giveen blessing patterns. Returns the
+// handle to this Advertise call.
+func (d *DiscoveryService) Advertise(s mojom.Service, patterns []string) (uint32, *mojom.Error, error) {
+	vService := discovery.Service{
+		InstanceUuid:  s.InstanceUuid,
+		InterfaceName: s.InterfaceName,
+		Attrs:         discovery.Attributes(s.Attrs),
+		Addrs:         s.Addrs,
+	}
+
+	ctx, cancel := context.WithCancel(d.ctx)
+
+	perms := make([]security.BlessingPattern, len(patterns))
+	for i, pattern := range patterns {
+		perms[i] = security.BlessingPattern(pattern)
+	}
+	err := d.s.Advertise(ctx, vService, perms)
+	if err != nil {
+		cancel()
+		return 0, v2mError(err), nil
+	}
+	d.mu.Lock()
+	currId := d.nextAdv
+	d.activeAdvs[currId] = cancel
+	d.nextAdv += 2
+	d.mu.Unlock()
+	return uint32(currId), nil, nil
+}
+
+func (d *DiscoveryService) stopAdvertising(handle uint32) error {
+	d.mu.Lock()
+	cancel := d.activeAdvs[id(handle)]
+	delete(d.activeAdvs, id(handle))
+	d.mu.Unlock()
+	if cancel != nil {
+		cancel()
+	}
+	return nil
+}
+
+func v2mService(s discovery.Service) mojom.Service {
+	return mojom.Service{
+		InstanceUuid:  s.InstanceUuid,
+		InterfaceName: s.InterfaceName,
+		Attrs:         s.Attrs,
+		Addrs:         s.Addrs,
+	}
+}
+
+// Scan scans for all services that match the query string passed in and calls scanHandler with updates.
+// Returns the handle to this Scan.
+func (d *DiscoveryService) Scan(query string, scanHandler mojom.ScanHandler_Pointer) (uint32, *mojom.Error, error) {
+	ctx, cancel := context.WithCancel(d.ctx)
+	scanCh, err := d.s.Scan(ctx, query)
+	if err != nil {
+		cancel()
+		return 0, v2mError(err), nil
+	}
+	d.mu.Lock()
+	currId := d.nextScan
+	d.activeScans[currId] = cancel
+	d.nextScan += 2
+	d.mu.Unlock()
+
+	go func() {
+		proxy := mojom.NewScanHandlerProxy(scanHandler, bindings.GetAsyncWaiter())
+		for v := range scanCh {
+			switch value := v.(type) {
+			case discovery.UpdateFound:
+				proxy.Found(v2mService(value.Value.Service))
+			case discovery.UpdateLost:
+				proxy.Lost(value.Value.InstanceUuid)
+			}
+		}
+	}()
+	return uint32(currId), nil, nil
+}
+
+// Stop stops the scan.
+func (d *DiscoveryService) Stop(handle uint32) error {
+	if handle % 2 == 0 {
+		return d.stopScan(handle)
+	}
+	return d.stopAdvertising(handle)
+}
+
+func (d *DiscoveryService) stopScan(handle uint32) error {
+	d.mu.Lock()
+	cancel := d.activeScans[id(handle)]
+	delete(d.activeScans, id(handle))
+	d.mu.Unlock()
+	if cancel != nil {
+		cancel()
+	}
+	return nil
+}
+
+// Stop Stops all scans and advertisements.
+func (d *DiscoveryService) StopAll() {
+	d.mu.Lock()
+	for _, cancel := range d.activeScans {
+		cancel()
+	}
+
+	for _, cancel := range d.activeAdvs {
+		cancel()
+	}
+	d.s.Close()
+	d.mu.Unlock()
+}
diff --git a/go/src/vanadium/discovery/internal/discovery_test.go b/go/src/vanadium/discovery/internal/discovery_test.go
new file mode 100644
index 0000000..585eb48
--- /dev/null
+++ b/go/src/vanadium/discovery/internal/discovery_test.go
@@ -0,0 +1,133 @@
+// 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 internal
+
+import (
+	"reflect"
+	"testing"
+
+	"v.io/v23/context"
+	"v.io/v23/discovery"
+	idiscovery "v.io/x/ref/lib/discovery"
+	vtest "v.io/x/ref/test"
+
+	_ "v.io/x/ref/runtime/factories/generic"
+
+	mojom "mojom/vanadium/discovery"
+	"sync"
+	"third_party/go/tool/android_arm/src/fmt"
+	"v.io/v23/security"
+)
+
+type mockAdv struct {
+	s discovery.Service
+}
+
+type discoveryMock struct {
+	mu       sync.Mutex
+	trigger  *idiscovery.Trigger
+	id       int64
+	services map[int64]discovery.Service
+	// An item will be put in deleteCh when something has been deleted.
+	deleteCh chan struct{}
+}
+
+func (d *discoveryMock) Advertise(ctx *context.T, s discovery.Service, perms []security.BlessingPattern) error {
+	d.mu.Lock()
+	currId := d.id
+	d.services[currId] = s
+	d.id++
+	d.mu.Unlock()
+	c := func() {
+		d.mu.Lock()
+		delete(d.services, currId)
+		d.mu.Unlock()
+		d.deleteCh <- struct{}{}
+	}
+	d.trigger.Add(c, ctx.Done())
+	return nil
+}
+
+func (*discoveryMock) Scan(ctx *context.T, query string) (<-chan discovery.Update, error) {
+	return nil, nil
+}
+
+func (*discoveryMock) Close() {}
+
+func compare(want discovery.Service, got mojom.Service) error {
+	mwant := v2mService(want)
+	if !reflect.DeepEqual(mwant, got) {
+		return fmt.Errorf("Got %#v want %#v", got, want)
+	}
+	return nil
+}
+
+func TestAdvertising(t *testing.T) {
+	ctx, shutdown := vtest.V23Init()
+	defer shutdown()
+	mock := &discoveryMock{
+		trigger:  idiscovery.NewTrigger(),
+		services: map[int64]discovery.Service{},
+		deleteCh: make(chan struct{}),
+	}
+	s := NewDiscoveryService(ctx, mock)
+	testService := mojom.Service{
+		InterfaceName: "v.io/v23/discovery.T",
+		Attrs: map[string]string{
+			"key1": "value1",
+			"key2": "value2",
+		},
+		Addrs: []string{"addr1", "addr2"},
+	}
+	id, e1, e2 := s.Advertise(testService, nil)
+
+	if e1 != nil || e2 != nil {
+		t.Fatalf("Failed to start service: %v, %v", e1, e2)
+	}
+	if len(mock.services) != 1 {
+		t.Errorf("service missing in mock")
+	}
+
+	for _, service := range mock.services {
+		if err := compare(service, testService); err != nil {
+			t.Error(err)
+		}
+
+	}
+
+	testService2 := mojom.Service{
+		InterfaceName: "v.io/v23/naming.T",
+		Attrs: map[string]string{
+			"key1": "value1",
+			"key2": "value2",
+		},
+		Addrs: []string{"addr1", "addr2"},
+	}
+
+	_, e1, e2 = s.Advertise(testService2, nil)
+	if e1 != nil || e2 != nil {
+		t.Fatalf("Failed to start service: %v, %v", e1, e2)
+	}
+
+	s.Stop(id)
+	// Wait for the deletion to finish.
+	<-mock.deleteCh
+	if len(mock.services) != 1 {
+		t.Errorf("service should have been removed")
+	}
+
+	for _, service := range mock.services {
+		if err := compare(service, testService2); err != nil {
+			t.Error(err)
+		}
+
+	}
+
+	s.StopAll()
+	<-mock.deleteCh
+	if len(mock.services) != 0 {
+		t.Errorf("service should have been removed")
+	}
+}
diff --git a/mojoconfig b/mojoconfig
new file mode 100644
index 0000000..9e2c0d5
--- /dev/null
+++ b/mojoconfig
@@ -0,0 +1,14 @@
+# Derived from $MOJO_DIR/mojoconfig.
+
+{
+  'dev_servers': [
+    {
+      'host': 'https://mojo.v.io/',
+      'mappings': [
+        ('', [
+          '@{DISCOVERY_BUILD_DIR}',
+        ]),
+      ],
+    },
+  ],
+}
diff --git a/mojom/vanadium/discovery.mojom b/mojom/vanadium/discovery.mojom
new file mode 100644
index 0000000..1114bfe
--- /dev/null
+++ b/mojom/vanadium/discovery.mojom
@@ -0,0 +1,60 @@
+// 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.
+
+module discovery;
+
+// Copied from v.io/v23/discovery/types.vdl
+struct Service {
+    // The 128 bit (16 byte) universal unique identifier of a service instance.
+	// If this is not specified, a random UUID will be used.
+	array<uint8> InstanceUuid;
+	// The interface that the service implements.
+	// E.g., 'v.io/v23/services/vtrace.Store'.
+	string InterfaceName;
+	// The service attributes.
+	// E.g., {'resolution': '1024x768'}.
+	map<string, string> Attrs;
+	// The addresses that the service is served on.
+	// E.g., '/host:port/a/b/c'.
+	array<string> Addrs;
+};
+
+struct Error {
+   string id;
+   int32 action;
+   string msg;
+};
+
+// Advertiser provides methods to do Vanadium Advertising.
+interface Advertiser {
+    // Advertise advertises the service to be discovered by "Scanner" implementations.
+	// visibility is used to limit the principals that can see the advertisement. An
+	// empty set means that there are no restrictions on visibility (i.e, equivalent
+	// to []security.BlessingPattern{security.AllPrincipals}). Advertising will continue
+	// until the context is canceled or exceeds its deadline.
+	Advertise(Service s, array<string> visibility) => (uint32 Handle, Error? Err);
+
+	// Stop Stops the advertisement associated with the given handle.
+	Stop(uint32 h);
+};
+
+// Scanner provides methods to scan for Vanadium advertisements.
+interface Scanner {
+	// Scan scans for services matching the query passed nad 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);
+
+	// StopScan stops the scanner associated weith the given handle.
+	Stop(uint32 h);
+};
+
+// ScanHandler is used to pass updates about Services that are found/lost during the
+// scan.
+interface ScanHandler {
+	// Found will be called when a Service is found.
+	Found(Service s);
+
+	// Lost will be called when a service is lost.
+	Lost(array<uint8> instanceId);
+};
\ No newline at end of file
