diff --git a/.gitignore b/.gitignore
index b7e2fde..afc89b2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,6 @@
-/.v23
\ No newline at end of file
+/.v23
+gen/
+out/
+go/.idea/
+.idea/
+*.iml
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..2652b3f
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,34 @@
+PWD := $(shell pwd)
+DISCOVERY_BUILD_DIR=$(PWD)/out
+
+include ../shared/mojo.mk
+
+# NOTE(nlacasse): Running Go Mojo services requires passing the
+# --enable-multiprocess flag to mojo_shell.  This is because the Go runtime is
+# very large, and can interfere with C++ memory if they are in the same
+# process.
+MOJO_SHELL_FLAGS += \
+	--config-alias DISCOVERY_BUILD_DIR=$(DISCOVERY_BUILD_DIR)
+
+echo-go-path:
+	echo $(GOPATH)
+
+run-advertiser-service: $(DISCOVERY_BUILD_DIR)/driver.mojo $(DISCOVERY_BUILD_DIR)/ble.mojo
+	sudo $(MOJO_DIR)/src/mojo/devtools/common/mojo_run --config-file $(PWD)/mojoconfig $(MOJO_SHELL_FLAGS) --args-for="https://mojo.v.io/ble.mojo test" https://mojo.v.io/driver.mojo
+
+run-scanner-service: $(DISCOVERY_BUILD_DIR)/scanner.mojo $(DISCOVERY_BUILD_DIR)/ble.mojo
+	sudo $(MOJO_DIR)/src/mojo/devtools/common/mojo_run --config-file $(PWD)/mojoconfig $(MOJO_SHELL_FLAGS) --args-for="https://mojo.v.io/ble.mojo test" https://mojo.v.io/scanner.mojo
+
+all_mojom: go/src/mojom/v.io/x/ref/services/discovery/ble/mojo/ble.mojom.go go/src/mojom/v.io/x/ref/services/discovery/mojo/discovery.mojom.go
+go/src/mojom/v.io/x/ref/services/discovery/ble/mojo/ble.mojom.go: mojom/v.io/x/ref/services/discovery/ble/ble.mojom
+	$(call MOJOM_GEN,$<,.,go)
+go/src/mojom/v.io/x/ref/services/discovery/mojo/discovery.mojom.go: mojom/v.io/x/ref/services/discovery/discovery.mojom
+	$(call MOJOM_GEN,$<,.,go)
+$(DISCOVERY_BUILD_DIR)/ble.mojo:  go/src/mojom/v.io/x/ref/services/discovery/ble/ble/ble.mojom.go go/src/v.io/x/ref/services/discovery/ble/neighborhood.go go/src/v.io/x/ref/services/discovery/ble/service.go $(MOJO_SHARED_LIB)
+	$(call MOGO_BUILD,v.io/x/ref/services/discovery/ble,$@)
+
+$(DISCOVERY_BUILD_DIR)/driver.mojo:  go/src/mojom/v.io/x/ref/services/discovery/ble/ble/ble.mojom.go go/src/v.io/x/ref/services/discovery/driver/driver.go $(MOJO_SHARED_LIB)
+	$(call MOGO_BUILD,v.io/x/ref/services/discovery/driver,$@)
+$(DISCOVERY_BUILD_DIR)/scanner.mojo:  go/src/mojom/v.io/x/ref/services/discovery/ble/ble/ble.mojom.go go/src/v.io/x/ref/services/discovery/scanner/scanner.go $(MOJO_SHARED_LIB)
+	$(call MOGO_BUILD,v.io/x/ref/services/discovery/scanner,$@)
+
diff --git a/go/src/mojom/v.io/x/ref/services/discovery/ble/ble/ble.mojom.go b/go/src/mojom/v.io/x/ref/services/discovery/ble/ble/ble.mojom.go
new file mode 100644
index 0000000..4276952
--- /dev/null
+++ b/go/src/mojom/v.io/x/ref/services/discovery/ble/ble/ble.mojom.go
@@ -0,0 +1,1393 @@
+// 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/v.io/x/ref/services/discovery/ble/ble.mojom
+//
+
+package ble
+
+import (
+	"fmt"
+	"mojo/public/go/bindings"
+	"mojo/public/go/system"
+	"sort"
+)
+
+type V23Ble interface {
+	Advertise(inAdv Advertisement) (outHandler PluginStopper_Pointer, err error)
+	Scan(inId *[]uint8, inAttributes map[string]string, inHandler PluginScanHandler_Pointer) (outHandler PluginStopper_Pointer, err error)
+}
+
+var v23BLE_Name = "ble::V23BLE"
+
+type V23Ble_Request bindings.InterfaceRequest
+
+func (r *V23Ble_Request) Name() string {
+	return v23BLE_Name
+}
+
+type V23Ble_Pointer bindings.InterfacePointer
+
+func (p *V23Ble_Pointer) Name() string {
+	return v23BLE_Name
+}
+
+type V23Ble_ServiceFactory struct{
+	Delegate V23Ble_Factory
+}
+
+type V23Ble_Factory interface {
+	Create(request V23Ble_Request)
+}
+
+func (f *V23Ble_ServiceFactory) Name() string {
+	return v23BLE_Name
+}
+
+func (f *V23Ble_ServiceFactory) Create(messagePipe system.MessagePipeHandle) {
+	request := V23Ble_Request{bindings.NewMessagePipeHandleOwner(messagePipe)}
+	f.Delegate.Create(request)
+}
+
+// CreateMessagePipeForV23Ble creates a message pipe for use with the
+// V23Ble interface with a V23Ble_Request on one end and a V23Ble_Pointer on the other.
+func CreateMessagePipeForV23Ble() (V23Ble_Request, V23Ble_Pointer) {
+        r, p := bindings.CreateMessagePipeForMojoInterface()
+        return V23Ble_Request(r), V23Ble_Pointer(p)
+}
+
+const v23BLE_Advertise_Name uint32 = 0
+const v23BLE_Scan_Name uint32 = 1
+
+type V23Ble_Proxy struct {
+	router *bindings.Router
+	ids bindings.Counter
+}
+
+func NewV23BleProxy(p V23Ble_Pointer, waiter bindings.AsyncWaiter) *V23Ble_Proxy {
+	return &V23Ble_Proxy{
+		bindings.NewRouter(p.PassMessagePipe(), waiter),
+		bindings.NewCounter(),
+	}
+}
+
+func (p *V23Ble_Proxy) Close_Proxy() {
+	p.router.Close()
+}
+
+type v23Ble_Advertise_Params struct {
+	inAdv Advertisement
+}
+
+func (s *v23Ble_Advertise_Params) Encode(encoder *bindings.Encoder) error {
+	encoder.StartStruct(8, 0)
+	if err := encoder.WritePointer(); err != nil {
+		return err
+	}
+	if err := s.inAdv.Encode(encoder); err != nil {
+		return err
+	}
+	if err := encoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+var v23Ble_Advertise_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
+	bindings.DataHeader{16, 0},
+}
+
+func (s *v23Ble_Advertise_Params) Decode(decoder *bindings.Decoder) error {
+	header, err := decoder.StartStruct()
+	if err != nil {
+		return err
+	}
+	index := sort.Search(len(v23Ble_Advertise_Params_Versions), func(i int) bool {
+		return v23Ble_Advertise_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
+	})
+	if index < len(v23Ble_Advertise_Params_Versions) {
+		if v23Ble_Advertise_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
+			index--
+		}
+		expectedSize := v23Ble_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.inAdv.Decode(decoder); err != nil {
+				return err
+			}
+		}
+	}
+	if err := decoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+type v23Ble_Advertise_ResponseParams struct {
+	outHandler PluginStopper_Pointer
+}
+
+func (s *v23Ble_Advertise_ResponseParams) Encode(encoder *bindings.Encoder) error {
+	encoder.StartStruct(8, 0)
+	if err := encoder.WriteInterface(s.outHandler.PassMessagePipe()); err != nil {
+		return err
+	}
+	if err := encoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+var v23Ble_Advertise_ResponseParams_Versions []bindings.DataHeader = []bindings.DataHeader{
+	bindings.DataHeader{16, 0},
+}
+
+func (s *v23Ble_Advertise_ResponseParams) Decode(decoder *bindings.Decoder) error {
+	header, err := decoder.StartStruct()
+	if err != nil {
+		return err
+	}
+	index := sort.Search(len(v23Ble_Advertise_ResponseParams_Versions), func(i int) bool {
+		return v23Ble_Advertise_ResponseParams_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
+	})
+	if index < len(v23Ble_Advertise_ResponseParams_Versions) {
+		if v23Ble_Advertise_ResponseParams_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
+			index--
+		}
+		expectedSize := v23Ble_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 {
+		handle0, err := decoder.ReadInterface()
+		if err != nil {
+			return err
+		}
+		if handle0.IsValid() {
+			handleOwner := bindings.NewMessagePipeHandleOwner(handle0)
+			s.outHandler = PluginStopper_Pointer{handleOwner}
+		} else {
+			return &bindings.ValidationError{bindings.UnexpectedInvalidHandle, "unexpected invalid handle"}
+		}
+	}
+	if err := decoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (p *V23Ble_Proxy) Advertise(inAdv Advertisement) (outHandler PluginStopper_Pointer, err error) {
+	payload := &v23Ble_Advertise_Params{
+		inAdv,
+	}
+	header := bindings.MessageHeader{
+		Type: v23BLE_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, v23BLE_Advertise_Name; got != want {
+		err = &bindings.ValidationError{bindings.MessageHeaderUnknownMethod,
+			fmt.Sprintf("invalid method in response: expected %v, got %v", want, got),
+		}
+		return
+	}
+	var response v23Ble_Advertise_ResponseParams
+	if err = readResult.Message.DecodePayload(&response); err != nil {
+		p.Close_Proxy()
+		return
+	}
+	outHandler = response.outHandler
+	return
+}
+
+type v23Ble_Scan_Params struct {
+	inId *[]uint8
+	inAttributes map[string]string
+	inHandler PluginScanHandler_Pointer
+}
+
+func (s *v23Ble_Scan_Params) Encode(encoder *bindings.Encoder) error {
+	encoder.StartStruct(24, 0)
+	if s.inId == nil {
+		encoder.WriteNullPointer()
+	} else {
+		if err := encoder.WritePointer(); err != nil {
+			return err
+		}
+		encoder.StartArray(uint32(len((*s.inId))), 8)
+		for _, elem0 := range (*s.inId) {
+			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
+	}
+	encoder.StartMap()
+	{
+		var keys0 []string
+		var values0 []string
+		for key0, value0 := range s.inAttributes {
+			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.WriteInterface(s.inHandler.PassMessagePipe()); err != nil {
+		return err
+	}
+	if err := encoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+var v23Ble_Scan_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
+	bindings.DataHeader{32, 0},
+}
+
+func (s *v23Ble_Scan_Params) Decode(decoder *bindings.Decoder) error {
+	header, err := decoder.StartStruct()
+	if err != nil {
+		return err
+	}
+	index := sort.Search(len(v23Ble_Scan_Params_Versions), func(i int) bool {
+		return v23Ble_Scan_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
+	})
+	if index < len(v23Ble_Scan_Params_Versions) {
+		if v23Ble_Scan_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
+			index--
+		}
+		expectedSize := v23Ble_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 {
+			s.inId = nil
+		} else {
+			s.inId = new([]uint8)
+			len0, err := decoder.StartArray(8)
+			if err != nil {
+				return err
+			}
+			(*s.inId) = make([]uint8, len0)
+			for i0 := uint32(0); i0 < len0; i0++ {
+				value1, err := decoder.ReadUint8()
+				if err != nil {
+					return err
+				}
+				(*s.inId)[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 {
+			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.inAttributes = map0
+		}
+	}
+	if header.ElementsOrVersion >= 0 {
+		handle0, err := decoder.ReadInterface()
+		if err != nil {
+			return err
+		}
+		if handle0.IsValid() {
+			handleOwner := bindings.NewMessagePipeHandleOwner(handle0)
+			s.inHandler = PluginScanHandler_Pointer{handleOwner}
+		} else {
+			return &bindings.ValidationError{bindings.UnexpectedInvalidHandle, "unexpected invalid handle"}
+		}
+	}
+	if err := decoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+type v23Ble_Scan_ResponseParams struct {
+	outHandler PluginStopper_Pointer
+}
+
+func (s *v23Ble_Scan_ResponseParams) Encode(encoder *bindings.Encoder) error {
+	encoder.StartStruct(8, 0)
+	if err := encoder.WriteInterface(s.outHandler.PassMessagePipe()); err != nil {
+		return err
+	}
+	if err := encoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+var v23Ble_Scan_ResponseParams_Versions []bindings.DataHeader = []bindings.DataHeader{
+	bindings.DataHeader{16, 0},
+}
+
+func (s *v23Ble_Scan_ResponseParams) Decode(decoder *bindings.Decoder) error {
+	header, err := decoder.StartStruct()
+	if err != nil {
+		return err
+	}
+	index := sort.Search(len(v23Ble_Scan_ResponseParams_Versions), func(i int) bool {
+		return v23Ble_Scan_ResponseParams_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
+	})
+	if index < len(v23Ble_Scan_ResponseParams_Versions) {
+		if v23Ble_Scan_ResponseParams_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
+			index--
+		}
+		expectedSize := v23Ble_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 {
+		handle0, err := decoder.ReadInterface()
+		if err != nil {
+			return err
+		}
+		if handle0.IsValid() {
+			handleOwner := bindings.NewMessagePipeHandleOwner(handle0)
+			s.outHandler = PluginStopper_Pointer{handleOwner}
+		} else {
+			return &bindings.ValidationError{bindings.UnexpectedInvalidHandle, "unexpected invalid handle"}
+		}
+	}
+	if err := decoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (p *V23Ble_Proxy) Scan(inId *[]uint8, inAttributes map[string]string, inHandler PluginScanHandler_Pointer) (outHandler PluginStopper_Pointer, err error) {
+	payload := &v23Ble_Scan_Params{
+		inId,
+		inAttributes,
+		inHandler,
+	}
+	header := bindings.MessageHeader{
+		Type: v23BLE_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, v23BLE_Scan_Name; got != want {
+		err = &bindings.ValidationError{bindings.MessageHeaderUnknownMethod,
+			fmt.Sprintf("invalid method in response: expected %v, got %v", want, got),
+		}
+		return
+	}
+	var response v23Ble_Scan_ResponseParams
+	if err = readResult.Message.DecodePayload(&response); err != nil {
+		p.Close_Proxy()
+		return
+	}
+	outHandler = response.outHandler
+	return
+}
+
+type v23BLE_Stub struct {
+	connector *bindings.Connector
+	impl V23Ble
+}
+
+func NewV23BleStub(r V23Ble_Request, impl V23Ble, waiter bindings.AsyncWaiter) *bindings.Stub {
+	connector := bindings.NewConnector(r.PassMessagePipe(), waiter)
+	return bindings.NewStub(connector, &v23BLE_Stub{connector, impl})
+}
+
+func (s *v23BLE_Stub) Accept(message *bindings.Message) (err error) {
+	switch message.Header.Type {
+	case v23BLE_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 v23Ble_Advertise_Params
+		if err := message.DecodePayload(&request); err != nil {
+			return err
+		}
+		var response v23Ble_Advertise_ResponseParams
+		response.outHandler, err = s.impl.Advertise(request.inAdv)
+		if err != nil {
+			return
+		}
+		header := bindings.MessageHeader{
+			Type: v23BLE_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 v23BLE_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 v23Ble_Scan_Params
+		if err := message.DecodePayload(&request); err != nil {
+			return err
+		}
+		var response v23Ble_Scan_ResponseParams
+		response.outHandler, err = s.impl.Scan(request.inId, request.inAttributes, request.inHandler)
+		if err != nil {
+			return
+		}
+		header := bindings.MessageHeader{
+			Type: v23BLE_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)
+	default:
+		return &bindings.ValidationError{
+			bindings.MessageHeaderUnknownMethod,
+			fmt.Sprintf("unknown method %v", message.Header.Type),
+		}
+	}
+	return
+}
+
+type PluginScanHandler interface {
+	Found(inS Advertisement) (err error)
+	Lost(inS Advertisement) (err error)
+}
+
+var pluginScanHandler_Name = "ble::PluginScanHandler"
+
+type PluginScanHandler_Request bindings.InterfaceRequest
+
+func (r *PluginScanHandler_Request) Name() string {
+	return pluginScanHandler_Name
+}
+
+type PluginScanHandler_Pointer bindings.InterfacePointer
+
+func (p *PluginScanHandler_Pointer) Name() string {
+	return pluginScanHandler_Name
+}
+
+type PluginScanHandler_ServiceFactory struct{
+	Delegate PluginScanHandler_Factory
+}
+
+type PluginScanHandler_Factory interface {
+	Create(request PluginScanHandler_Request)
+}
+
+func (f *PluginScanHandler_ServiceFactory) Name() string {
+	return pluginScanHandler_Name
+}
+
+func (f *PluginScanHandler_ServiceFactory) Create(messagePipe system.MessagePipeHandle) {
+	request := PluginScanHandler_Request{bindings.NewMessagePipeHandleOwner(messagePipe)}
+	f.Delegate.Create(request)
+}
+
+// CreateMessagePipeForPluginScanHandler creates a message pipe for use with the
+// PluginScanHandler interface with a PluginScanHandler_Request on one end and a PluginScanHandler_Pointer on the other.
+func CreateMessagePipeForPluginScanHandler() (PluginScanHandler_Request, PluginScanHandler_Pointer) {
+        r, p := bindings.CreateMessagePipeForMojoInterface()
+        return PluginScanHandler_Request(r), PluginScanHandler_Pointer(p)
+}
+
+const pluginScanHandler_Found_Name uint32 = 0
+const pluginScanHandler_Lost_Name uint32 = 1
+
+type PluginScanHandler_Proxy struct {
+	router *bindings.Router
+	ids bindings.Counter
+}
+
+func NewPluginScanHandlerProxy(p PluginScanHandler_Pointer, waiter bindings.AsyncWaiter) *PluginScanHandler_Proxy {
+	return &PluginScanHandler_Proxy{
+		bindings.NewRouter(p.PassMessagePipe(), waiter),
+		bindings.NewCounter(),
+	}
+}
+
+func (p *PluginScanHandler_Proxy) Close_Proxy() {
+	p.router.Close()
+}
+
+type pluginScanHandler_Found_Params struct {
+	inS Advertisement
+}
+
+func (s *pluginScanHandler_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 pluginScanHandler_Found_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
+	bindings.DataHeader{16, 0},
+}
+
+func (s *pluginScanHandler_Found_Params) Decode(decoder *bindings.Decoder) error {
+	header, err := decoder.StartStruct()
+	if err != nil {
+		return err
+	}
+	index := sort.Search(len(pluginScanHandler_Found_Params_Versions), func(i int) bool {
+		return pluginScanHandler_Found_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
+	})
+	if index < len(pluginScanHandler_Found_Params_Versions) {
+		if pluginScanHandler_Found_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
+			index--
+		}
+		expectedSize := pluginScanHandler_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 *PluginScanHandler_Proxy) Found(inS Advertisement) (err error) {
+	payload := &pluginScanHandler_Found_Params{
+		inS,
+	}
+	header := bindings.MessageHeader{
+		Type: pluginScanHandler_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 pluginScanHandler_Lost_Params struct {
+	inS Advertisement
+}
+
+func (s *pluginScanHandler_Lost_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 pluginScanHandler_Lost_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
+	bindings.DataHeader{16, 0},
+}
+
+func (s *pluginScanHandler_Lost_Params) Decode(decoder *bindings.Decoder) error {
+	header, err := decoder.StartStruct()
+	if err != nil {
+		return err
+	}
+	index := sort.Search(len(pluginScanHandler_Lost_Params_Versions), func(i int) bool {
+		return pluginScanHandler_Lost_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
+	})
+	if index < len(pluginScanHandler_Lost_Params_Versions) {
+		if pluginScanHandler_Lost_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
+			index--
+		}
+		expectedSize := pluginScanHandler_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 {
+			if err := s.inS.Decode(decoder); err != nil {
+				return err
+			}
+		}
+	}
+	if err := decoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (p *PluginScanHandler_Proxy) Lost(inS Advertisement) (err error) {
+	payload := &pluginScanHandler_Lost_Params{
+		inS,
+	}
+	header := bindings.MessageHeader{
+		Type: pluginScanHandler_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 pluginScanHandler_Stub struct {
+	connector *bindings.Connector
+	impl PluginScanHandler
+}
+
+func NewPluginScanHandlerStub(r PluginScanHandler_Request, impl PluginScanHandler, waiter bindings.AsyncWaiter) *bindings.Stub {
+	connector := bindings.NewConnector(r.PassMessagePipe(), waiter)
+	return bindings.NewStub(connector, &pluginScanHandler_Stub{connector, impl})
+}
+
+func (s *pluginScanHandler_Stub) Accept(message *bindings.Message) (err error) {
+	switch message.Header.Type {
+	case pluginScanHandler_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 pluginScanHandler_Found_Params
+		if err := message.DecodePayload(&request); err != nil {
+			return err
+		}
+		err = s.impl.Found(request.inS)
+		if err != nil {
+			return
+		}
+	case pluginScanHandler_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 pluginScanHandler_Lost_Params
+		if err := message.DecodePayload(&request); err != nil {
+			return err
+		}
+		err = s.impl.Lost(request.inS)
+		if err != nil {
+			return
+		}
+	default:
+		return &bindings.ValidationError{
+			bindings.MessageHeaderUnknownMethod,
+			fmt.Sprintf("unknown method %v", message.Header.Type),
+		}
+	}
+	return
+}
+
+type PluginStopper interface {
+	Stop() (err error)
+}
+
+var pluginStopper_Name = "ble::PluginStopper"
+
+type PluginStopper_Request bindings.InterfaceRequest
+
+func (r *PluginStopper_Request) Name() string {
+	return pluginStopper_Name
+}
+
+type PluginStopper_Pointer bindings.InterfacePointer
+
+func (p *PluginStopper_Pointer) Name() string {
+	return pluginStopper_Name
+}
+
+type PluginStopper_ServiceFactory struct{
+	Delegate PluginStopper_Factory
+}
+
+type PluginStopper_Factory interface {
+	Create(request PluginStopper_Request)
+}
+
+func (f *PluginStopper_ServiceFactory) Name() string {
+	return pluginStopper_Name
+}
+
+func (f *PluginStopper_ServiceFactory) Create(messagePipe system.MessagePipeHandle) {
+	request := PluginStopper_Request{bindings.NewMessagePipeHandleOwner(messagePipe)}
+	f.Delegate.Create(request)
+}
+
+// CreateMessagePipeForPluginStopper creates a message pipe for use with the
+// PluginStopper interface with a PluginStopper_Request on one end and a PluginStopper_Pointer on the other.
+func CreateMessagePipeForPluginStopper() (PluginStopper_Request, PluginStopper_Pointer) {
+        r, p := bindings.CreateMessagePipeForMojoInterface()
+        return PluginStopper_Request(r), PluginStopper_Pointer(p)
+}
+
+const pluginStopper_Stop_Name uint32 = 0
+
+type PluginStopper_Proxy struct {
+	router *bindings.Router
+	ids bindings.Counter
+}
+
+func NewPluginStopperProxy(p PluginStopper_Pointer, waiter bindings.AsyncWaiter) *PluginStopper_Proxy {
+	return &PluginStopper_Proxy{
+		bindings.NewRouter(p.PassMessagePipe(), waiter),
+		bindings.NewCounter(),
+	}
+}
+
+func (p *PluginStopper_Proxy) Close_Proxy() {
+	p.router.Close()
+}
+
+type pluginStopper_Stop_Params struct {
+}
+
+func (s *pluginStopper_Stop_Params) Encode(encoder *bindings.Encoder) error {
+	encoder.StartStruct(0, 0)
+	if err := encoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+var pluginStopper_Stop_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
+	bindings.DataHeader{8, 0},
+}
+
+func (s *pluginStopper_Stop_Params) Decode(decoder *bindings.Decoder) error {
+	header, err := decoder.StartStruct()
+	if err != nil {
+		return err
+	}
+	index := sort.Search(len(pluginStopper_Stop_Params_Versions), func(i int) bool {
+		return pluginStopper_Stop_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
+	})
+	if index < len(pluginStopper_Stop_Params_Versions) {
+		if pluginStopper_Stop_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
+			index--
+		}
+		expectedSize := pluginStopper_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 err := decoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (p *PluginStopper_Proxy) Stop() (err error) {
+	payload := &pluginStopper_Stop_Params{
+	}
+	header := bindings.MessageHeader{
+		Type: pluginStopper_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 pluginStopper_Stub struct {
+	connector *bindings.Connector
+	impl PluginStopper
+}
+
+func NewPluginStopperStub(r PluginStopper_Request, impl PluginStopper, waiter bindings.AsyncWaiter) *bindings.Stub {
+	connector := bindings.NewConnector(r.PassMessagePipe(), waiter)
+	return bindings.NewStub(connector, &pluginStopper_Stub{connector, impl})
+}
+
+func (s *pluginStopper_Stub) Accept(message *bindings.Message) (err error) {
+	switch message.Header.Type {
+	case pluginStopper_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 pluginStopper_Stop_Params
+		if err := message.DecodePayload(&request); err != nil {
+			return err
+		}
+		err = s.impl.Stop()
+		if err != nil {
+			return
+		}
+	default:
+		return &bindings.ValidationError{
+			bindings.MessageHeaderUnknownMethod,
+			fmt.Sprintf("unknown method %v", message.Header.Type),
+		}
+	}
+	return
+}
+
+type Advertisement struct {
+	ServiceId []uint8
+	Service Service
+}
+
+func (s *Advertisement) Encode(encoder *bindings.Encoder) error {
+	encoder.StartStruct(16, 0)
+	if err := encoder.WritePointer(); err != nil {
+		return err
+	}
+	encoder.StartArray(uint32(len(s.ServiceId)), 8)
+	for _, elem0 := range s.ServiceId {
+		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 := s.Service.Encode(encoder); err != nil {
+		return err
+	}
+	if err := encoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+var advertisement_Versions []bindings.DataHeader = []bindings.DataHeader{
+	bindings.DataHeader{24, 0},
+}
+
+func (s *Advertisement) Decode(decoder *bindings.Decoder) error {
+	header, err := decoder.StartStruct()
+	if err != nil {
+		return err
+	}
+	index := sort.Search(len(advertisement_Versions), func(i int) bool {
+		return advertisement_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
+	})
+	if index < len(advertisement_Versions) {
+		if advertisement_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
+			index--
+		}
+		expectedSize := advertisement_Versions[index].Size
+		if expectedSize != header.Size {
+			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
+				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
+			}
+		}
+	}
+	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.ServiceId = make([]uint8, len0)
+			for i0 := uint32(0); i0 < len0; i0++ {
+				value1, err := decoder.ReadUint8()
+				if err != nil {
+					return err
+				}
+				s.ServiceId[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 {
+			if err := s.Service.Decode(decoder); err != nil {
+				return err
+			}
+		}
+	}
+	if err := decoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+type Service struct {
+	InstanceId []uint8
+	Attributes map[string]string
+}
+
+func (s *Service) Encode(encoder *bindings.Encoder) error {
+	encoder.StartStruct(16, 0)
+	if err := encoder.WritePointer(); err != nil {
+		return err
+	}
+	encoder.StartArray(uint32(len(s.InstanceId)), 8)
+	for _, elem0 := range s.InstanceId {
+		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
+	}
+	encoder.StartMap()
+	{
+		var keys0 []string
+		var values0 []string
+		for key0, value0 := range s.Attributes {
+			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.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+var service_Versions []bindings.DataHeader = []bindings.DataHeader{
+	bindings.DataHeader{24, 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.InstanceId = make([]uint8, len0)
+			for i0 := uint32(0); i0 < len0; i0++ {
+				value1, err := decoder.ReadUint8()
+				if err != nil {
+					return err
+				}
+				s.InstanceId[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 {
+			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.Attributes = map0
+		}
+	}
+	if err := decoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
diff --git a/go/src/mojom/v.io/x/ref/services/discovery/discovery/discovery.mojom.go b/go/src/mojom/v.io/x/ref/services/discovery/discovery/discovery.mojom.go
new file mode 100644
index 0000000..9ad87c7
--- /dev/null
+++ b/go/src/mojom/v.io/x/ref/services/discovery/discovery/discovery.mojom.go
@@ -0,0 +1,1183 @@
+// 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/v.io/x/ref/services/discovery/discovery.mojom
+//
+
+package discovery
+
+import (
+	"fmt"
+	"mojo/public/go/bindings"
+	"mojo/public/go/system"
+	"sort"
+)
+
+type Discovery interface {
+	Advertise(inService Service) (outHandle DiscoveryStopper_Pointer, err error)
+	Scan(inQuery string, inHandler DiscoveryHandler_Pointer) (outHandle DiscoveryStopper_Pointer, err error)
+}
+
+var discovery_Name = "discovery::Discovery"
+
+type Discovery_Request bindings.InterfaceRequest
+
+func (r *Discovery_Request) Name() string {
+	return discovery_Name
+}
+
+type Discovery_Pointer bindings.InterfacePointer
+
+func (p *Discovery_Pointer) Name() string {
+	return discovery_Name
+}
+
+type Discovery_ServiceFactory struct{
+	Delegate Discovery_Factory
+}
+
+type Discovery_Factory interface {
+	Create(request Discovery_Request)
+}
+
+func (f *Discovery_ServiceFactory) Name() string {
+	return discovery_Name
+}
+
+func (f *Discovery_ServiceFactory) Create(messagePipe system.MessagePipeHandle) {
+	request := Discovery_Request{bindings.NewMessagePipeHandleOwner(messagePipe)}
+	f.Delegate.Create(request)
+}
+
+// CreateMessagePipeForDiscovery creates a message pipe for use with the
+// Discovery interface with a Discovery_Request on one end and a Discovery_Pointer on the other.
+func CreateMessagePipeForDiscovery() (Discovery_Request, Discovery_Pointer) {
+        r, p := bindings.CreateMessagePipeForMojoInterface()
+        return Discovery_Request(r), Discovery_Pointer(p)
+}
+
+const discovery_Advertise_Name uint32 = 0
+const discovery_Scan_Name uint32 = 1
+
+type Discovery_Proxy struct {
+	router *bindings.Router
+	ids bindings.Counter
+}
+
+func NewDiscoveryProxy(p Discovery_Pointer, waiter bindings.AsyncWaiter) *Discovery_Proxy {
+	return &Discovery_Proxy{
+		bindings.NewRouter(p.PassMessagePipe(), waiter),
+		bindings.NewCounter(),
+	}
+}
+
+func (p *Discovery_Proxy) Close_Proxy() {
+	p.router.Close()
+}
+
+type discovery_Advertise_Params struct {
+	inService Service
+}
+
+func (s *discovery_Advertise_Params) Encode(encoder *bindings.Encoder) error {
+	encoder.StartStruct(8, 0)
+	if err := encoder.WritePointer(); err != nil {
+		return err
+	}
+	if err := s.inService.Encode(encoder); err != nil {
+		return err
+	}
+	if err := encoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+var discovery_Advertise_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
+	bindings.DataHeader{16, 0},
+}
+
+func (s *discovery_Advertise_Params) Decode(decoder *bindings.Decoder) error {
+	header, err := decoder.StartStruct()
+	if err != nil {
+		return err
+	}
+	index := sort.Search(len(discovery_Advertise_Params_Versions), func(i int) bool {
+		return discovery_Advertise_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
+	})
+	if index < len(discovery_Advertise_Params_Versions) {
+		if discovery_Advertise_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
+			index--
+		}
+		expectedSize := discovery_Advertise_Params_Versions[index].Size
+		if expectedSize != header.Size {
+			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
+				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
+			}
+		}
+	}
+	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.inService.Decode(decoder); err != nil {
+				return err
+			}
+		}
+	}
+	if err := decoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+type discovery_Advertise_ResponseParams struct {
+	outHandle DiscoveryStopper_Pointer
+}
+
+func (s *discovery_Advertise_ResponseParams) Encode(encoder *bindings.Encoder) error {
+	encoder.StartStruct(8, 0)
+	if err := encoder.WriteInterface(s.outHandle.PassMessagePipe()); err != nil {
+		return err
+	}
+	if err := encoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+var discovery_Advertise_ResponseParams_Versions []bindings.DataHeader = []bindings.DataHeader{
+	bindings.DataHeader{16, 0},
+}
+
+func (s *discovery_Advertise_ResponseParams) Decode(decoder *bindings.Decoder) error {
+	header, err := decoder.StartStruct()
+	if err != nil {
+		return err
+	}
+	index := sort.Search(len(discovery_Advertise_ResponseParams_Versions), func(i int) bool {
+		return discovery_Advertise_ResponseParams_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
+	})
+	if index < len(discovery_Advertise_ResponseParams_Versions) {
+		if discovery_Advertise_ResponseParams_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
+			index--
+		}
+		expectedSize := discovery_Advertise_ResponseParams_Versions[index].Size
+		if expectedSize != header.Size {
+			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
+				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
+			}
+		}
+	}
+	if header.ElementsOrVersion >= 0 {
+		handle0, err := decoder.ReadInterface()
+		if err != nil {
+			return err
+		}
+		if handle0.IsValid() {
+			handleOwner := bindings.NewMessagePipeHandleOwner(handle0)
+			s.outHandle = DiscoveryStopper_Pointer{handleOwner}
+		} else {
+			return &bindings.ValidationError{bindings.UnexpectedInvalidHandle, "unexpected invalid handle"}
+		}
+	}
+	if err := decoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (p *Discovery_Proxy) Advertise(inService Service) (outHandle DiscoveryStopper_Pointer, err error) {
+	payload := &discovery_Advertise_Params{
+		inService,
+	}
+	header := bindings.MessageHeader{
+		Type: discovery_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, discovery_Advertise_Name; got != want {
+		err = &bindings.ValidationError{bindings.MessageHeaderUnknownMethod,
+			fmt.Sprintf("invalid method in response: expected %v, got %v", want, got),
+		}
+		return
+	}
+	var response discovery_Advertise_ResponseParams
+	if err = readResult.Message.DecodePayload(&response); err != nil {
+		p.Close_Proxy()
+		return
+	}
+	outHandle = response.outHandle
+	return
+}
+
+type discovery_Scan_Params struct {
+	inQuery string
+	inHandler DiscoveryHandler_Pointer
+}
+
+func (s *discovery_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.inHandler.PassMessagePipe()); err != nil {
+		return err
+	}
+	if err := encoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+var discovery_Scan_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
+	bindings.DataHeader{24, 0},
+}
+
+func (s *discovery_Scan_Params) Decode(decoder *bindings.Decoder) error {
+	header, err := decoder.StartStruct()
+	if err != nil {
+		return err
+	}
+	index := sort.Search(len(discovery_Scan_Params_Versions), func(i int) bool {
+		return discovery_Scan_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
+	})
+	if index < len(discovery_Scan_Params_Versions) {
+		if discovery_Scan_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
+			index--
+		}
+		expectedSize := discovery_Scan_Params_Versions[index].Size
+		if expectedSize != header.Size {
+			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
+				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
+			}
+		}
+	}
+	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.inHandler = DiscoveryHandler_Pointer{handleOwner}
+		} else {
+			return &bindings.ValidationError{bindings.UnexpectedInvalidHandle, "unexpected invalid handle"}
+		}
+	}
+	if err := decoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+type discovery_Scan_ResponseParams struct {
+	outHandle DiscoveryStopper_Pointer
+}
+
+func (s *discovery_Scan_ResponseParams) Encode(encoder *bindings.Encoder) error {
+	encoder.StartStruct(8, 0)
+	if err := encoder.WriteInterface(s.outHandle.PassMessagePipe()); err != nil {
+		return err
+	}
+	if err := encoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+var discovery_Scan_ResponseParams_Versions []bindings.DataHeader = []bindings.DataHeader{
+	bindings.DataHeader{16, 0},
+}
+
+func (s *discovery_Scan_ResponseParams) Decode(decoder *bindings.Decoder) error {
+	header, err := decoder.StartStruct()
+	if err != nil {
+		return err
+	}
+	index := sort.Search(len(discovery_Scan_ResponseParams_Versions), func(i int) bool {
+		return discovery_Scan_ResponseParams_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
+	})
+	if index < len(discovery_Scan_ResponseParams_Versions) {
+		if discovery_Scan_ResponseParams_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
+			index--
+		}
+		expectedSize := discovery_Scan_ResponseParams_Versions[index].Size
+		if expectedSize != header.Size {
+			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
+				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
+			}
+		}
+	}
+	if header.ElementsOrVersion >= 0 {
+		handle0, err := decoder.ReadInterface()
+		if err != nil {
+			return err
+		}
+		if handle0.IsValid() {
+			handleOwner := bindings.NewMessagePipeHandleOwner(handle0)
+			s.outHandle = DiscoveryStopper_Pointer{handleOwner}
+		} else {
+			return &bindings.ValidationError{bindings.UnexpectedInvalidHandle, "unexpected invalid handle"}
+		}
+	}
+	if err := decoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (p *Discovery_Proxy) Scan(inQuery string, inHandler DiscoveryHandler_Pointer) (outHandle DiscoveryStopper_Pointer, err error) {
+	payload := &discovery_Scan_Params{
+		inQuery,
+		inHandler,
+	}
+	header := bindings.MessageHeader{
+		Type: discovery_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, discovery_Scan_Name; got != want {
+		err = &bindings.ValidationError{bindings.MessageHeaderUnknownMethod,
+			fmt.Sprintf("invalid method in response: expected %v, got %v", want, got),
+		}
+		return
+	}
+	var response discovery_Scan_ResponseParams
+	if err = readResult.Message.DecodePayload(&response); err != nil {
+		p.Close_Proxy()
+		return
+	}
+	outHandle = response.outHandle
+	return
+}
+
+type discovery_Stub struct {
+	connector *bindings.Connector
+	impl Discovery
+}
+
+func NewDiscoveryStub(r Discovery_Request, impl Discovery, waiter bindings.AsyncWaiter) *bindings.Stub {
+	connector := bindings.NewConnector(r.PassMessagePipe(), waiter)
+	return bindings.NewStub(connector, &discovery_Stub{connector, impl})
+}
+
+func (s *discovery_Stub) Accept(message *bindings.Message) (err error) {
+	switch message.Header.Type {
+	case discovery_Advertise_Name:
+		if message.Header.Flags != bindings.MessageExpectsResponseFlag {
+			return &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
+				fmt.Sprintf("invalid message header flag: %v", message.Header.Flags),
+			}
+		}
+		var request discovery_Advertise_Params
+		if err := message.DecodePayload(&request); err != nil {
+			return err
+		}
+		var response discovery_Advertise_ResponseParams
+		response.outHandle, err = s.impl.Advertise(request.inService)
+		if err != nil {
+			return
+		}
+		header := bindings.MessageHeader{
+			Type: discovery_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 discovery_Scan_Name:
+		if message.Header.Flags != bindings.MessageExpectsResponseFlag {
+			return &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
+				fmt.Sprintf("invalid message header flag: %v", message.Header.Flags),
+			}
+		}
+		var request discovery_Scan_Params
+		if err := message.DecodePayload(&request); err != nil {
+			return err
+		}
+		var response discovery_Scan_ResponseParams
+		response.outHandle, err = s.impl.Scan(request.inQuery, request.inHandler)
+		if err != nil {
+			return
+		}
+		header := bindings.MessageHeader{
+			Type: discovery_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)
+	default:
+		return &bindings.ValidationError{
+			bindings.MessageHeaderUnknownMethod,
+			fmt.Sprintf("unknown method %v", message.Header.Type),
+		}
+	}
+	return
+}
+
+type DiscoveryStopper interface {
+	Stop() (err error)
+}
+
+var discoveryStopper_Name = "discovery::DiscoveryStopper"
+
+type DiscoveryStopper_Request bindings.InterfaceRequest
+
+func (r *DiscoveryStopper_Request) Name() string {
+	return discoveryStopper_Name
+}
+
+type DiscoveryStopper_Pointer bindings.InterfacePointer
+
+func (p *DiscoveryStopper_Pointer) Name() string {
+	return discoveryStopper_Name
+}
+
+type DiscoveryStopper_ServiceFactory struct{
+	Delegate DiscoveryStopper_Factory
+}
+
+type DiscoveryStopper_Factory interface {
+	Create(request DiscoveryStopper_Request)
+}
+
+func (f *DiscoveryStopper_ServiceFactory) Name() string {
+	return discoveryStopper_Name
+}
+
+func (f *DiscoveryStopper_ServiceFactory) Create(messagePipe system.MessagePipeHandle) {
+	request := DiscoveryStopper_Request{bindings.NewMessagePipeHandleOwner(messagePipe)}
+	f.Delegate.Create(request)
+}
+
+// CreateMessagePipeForDiscoveryStopper creates a message pipe for use with the
+// DiscoveryStopper interface with a DiscoveryStopper_Request on one end and a DiscoveryStopper_Pointer on the other.
+func CreateMessagePipeForDiscoveryStopper() (DiscoveryStopper_Request, DiscoveryStopper_Pointer) {
+        r, p := bindings.CreateMessagePipeForMojoInterface()
+        return DiscoveryStopper_Request(r), DiscoveryStopper_Pointer(p)
+}
+
+const discoveryStopper_Stop_Name uint32 = 0
+
+type DiscoveryStopper_Proxy struct {
+	router *bindings.Router
+	ids bindings.Counter
+}
+
+func NewDiscoveryStopperProxy(p DiscoveryStopper_Pointer, waiter bindings.AsyncWaiter) *DiscoveryStopper_Proxy {
+	return &DiscoveryStopper_Proxy{
+		bindings.NewRouter(p.PassMessagePipe(), waiter),
+		bindings.NewCounter(),
+	}
+}
+
+func (p *DiscoveryStopper_Proxy) Close_Proxy() {
+	p.router.Close()
+}
+
+type discoveryStopper_Stop_Params struct {
+}
+
+func (s *discoveryStopper_Stop_Params) Encode(encoder *bindings.Encoder) error {
+	encoder.StartStruct(0, 0)
+	if err := encoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+var discoveryStopper_Stop_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
+	bindings.DataHeader{8, 0},
+}
+
+func (s *discoveryStopper_Stop_Params) Decode(decoder *bindings.Decoder) error {
+	header, err := decoder.StartStruct()
+	if err != nil {
+		return err
+	}
+	index := sort.Search(len(discoveryStopper_Stop_Params_Versions), func(i int) bool {
+		return discoveryStopper_Stop_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
+	})
+	if index < len(discoveryStopper_Stop_Params_Versions) {
+		if discoveryStopper_Stop_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
+			index--
+		}
+		expectedSize := discoveryStopper_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 err := decoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (p *DiscoveryStopper_Proxy) Stop() (err error) {
+	payload := &discoveryStopper_Stop_Params{
+	}
+	header := bindings.MessageHeader{
+		Type: discoveryStopper_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 discoveryStopper_Stub struct {
+	connector *bindings.Connector
+	impl DiscoveryStopper
+}
+
+func NewDiscoveryStopperStub(r DiscoveryStopper_Request, impl DiscoveryStopper, waiter bindings.AsyncWaiter) *bindings.Stub {
+	connector := bindings.NewConnector(r.PassMessagePipe(), waiter)
+	return bindings.NewStub(connector, &discoveryStopper_Stub{connector, impl})
+}
+
+func (s *discoveryStopper_Stub) Accept(message *bindings.Message) (err error) {
+	switch message.Header.Type {
+	case discoveryStopper_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 discoveryStopper_Stop_Params
+		if err := message.DecodePayload(&request); err != nil {
+			return err
+		}
+		err = s.impl.Stop()
+		if err != nil {
+			return
+		}
+	default:
+		return &bindings.ValidationError{
+			bindings.MessageHeaderUnknownMethod,
+			fmt.Sprintf("unknown method %v", message.Header.Type),
+		}
+	}
+	return
+}
+
+type DiscoveryHandler interface {
+	Found(inS Service) (err error)
+	Lost(inId []uint8) (err error)
+}
+
+var discoveryHandler_Name = "discovery::DiscoveryHandler"
+
+type DiscoveryHandler_Request bindings.InterfaceRequest
+
+func (r *DiscoveryHandler_Request) Name() string {
+	return discoveryHandler_Name
+}
+
+type DiscoveryHandler_Pointer bindings.InterfacePointer
+
+func (p *DiscoveryHandler_Pointer) Name() string {
+	return discoveryHandler_Name
+}
+
+type DiscoveryHandler_ServiceFactory struct{
+	Delegate DiscoveryHandler_Factory
+}
+
+type DiscoveryHandler_Factory interface {
+	Create(request DiscoveryHandler_Request)
+}
+
+func (f *DiscoveryHandler_ServiceFactory) Name() string {
+	return discoveryHandler_Name
+}
+
+func (f *DiscoveryHandler_ServiceFactory) Create(messagePipe system.MessagePipeHandle) {
+	request := DiscoveryHandler_Request{bindings.NewMessagePipeHandleOwner(messagePipe)}
+	f.Delegate.Create(request)
+}
+
+// CreateMessagePipeForDiscoveryHandler creates a message pipe for use with the
+// DiscoveryHandler interface with a DiscoveryHandler_Request on one end and a DiscoveryHandler_Pointer on the other.
+func CreateMessagePipeForDiscoveryHandler() (DiscoveryHandler_Request, DiscoveryHandler_Pointer) {
+        r, p := bindings.CreateMessagePipeForMojoInterface()
+        return DiscoveryHandler_Request(r), DiscoveryHandler_Pointer(p)
+}
+
+const discoveryHandler_Found_Name uint32 = 0
+const discoveryHandler_Lost_Name uint32 = 1
+
+type DiscoveryHandler_Proxy struct {
+	router *bindings.Router
+	ids bindings.Counter
+}
+
+func NewDiscoveryHandlerProxy(p DiscoveryHandler_Pointer, waiter bindings.AsyncWaiter) *DiscoveryHandler_Proxy {
+	return &DiscoveryHandler_Proxy{
+		bindings.NewRouter(p.PassMessagePipe(), waiter),
+		bindings.NewCounter(),
+	}
+}
+
+func (p *DiscoveryHandler_Proxy) Close_Proxy() {
+	p.router.Close()
+}
+
+type discoveryHandler_Found_Params struct {
+	inS Service
+}
+
+func (s *discoveryHandler_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 discoveryHandler_Found_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
+	bindings.DataHeader{16, 0},
+}
+
+func (s *discoveryHandler_Found_Params) Decode(decoder *bindings.Decoder) error {
+	header, err := decoder.StartStruct()
+	if err != nil {
+		return err
+	}
+	index := sort.Search(len(discoveryHandler_Found_Params_Versions), func(i int) bool {
+		return discoveryHandler_Found_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
+	})
+	if index < len(discoveryHandler_Found_Params_Versions) {
+		if discoveryHandler_Found_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
+			index--
+		}
+		expectedSize := discoveryHandler_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 *DiscoveryHandler_Proxy) Found(inS Service) (err error) {
+	payload := &discoveryHandler_Found_Params{
+		inS,
+	}
+	header := bindings.MessageHeader{
+		Type: discoveryHandler_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 discoveryHandler_Lost_Params struct {
+	inId []uint8
+}
+
+func (s *discoveryHandler_Lost_Params) Encode(encoder *bindings.Encoder) error {
+	encoder.StartStruct(8, 0)
+	if err := encoder.WritePointer(); err != nil {
+		return err
+	}
+	encoder.StartArray(uint32(len(s.inId)), 8)
+	for _, elem0 := range s.inId {
+		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 discoveryHandler_Lost_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
+	bindings.DataHeader{16, 0},
+}
+
+func (s *discoveryHandler_Lost_Params) Decode(decoder *bindings.Decoder) error {
+	header, err := decoder.StartStruct()
+	if err != nil {
+		return err
+	}
+	index := sort.Search(len(discoveryHandler_Lost_Params_Versions), func(i int) bool {
+		return discoveryHandler_Lost_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
+	})
+	if index < len(discoveryHandler_Lost_Params_Versions) {
+		if discoveryHandler_Lost_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
+			index--
+		}
+		expectedSize := discoveryHandler_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.inId = make([]uint8, len0)
+			for i0 := uint32(0); i0 < len0; i0++ {
+				value1, err := decoder.ReadUint8()
+				if err != nil {
+					return err
+				}
+				s.inId[i0] = value1
+			}
+			if err := decoder.Finish(); err != nil {
+				return err
+			}
+		}
+	}
+	if err := decoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (p *DiscoveryHandler_Proxy) Lost(inId []uint8) (err error) {
+	payload := &discoveryHandler_Lost_Params{
+		inId,
+	}
+	header := bindings.MessageHeader{
+		Type: discoveryHandler_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 discoveryHandler_Stub struct {
+	connector *bindings.Connector
+	impl DiscoveryHandler
+}
+
+func NewDiscoveryHandlerStub(r DiscoveryHandler_Request, impl DiscoveryHandler, waiter bindings.AsyncWaiter) *bindings.Stub {
+	connector := bindings.NewConnector(r.PassMessagePipe(), waiter)
+	return bindings.NewStub(connector, &discoveryHandler_Stub{connector, impl})
+}
+
+func (s *discoveryHandler_Stub) Accept(message *bindings.Message) (err error) {
+	switch message.Header.Type {
+	case discoveryHandler_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 discoveryHandler_Found_Params
+		if err := message.DecodePayload(&request); err != nil {
+			return err
+		}
+		err = s.impl.Found(request.inS)
+		if err != nil {
+			return
+		}
+	case discoveryHandler_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 discoveryHandler_Lost_Params
+		if err := message.DecodePayload(&request); err != nil {
+			return err
+		}
+		err = s.impl.Lost(request.inId)
+		if err != nil {
+			return
+		}
+	default:
+		return &bindings.ValidationError{
+			bindings.MessageHeaderUnknownMethod,
+			fmt.Sprintf("unknown method %v", message.Header.Type),
+		}
+	}
+	return
+}
+
+type Service struct {
+	InterfaceNames string
+	Attrs map[string]string
+	Addrs []string
+}
+
+func (s *Service) Encode(encoder *bindings.Encoder) error {
+	encoder.StartStruct(24, 0)
+	if err := encoder.WritePointer(); err != nil {
+		return err
+	}
+	if err := encoder.WriteString(s.InterfaceNames); 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{32, 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 {
+			value0, err := decoder.ReadString()
+			if err != nil {
+				return err
+			}
+			s.InterfaceNames = 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
+}
+
diff --git a/go/src/v.io/x/ref/services/discovery/ble/neighborhood.go b/go/src/v.io/x/ref/services/discovery/ble/neighborhood.go
new file mode 100644
index 0000000..301316a
--- /dev/null
+++ b/go/src/v.io/x/ref/services/discovery/ble/neighborhood.go
@@ -0,0 +1,525 @@
+// 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 (
+	"bytes"
+	"encoding/binary"
+	"encoding/hex"
+	"hash/fnv"
+	"log"
+	"sync"
+	"time"
+
+	"mojom/v.io/x/ref/services/discovery/ble/ble"
+
+	"github.com/paypal/gatt"
+	"github.com/paypal/gatt/linux/cmd"
+	"reflect"
+)
+
+func newService(uuid string, serviceId []byte, attributes map[string]string) *gatt.Service {
+	s := gatt.NewService(gatt.MustParseUUID(uuid))
+	for u, v := range attributes {
+		s.AddCharacteristic(gatt.MustParseUUID(u)).SetValue([]byte(v))
+	}
+	s.AddCharacteristic(uniqueServiceId).SetValue(serviceId)
+	return s
+}
+
+var (
+	attrGAPUUID = gatt.UUID16(0x1800)
+
+	attrDeviceNameUUID        = gatt.UUID16(0x2A00)
+	attrAppearanceUUID        = gatt.UUID16(0x2A01)
+	attrPeripheralPrivacyUUID = gatt.UUID16(0x2A02)
+	attrReconnectionAddrUUID  = gatt.UUID16(0x2A03)
+	attrPeferredParamsUUID    = gatt.UUID16(0x2A04)
+
+	attrGATTUUID           = gatt.UUID16(0x1801)
+	attrServiceChangedUUID = gatt.UUID16(0x2A05)
+)
+
+const (
+	manufacturerId = uint16(1001)
+)
+
+var uniqueServiceId gatt.UUID
+
+func init() {
+	uniqueServiceId = gatt.MustParseUUID("f6445c7f-73fd-4b8d-98d0-c4e02b087844")
+
+}
+
+// https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml
+var gapCharAppearanceGenericComputer = []byte{0x00, 0x80}
+
+func newGapService(name string) *gatt.Service {
+	s := gatt.NewService(attrGAPUUID)
+	s.AddCharacteristic(attrDeviceNameUUID).SetValue([]byte(name))
+	s.AddCharacteristic(attrAppearanceUUID).SetValue(gapCharAppearanceGenericComputer)
+	s.AddCharacteristic(attrPeripheralPrivacyUUID).SetValue([]byte{0x00})
+	s.AddCharacteristic(attrReconnectionAddrUUID).SetValue([]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
+	s.AddCharacteristic(attrPeferredParamsUUID).SetValue([]byte{0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0xd0, 0x07})
+	return s
+}
+
+func newGattService() *gatt.Service {
+	s := gatt.NewService(attrGATTUUID)
+	s.AddCharacteristic(attrServiceChangedUUID).HandleNotifyFunc(
+		func(r gatt.Request, n gatt.Notifier) {})
+	return s
+}
+
+var gattOptions = []gatt.Option{
+	gatt.LnxMaxConnections(1),
+	gatt.LnxDeviceID(-1, true),
+	gatt.LnxSetAdvertisingParameters(&cmd.LESetAdvertisingParameters{
+		// Set an advertising rate of 150ms.  This value is multipled by
+		// 0.625ms to get the actual rate.
+		AdvertisingIntervalMin: 0x00f4,
+		AdvertisingIntervalMax: 0x00f4,
+		AdvertisingChannelMap:  0x7,
+	}),
+}
+
+type scanner struct {
+	mu         sync.Mutex
+	uuid       string
+	attributes map[string]string
+	ch         chan *update
+	done       bool
+}
+
+func (s *scanner) handleChange(id string, oldService *ble.Service, newService *ble.Service) {
+	s.mu.Lock()
+	defer s.mu.Unlock()
+	if s.done {
+		return
+	}
+	matches := s.matches(id, newService)
+	oldMatches := s.matches(id, oldService)
+	uuid, err := hex.DecodeString(id)
+	if err != nil {
+		log.Fatal("Failed to decode uuid:",id,",",err)
+	}
+	if oldMatches {
+		s.ch <- &update{
+			found: false,
+			adv: ble.Advertisement{
+				ServiceId: uuid,
+				Service: *oldService,
+			},
+		}
+	}
+
+	if matches {
+		s.ch <- &update{
+			found: true,
+			adv: ble.Advertisement{
+				ServiceId: uuid,
+				Service: *newService,
+			},
+		}
+	}
+}
+
+func (s *scanner) stop() {
+	s.mu.Lock()
+	s.done = true
+	s.mu.Unlock()
+}
+
+func attributeMatch(filter map[string]string, attr map[string]string) bool {
+	for k, v := range filter {
+		if attr[k] != v {
+			return false
+		}
+	}
+	return true
+}
+
+func (s *scanner) matches(id string, service *ble.Service) bool {
+	if service == nil {
+		return false
+	}
+	return (s.uuid == "" || id == s.uuid) && attributeMatch(s.attributes, service.Attributes)
+}
+
+type update struct {
+	found   bool
+	adv ble.Advertisement
+}
+
+type bleCacheEntry struct {
+	id       string
+	name     string
+	services map[string]*ble.Service
+	hash     string
+	lastSeen time.Time
+}
+
+type bleNeighborHood struct {
+	mu sync.Mutex
+
+	neighborsHashCache map[string]*bleCacheEntry
+	knownNeighbors		map[string]*bleCacheEntry
+	services           map[string]*gatt.Service
+	// Scanners out standing calls to Scan that need be serviced.  Each time a
+	// new device appears or disappears, the scanner is notified of the event.
+	scanners map[int64]*scanner
+	// If both sides try to connect to each other at the same time, then only
+	// one will succeed and the other hangs forever.  This means that the side
+	// that hangs won't ever start scanning or advertising again.  To avoid this
+	// we timeout any connections that don't finish in under 4 seconds.  This
+	// channel is closed when a connection has been made successfully, to notify
+	// the cancel goroutine that it doesn't need to do anything.
+	timeoutMap map[string]chan struct{}
+	// The hash that we use to avoid multiple connections are stored in the
+	// advertising data, so we need to store somewhere in the bleNeighorhood
+	// until we are ready to save the new device data.  This map is
+	// the keeper of the data.
+	pendingHashMap map[string]string
+	name           string
+	device         gatt.Device
+	isStopped      bool
+	nextScanId     int64
+}
+
+func newBleNeighborhood(name string) (*bleNeighborHood, error) {
+	b := &bleNeighborHood{
+		neighborsHashCache: make(map[string]*bleCacheEntry),
+		knownNeighbors: make(map[string]*bleCacheEntry),
+		name:               name,
+		services:           make(map[string]*gatt.Service),
+		scanners:           make(map[int64]*scanner),
+		timeoutMap:         make(map[string]chan struct{}),
+		pendingHashMap:     make(map[string]string),
+	}
+	if err := b.startBLEService(); err != nil {
+		return nil, err
+	}
+	return b, nil
+}
+
+func (b *bleNeighborHood) addService(id string, service ble.Service) {
+	b.mu.Lock()
+	b.services[id] = newService(id, service.InstanceId, service.Attributes)
+	v := make([]*gatt.Service, 0, len(b.services))
+	for _, s := range b.services {
+		v = append(v, s)
+	}
+	b.mu.Unlock()
+	b.device.SetServices(v)
+}
+
+func (b *bleNeighborHood) removeService(id string) {
+	b.mu.Lock()
+	delete(b.services, id)
+	v := make([]*gatt.Service, 0, len(b.services))
+	for _, s := range b.services {
+		v = append(v, s)
+	}
+	b.mu.Unlock()
+	b.device.SetServices(v)
+}
+
+func (b *bleNeighborHood) addScanner(uuid *[]byte, attr map[string]string, ch chan *update) int64 {
+	s := &scanner{
+		attributes: attr,
+		ch:         ch,
+	}
+	if uuid != nil {
+		s.uuid = hex.EncodeToString(*uuid)
+	}
+	b.mu.Lock()
+	id := b.nextScanId
+	b.nextScanId++
+	b.scanners[id] = s
+	b.mu.Unlock()
+	return id
+}
+
+func (b *bleNeighborHood) removeScanner(id int64) {
+	b.mu.Lock()
+	scanner, found := b.scanners[id]
+	if found {
+		scanner.stop()
+	}
+	delete(b.scanners, id)
+	b.mu.Unlock()
+}
+
+func (b *bleNeighborHood) Stop() error {
+	b.mu.Lock()
+	b.isStopped = true
+	b.mu.Unlock()
+	b.device.StopAdvertising()
+	b.device.StopScanning()
+	return nil
+}
+
+func (b *bleNeighborHood) advertiseAndScan() {
+	b.mu.Lock()
+	isStopped := b.isStopped
+	b.mu.Unlock()
+	if isStopped {
+		log.Println("Quitting")
+		return
+	}
+	log.Println("starting advertisement and scanning")
+	b.device.Advertise(b.computeAdvertisement())
+	b.device.Scan([]gatt.UUID{}, false)
+}
+
+// seenHash returns
+func (b *bleNeighborHood) seenHash(id string, h string) bool {
+	log.Println("Checking for existence of", h)
+	b.mu.Lock()
+	defer b.mu.Unlock()
+	entry, ok := b.neighborsHashCache[h]
+	if !ok {
+		b.pendingHashMap[id] = h
+		return false
+	}
+
+	if entry.id != id {
+		// This can happen either because two different devices chose the same
+		// endpoint and name, or that one device changed its mac address.  It
+		// seems more likely that the latter happened
+		// TODO(bjornick): Deal with the first case.
+		entry.id = id
+	}
+	entry.lastSeen = time.Now()
+	log.Println("Skipping connect because hashes match")
+	return true
+}
+
+// shouldConnect returns true if a connection should be made to p to get an update on the
+// state of the services on that device.
+func (b *bleNeighborHood) shouldConnect(p gatt.Peripheral, a *gatt.Advertisement) bool {
+	md := a.ManufacturerData
+	// The manufuacture data for other vanadium devices have the format:
+	// 0xe9 0x03 <length> <hash>
+	if len(md) < 2 {
+		return false
+	}
+	if md[0] != uint8(0xe9) || md[1] != uint8(0x03) {
+		return false
+	}
+	hash := md[3:]
+	return !b.seenHash(p.ID(), hex.EncodeToString(hash))
+}
+
+func (b *bleNeighborHood) getAllServices(p gatt.Peripheral) {
+	log.Println("Connected to device")
+
+	b.mu.Lock()
+	h := b.pendingHashMap[p.ID()]
+	delete(b.pendingHashMap, p.ID())
+	b.mu.Unlock()
+	defer func() {
+		b.mu.Lock()
+		ch := b.timeoutMap[p.ID()]
+		delete(b.timeoutMap, p.ID())
+		b.mu.Unlock()
+		if ch != nil {
+			log.Println("Closing channel")
+			close(ch)
+		}
+		p.Device().CancelConnection(p)
+		b.advertiseAndScan()
+	}()
+	/*
+		if err := p.SetMTU(500); err != nil {
+			log.Errorf("Failed to set MTU, err: %s", err)
+			return
+		}
+	*/
+
+	log.Println("Scanning for services")
+	ss, err := p.DiscoverServices(nil)
+
+	if err != nil {
+		log.Printf("Failed to discover services, err: %s\n", err)
+		return
+	}
+
+	services := map[string]*ble.Service{}
+	var name string
+	for _, s := range ss {
+		if s.UUID().Equal(attrGAPUUID) {
+			continue
+		}
+
+		cs, err := p.DiscoverCharacteristics(nil, s)
+		if err != nil {
+			log.Printf("Failed to discover characteristics: %s\n", err)
+			continue
+		}
+
+		charMap := make(map[string]string)
+		uniqueId := []byte{}
+		for _, c := range cs {
+			if s.UUID().Equal(attrGATTUUID) {
+				if !c.UUID().Equal(attrDeviceNameUUID) {
+					continue
+				}
+				v, err := p.ReadLongCharacteristic(c)
+				if err != nil {
+					log.Printf("Failed to read the name: %v\n", err)
+					continue
+
+				}
+				name = string(v)
+				continue
+			}
+			key := c.UUID().String()
+			v, err := p.ReadLongCharacteristic(c)
+			if err != nil {
+				log.Printf("Failed to read the characteristc (%s): %v\n", key, err)
+				continue
+
+			}
+
+			if c.UUID().Equal(uniqueServiceId) {
+				uniqueId = v
+				continue
+			}
+			charMap[key] = string(v)
+		}
+		services[s.UUID().String()] = &ble.Service{
+			Attributes: charMap,
+			InstanceId:  uniqueId,
+		}
+	}
+	b.saveDevice(h, p.ID(), name, services)
+}
+
+func (b *bleNeighborHood) startBLEService() error {
+	d, err := gatt.NewDevice(gattOptions...)
+	if err != nil {
+		return err
+	}
+	onPeriphDiscovered := func(p gatt.Peripheral, a *gatt.Advertisement, rssi int) {
+		log.Printf("Found a device (%s)!\n", p.Name())
+		if b.shouldConnect(p, a) {
+			log.Println("trying to connect to ", p.Name())
+			// We stop the scanning and advertising so we can connect to the new device.
+			// If one device is changing too frequently we might never find all the devices,
+			// since we restart the scan every time we finish connecting, but hopefully
+			// that is rare.
+			p.Device().StopScanning()
+			p.Device().StopAdvertising()
+			p.Device().Connect(p)
+			b.mu.Lock()
+			cancel := make(chan struct{}, 1)
+			b.timeoutMap[p.ID()] = cancel
+			b.mu.Unlock()
+			go func() {
+				select {
+				case <-time.After(4 * time.Second):
+					p.Device().CancelConnection(p)
+					b.advertiseAndScan()
+				case <-cancel:
+				}
+			}()
+		}
+	}
+
+	onPeriphConnected := func(p gatt.Peripheral, err error) {
+		if err != nil {
+			log.Println("Failed to connect:", err)
+			return
+		}
+		b.getAllServices(p)
+	}
+
+	onStateChanged := func(d gatt.Device, s gatt.State) {
+		log.Printf("State: %s\n", s)
+		switch s {
+		case gatt.StatePoweredOn:
+			d.AddService(newGapService(b.name))
+			d.AddService(newGattService())
+
+			b.advertiseAndScan()
+		default:
+			d.StopScanning()
+
+		}
+	}
+
+	d.Handle(
+		gatt.CentralConnected(func(c gatt.Central) { log.Printf("Connect: %v\n", c.ID()) }),
+		gatt.CentralDisconnected(func(c gatt.Central) { log.Printf("Disconnected: %v\n", c.ID()) }),
+		gatt.PeripheralDiscovered(onPeriphDiscovered),
+		gatt.PeripheralConnected(onPeriphConnected),
+	)
+
+	d.Init(onStateChanged)
+	b.device = d
+	return nil
+}
+
+func (b *bleNeighborHood) saveDevice(hash string, id string, name string, services map[string]*ble.Service) {
+	b.mu.Lock()
+	defer b.mu.Unlock()
+	_, found := b.neighborsHashCache[hash]
+	if found {
+		log.Printf("Skipping a new save for the same hash (%s) for %s\n",
+			hash, name)
+		return
+	}
+	oldServices := map[string]*ble.Service{}
+	if oldEntry, ok := b.knownNeighbors[id]; ok {
+		oldServices = oldEntry.services
+	}
+
+	newEntry := &bleCacheEntry{
+		id: id,
+		hash:     hash,
+		name:     name,
+		services: services,
+		lastSeen: time.Now(),
+	}
+	b.neighborsHashCache[hash] = newEntry
+	b.knownNeighbors[id] = newEntry
+	log.Println("Looking through", len(b.scanners), "scanners *****")
+	for _, s := range b.scanners {
+		for id, oldService := range oldServices {
+			newValue := services[id]
+			if !reflect.DeepEqual(oldService, newValue) {
+				s.handleChange(id, oldService, newValue)
+			}
+		}
+
+		for id, newService := range newEntry.services {
+			if _, ok := oldServices[id]; !ok {
+				s.handleChange(id, nil, newService)
+			}
+		}
+	}
+
+}
+
+func (b *bleNeighborHood) computeAdvertisement() *gatt.AdvPacket {
+	// The hash is:
+	// Hash(Hash(name),Hash(b.endpoints))
+	hasher := fnv.New64()
+	nameHasher := fnv.New64()
+	nameHasher.Write([]byte(b.name))
+	binary.Write(hasher, binary.BigEndian, nameHasher.Sum64())
+	for k, _ := range b.services {
+		innerHash := fnv.New64()
+		innerHash.Write([]byte(k))
+		binary.Write(hasher, binary.BigEndian, innerHash.Sum64())
+	}
+	var buf bytes.Buffer
+	binary.Write(&buf, binary.BigEndian, hasher.Sum64())
+	adv := &gatt.AdvPacket{}
+	adv.AppendManufacturerData(manufacturerId, buf.Bytes())
+	adv.AppendName(b.name)
+	return adv
+}
diff --git a/go/src/v.io/x/ref/services/discovery/ble/service.go b/go/src/v.io/x/ref/services/discovery/ble/service.go
new file mode 100644
index 0000000..bf0a91a
--- /dev/null
+++ b/go/src/v.io/x/ref/services/discovery/ble/service.go
@@ -0,0 +1,145 @@
+package main
+
+import (
+	"encoding/hex"
+	"log"
+	"sync"
+
+	"mojo/public/go/application"
+	"mojo/public/go/bindings"
+	"mojo/public/go/system"
+
+	"mojom/v.io/x/ref/services/discovery/ble/ble"
+)
+
+//#include "mojo/public/c/system/types.h"
+import "C"
+
+type bleImpl struct {
+	n *bleNeighborHood
+	d *delegate
+}
+
+func (b *bleImpl) Advertise(adv ble.Advertisement) (ble.PluginStopper_Pointer, error) {
+	uuid := hex.EncodeToString(adv.ServiceId)
+	b.n.addService(uuid, adv.Service)
+	return b.createHandleFor(&stopAdvertingImpl{uuid: uuid, n: b.n}), nil
+}
+
+func (b *bleImpl) Scan(uuid *[]uint8, attr map[string]string, handler ble.PluginScanHandler_Pointer) (ble.PluginStopper_Pointer, error) {
+	ch := make(chan *update, 10)
+	proxy := ble.NewPluginScanHandlerProxy(handler, bindings.GetAsyncWaiter())
+	go func() {
+		for v := range ch {
+			if v.found {
+				proxy.Found(v.adv)
+			} else {
+				proxy.Lost(v.adv)
+			}
+		}
+	}()
+	id := b.n.addScanner(uuid, attr, ch)
+	return b.createHandleFor(&stopScanImpl{id: id, n: b.n}), nil
+}
+
+func (b *bleImpl) createHandleFor(h ble.PluginStopper) ble.PluginStopper_Pointer {
+	req, ptr := ble.CreateMessagePipeForPluginStopper()
+	stub := ble.NewPluginStopperStub(req, h, bindings.GetAsyncWaiter())
+	b.d.addStub(stub)
+	go func() {
+		for {
+			if err := stub.ServeRequest(); err != nil {
+				connErr, ok := err.(*bindings.ConnectionError)
+				if !ok || !connErr.Closed() {
+					log.Println(err)
+				}
+				break
+			}
+		}
+	}()
+
+	return ptr
+}
+
+type stopAdvertingImpl struct {
+	uuid string
+	n    *bleNeighborHood
+}
+
+func (s *stopAdvertingImpl) Stop() error {
+	s.n.removeService(s.uuid)
+	return nil
+}
+
+type stopScanImpl struct {
+	id int64
+	n  *bleNeighborHood
+}
+
+func (s *stopScanImpl) Stop() error {
+	s.n.removeScanner(s.id)
+	return nil
+}
+
+type delegate struct {
+	mu    sync.Mutex
+	n     *bleNeighborHood
+	stubs []*bindings.Stub
+}
+
+func (d *delegate) Initialize(ctx application.Context) {
+	args := ctx.Args()
+	if len(args) < 2 {
+		log.Println("Device name needs to be passed in")
+		ctx.Close()
+	}
+	name := ctx.Args()[1]
+	n, err := newBleNeighborhood(name)
+	if err != nil {
+		log.Println("Failed to start neighborhood", err)
+		ctx.Close()
+	}
+	d.n = n
+}
+
+func (d *delegate) Create(req ble.V23Ble_Request) {
+	stub := ble.NewV23BleStub(req, &bleImpl{n: d.n, d: d}, bindings.GetAsyncWaiter())
+	d.addStub(stub)
+	go func() {
+		for {
+			if err := stub.ServeRequest(); err != nil {
+				connErr, ok := err.(*bindings.ConnectionError)
+				if !ok || !connErr.Closed() {
+					log.Println(err)
+				}
+				break
+			}
+		}
+	}()
+}
+
+func (d *delegate) addStub(s *bindings.Stub) {
+	d.mu.Lock()
+	d.stubs = append(d.stubs, s)
+	d.mu.Unlock()
+}
+func (d *delegate) AcceptConnection(conn *application.Connection) {
+	conn.ProvideServices(&ble.V23Ble_ServiceFactory{d})
+}
+
+func (d *delegate) Quit() {
+	for _, stub := range d.stubs {
+		stub.Close()
+	}
+	if d.n != nil {
+		d.n.Stop()
+	}
+}
+
+//export MojoMain
+func MojoMain(handle C.MojoHandle) C.MojoResult {
+	application.Run(&delegate{}, system.MojoHandle(handle))
+	return C.MOJO_RESULT_OK
+}
+
+func main() {}
diff --git a/go/src/v.io/x/ref/services/discovery/driver/driver.go b/go/src/v.io/x/ref/services/discovery/driver/driver.go
new file mode 100644
index 0000000..038345b
--- /dev/null
+++ b/go/src/v.io/x/ref/services/discovery/driver/driver.go
@@ -0,0 +1,60 @@
+package main
+
+import (
+	"crypto/sha256"
+	"encoding/hex"
+	"log"
+	"mojo/public/go/application"
+	"mojo/public/go/bindings"
+	"mojo/public/go/system"
+	"mojom/v.io/x/ref/services/discovery/ble/ble"
+)
+
+//#include "mojo/public/c/system/types.h"
+import "C"
+
+type discoveryDelegate struct {
+	bleHandlerProxy *ble.PluginStopper_Proxy
+}
+
+func (d *discoveryDelegate) Initialize(ctx application.Context) {
+	hash := sha256.Sum256([]byte("foobar"))
+	uuid := hash[:16]
+	hash = sha256.Sum256([]byte("key1"))
+	key1 := hex.EncodeToString(hash[:16])
+	bleRequest, blePointer := ble.CreateMessagePipeForV23Ble()
+	ctx.ConnectToApplication("https://mojo.v.io/ble.mojo").ConnectToService(&bleRequest)
+	bleProxy := ble.NewV23BleProxy(blePointer, bindings.GetAsyncWaiter())
+	adv := ble.Advertisement{
+		ServiceId: uuid,
+		Service: ble.Service{
+			Attributes: map[string]string{key1: "value1"},
+			InstanceId: []byte("random-uuid"),
+		},
+	}
+	handlerPtr, err := bleProxy.Advertise(adv)
+	if err != nil {
+		log.Println(err)
+		ctx.Close()
+		return
+	}
+	d.bleHandlerProxy = ble.NewPluginStopperProxy(handlerPtr, bindings.GetAsyncWaiter())
+}
+
+func (d *discoveryDelegate) AcceptConnection(conn *application.Connection) {
+	conn.Close()
+}
+
+func (d *discoveryDelegate) Quit() {
+	if d.bleHandlerProxy != nil {
+		d.bleHandlerProxy.Stop()
+	}
+}
+
+//export MojoMain
+func MojoMain(handle C.MojoHandle) C.MojoResult {
+	application.Run(&discoveryDelegate{}, system.MojoHandle(handle))
+	return C.MOJO_RESULT_OK
+}
+
+func main() {}
diff --git a/go/src/v.io/x/ref/services/discovery/scanner/scanner.go b/go/src/v.io/x/ref/services/discovery/scanner/scanner.go
new file mode 100644
index 0000000..65745d7
--- /dev/null
+++ b/go/src/v.io/x/ref/services/discovery/scanner/scanner.go
@@ -0,0 +1,84 @@
+package main
+
+import (
+	"crypto/sha256"
+	"log"
+	"mojo/public/go/application"
+	"mojo/public/go/bindings"
+	"mojo/public/go/system"
+	"mojom/v.io/x/ref/services/discovery/ble/ble"
+)
+
+//#include "mojo/public/c/system/types.h"
+import "C"
+
+type responseHandler struct{}
+
+func (r *responseHandler) Found(a ble.Advertisement) error {
+	log.Println("Found:", a)
+	return nil
+}
+
+func (r *responseHandler) Lost(a ble.Advertisement) error {
+	log.Println("Removed:", a)
+	return nil
+}
+
+type scannerDelegate struct {
+	bleHandlerProxy *ble.PluginStopper_Proxy
+	stubs           []*bindings.Stub
+}
+
+func (s *scannerDelegate) Initialize(ctx application.Context) {
+	hash := sha256.Sum256([]byte("foobar"))
+	uuid := hash[:16]
+	hash = sha256.Sum256([]byte("key1"))
+	// key1 := hex.EncodeToString(hash[:16])
+	bleRequest, blePointer := ble.CreateMessagePipeForV23Ble()
+	ctx.ConnectToApplication("https://mojo.v.io/ble.mojo").ConnectToService(&bleRequest)
+	bleProxy := ble.NewV23BleProxy(blePointer, bindings.GetAsyncWaiter())
+	cbRequest, cbPointer := ble.CreateMessagePipeForPluginScanHandler()
+	stub := ble.NewPluginScanHandlerStub(cbRequest, &responseHandler{}, bindings.GetAsyncWaiter())
+	s.stubs = append(s.stubs, stub)
+	go func() {
+		for {
+			if err := stub.ServeRequest(); err != nil {
+				connErr, ok := err.(*bindings.ConnectionError)
+				if !ok || !connErr.Closed() {
+					log.Println(err)
+				}
+				break
+			}
+		}
+	}()
+	log.Println("Calling scanner")
+	handlerPtr, err := bleProxy.Scan(&uuid, map[string]string{}, cbPointer)
+	if err != nil {
+		log.Println(err)
+		ctx.Close()
+		return
+	}
+	s.bleHandlerProxy = ble.NewPluginStopperProxy(handlerPtr, bindings.GetAsyncWaiter())
+}
+
+func (*scannerDelegate) AcceptConnection(conn *application.Connection) {
+	conn.Close()
+}
+
+func (s *scannerDelegate) Quit() {
+	if s.bleHandlerProxy != nil {
+		s.bleHandlerProxy.Stop()
+	}
+
+	for _, stub := range s.stubs {
+		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/mojoconfig b/mojoconfig
new file mode 100644
index 0000000..47f802a
--- /dev/null
+++ b/mojoconfig
@@ -0,0 +1,15 @@
+# Derived from $MOJO_DIR/mojoconfig.
+
+{
+  'dev_servers': [
+    {
+      'host': 'https://mojo.v.io/',
+      'mappings': [
+        ('', [
+          # For ble.mojo.
+          '@{DISCOVERY_BUILD_DIR}',
+        ]),
+      ],
+    }
+  ],
+}
diff --git a/mojom/v.io/x/ref/services/discovery/ble/ble.mojom b/mojom/v.io/x/ref/services/discovery/ble/ble.mojom
new file mode 100644
index 0000000..62985f7
--- /dev/null
+++ b/mojom/v.io/x/ref/services/discovery/ble/ble.mojom
@@ -0,0 +1,37 @@
+module ble;
+
+interface V23BLE {
+    // Exports the given service id with the attributes specified. The
+    // keys should be string forms of 128-bit uuids.  The values can be anything.
+    // Returns a handle to the service that can be used to stop the Advertisement.
+    Advertise(Advertisement adv) => (PluginStopper Handler);
+
+    // Scans for all services which match the given attributes.  The key in
+    // the attribute map should be 128-bit uuids in human readable format.
+    // All services that have an exact match for the given attributes are
+    // returned.  Attributes not specified in attributes will not be used
+    // in the match.  Calls handler with each new service found.  Returns
+    // a handle to the Scan operation so it can be canceled when no longer
+    // relevant
+    Scan(array<uint8>? id, map<string, string> attributes, PluginScanHandler handler) => (PluginStopper Handler);
+};
+
+struct Advertisement {
+    array<uint8> ServiceId;
+    Service Service;
+};
+
+struct Service {
+  array<uint8> InstanceId;
+  map<string, string> Attributes;
+};
+
+interface PluginScanHandler {
+    Found(Advertisement s);
+
+    Lost(Advertisement s);
+};
+
+interface PluginStopper {
+    Stop();
+};
diff --git a/mojom/v.io/x/ref/services/discovery/discovery.mojom b/mojom/v.io/x/ref/services/discovery/discovery.mojom
new file mode 100644
index 0000000..17b5146
--- /dev/null
+++ b/mojom/v.io/x/ref/services/discovery/discovery.mojom
@@ -0,0 +1,29 @@
+module discovery;
+
+interface Discovery {
+	// TODO(bjornick): Figure out how to do security in mojo
+	Advertise(Service service) => (DiscoveryStopper Handle);
+
+	Scan(string query, DiscoveryHandler handler) => (DiscoveryStopper Handle);
+};
+
+interface DiscoveryStopper {
+	// Stops the Advertisement/Scanning that is associated with this service
+	Stop();
+};
+
+interface DiscoveryHandler {
+	Found(Service s);
+
+	Lost(array<uint8> id);
+};
+
+struct Service {
+	// The interface name this service implements.
+	// E.g. 'v.io/v23/Display.T
+	string InterfaceNames;
+
+	map<string, string> Attrs;
+
+	array<string> Addrs;
+};
