diff --git a/incubator/net/src/test/java/org/onosproject/incubator/net/neighbour/impl/DefaultNeighbourMessageActionsTest.java b/incubator/net/src/test/java/org/onosproject/incubator/net/neighbour/impl/DefaultNeighbourMessageActionsTest.java
new file mode 100644
index 0000000..a0dc4c1
--- /dev/null
+++ b/incubator/net/src/test/java/org/onosproject/incubator/net/neighbour/impl/DefaultNeighbourMessageActionsTest.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.incubator.net.neighbour.impl;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Sets;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.ARP;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.edge.EdgePortServiceAdapter;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.packet.DefaultOutboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketService;
+
+import java.nio.ByteBuffer;
+import java.util.Collections;
+import java.util.List;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.onosproject.incubator.net.neighbour.impl.DefaultNeighbourMessageContext.createContext;
+import static org.onosproject.incubator.net.neighbour.impl.NeighbourTestUtils.createArpRequest;
+import static org.onosproject.incubator.net.neighbour.impl.NeighbourTestUtils.intf;
+
+/**
+ * Unit tests for DefaultNeighbourMessageActions.
+ */
+public class DefaultNeighbourMessageActionsTest {
+
+    private static final ConnectPoint CP1 = ConnectPoint.deviceConnectPoint("of:0000000000000001/1");
+    private static final ConnectPoint CP2 = ConnectPoint.deviceConnectPoint("of:0000000000000001/2");
+    private static final ConnectPoint CP3 = ConnectPoint.deviceConnectPoint("of:0000000000000002/1");
+
+    private static final List<ConnectPoint> EDGE_PORTS =
+            ImmutableList.<ConnectPoint>builder()
+                    .add(CP1)
+                    .add(CP2)
+                    .add(CP3)
+                    .build();
+
+    private static final MacAddress MAC1 = MacAddress.valueOf(1);
+    private static final MacAddress MAC2 = MacAddress.valueOf(2);
+    private static final IpAddress IP1 = IpAddress.valueOf(1);
+    private static final IpAddress IP2 = IpAddress.valueOf(2);
+
+    private static final VlanId VLAN1 = VlanId.vlanId((short) 1);
+
+    private static final Interface INTF1 = intf(CP1, IP1, MAC1, VLAN1);
+    private static final Interface INTF2 = intf(CP2, IP2, MAC2, VLAN1);
+
+    private DefaultNeighbourMessageActions actions;
+    private PacketService packetService;
+
+    @Before
+    public void setUp() throws Exception {
+        packetService = createMock(PacketService.class);
+        actions = new DefaultNeighbourMessageActions(packetService, new TestEdgeService());
+    }
+
+    @Test
+    public void reply() throws Exception {
+        Ethernet request = createArpRequest(IP1);
+
+        Ip4Address ip4Address = INTF1.ipAddressesList().get(0).ipAddress().getIp4Address();
+        Ethernet response = ARP.buildArpReply(ip4Address, MAC2, request);
+
+        packetService.emit(outbound(response, CP1));
+        expectLastCall().once();
+        replay(packetService);
+
+        actions.reply(createContext(request, CP1, null), MAC2);
+
+        verify(packetService);
+    }
+
+    @Test
+    public void forwardToConnectPoint() {
+        Ethernet request = createArpRequest(IP1);
+
+        packetService.emit(outbound(request, CP2));
+        expectLastCall().once();
+        replay(packetService);
+
+        actions.forward(createContext(request, CP1, null), CP2);
+
+        verify(packetService);
+    }
+
+    @Test
+    public void forwardToInterface() {
+        Ethernet request = createArpRequest(IP1);
+
+        Ethernet forwardedRequest = (Ethernet) request.clone();
+        forwardedRequest.setSourceMACAddress(INTF2.mac());
+        forwardedRequest.setVlanID(INTF2.vlan().toShort());
+
+        packetService.emit(outbound(forwardedRequest, CP2));
+        expectLastCall().once();
+        replay(packetService);
+
+        actions.forward(createContext(request, CP1, null), INTF2);
+
+        verify(packetService);
+    }
+
+    @Test
+    public void flood() {
+        Ethernet request = createArpRequest(IP1);
+
+        // Expect the packet to be emitted out all ports apart from the in port
+        Sets.difference(Sets.newLinkedHashSet(EDGE_PORTS), Collections.singleton(CP1))
+                .forEach(cp -> {
+                    packetService.emit(outbound(request, cp));
+                    expectLastCall().once();
+                });
+        replay(packetService);
+
+        actions.flood(createContext(request, CP1, null));
+
+        verify(packetService);
+    }
+
+    private static OutboundPacket outbound(Ethernet packet, ConnectPoint outPort) {
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder().setOutput(outPort.port()).build();
+        return new DefaultOutboundPacket(outPort.deviceId(),
+                treatment, ByteBuffer.wrap(packet.serialize()));
+    }
+
+    private class TestEdgeService extends EdgePortServiceAdapter {
+
+        @Override
+        public boolean isEdgePoint(ConnectPoint point) {
+            return true;
+        }
+
+        @Override
+        public Iterable<ConnectPoint> getEdgePoints() {
+            return EDGE_PORTS;
+        }
+
+    }
+
+}
diff --git a/incubator/net/src/test/java/org/onosproject/incubator/net/neighbour/impl/NeighbourResolutionManagerTest.java b/incubator/net/src/test/java/org/onosproject/incubator/net/neighbour/impl/NeighbourResolutionManagerTest.java
new file mode 100644
index 0000000..6cdc88c
--- /dev/null
+++ b/incubator/net/src/test/java/org/onosproject/incubator/net/neighbour/impl/NeighbourResolutionManagerTest.java
@@ -0,0 +1,321 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.incubator.net.neighbour.impl;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.osgi.ComponentContextAdapter;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.TestApplicationId;
+import org.onosproject.cfg.ComponentConfigAdapter;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.incubator.net.neighbour.NeighbourHandlerRegistration;
+import org.onosproject.incubator.net.neighbour.NeighbourMessageContext;
+import org.onosproject.incubator.net.neighbour.NeighbourMessageHandler;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.packet.DefaultInboundPacket;
+import org.onosproject.net.packet.DefaultOutboundPacket;
+import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.net.packet.PacketContextAdapter;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketPriority;
+import org.onosproject.net.packet.PacketProcessor;
+import org.onosproject.net.packet.PacketService;
+import org.onosproject.net.packet.PacketServiceAdapter;
+
+import java.util.Collection;
+
+import static org.easymock.EasyMock.anyInt;
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.reset;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.onosproject.incubator.net.neighbour.impl.DefaultNeighbourMessageContext.createContext;
+import static org.onosproject.incubator.net.neighbour.impl.NeighbourTestUtils.createArpRequest;
+import static org.onosproject.incubator.net.neighbour.impl.NeighbourTestUtils.intf;
+
+/**
+ * Unit tests for the NeighbourResolutionManager.
+ */
+public class NeighbourResolutionManagerTest {
+
+    private NeighbourResolutionManager neighbourManager;
+
+    private PacketService packetService;
+    private PacketProcessor packetProcessor;
+
+    private static final NeighbourMessageHandler HANDLER = new TestNeighbourHandler();
+
+    private static final ConnectPoint CP1 = ConnectPoint.deviceConnectPoint("of:0000000000000001/1");
+    private static final ConnectPoint CP2 = ConnectPoint.deviceConnectPoint("of:0000000000000001/2");
+
+    private static final MacAddress MAC1 = MacAddress.valueOf(1);
+    private static final IpAddress IP1 = IpAddress.valueOf(1);
+    private static final IpAddress IP2 = IpAddress.valueOf(2);
+
+    private static final Interface INTF1 = intf(CP1, IP1, MAC1, VlanId.NONE);
+
+    private static final ApplicationId APP_ID = TestApplicationId.create("app");
+
+    @Before
+    public void setUp() throws Exception {
+        neighbourManager = new NeighbourResolutionManager();
+
+        packetService = createMock(PacketService.class);
+        packetService.requestPackets(anyObject(TrafficSelector.class),
+                anyObject(PacketPriority.class), anyObject(ApplicationId.class));
+        expectLastCall().anyTimes();
+        packetService.addProcessor(anyObject(PacketProcessor.class), anyInt());
+        expectLastCall().andDelegateTo(new TestPacketService()).once();
+        packetService.cancelPackets(anyObject(TrafficSelector.class),
+                anyObject(PacketPriority.class), anyObject(ApplicationId.class));
+        expectLastCall().anyTimes();
+        replay(packetService);
+
+        neighbourManager.packetService = packetService;
+
+        CoreService coreService = createNiceMock(CoreService.class);
+        replay(coreService);
+        neighbourManager.coreService = coreService;
+
+        neighbourManager.componentConfigService = new ComponentConfigAdapter();
+
+        neighbourManager.activate(new ComponentContextAdapter());
+    }
+
+    @Test
+    public void testRegistration() throws Exception {
+        neighbourManager.registerNeighbourHandler(CP1, HANDLER, APP_ID);
+
+        assertTrue(verifyRegistration(CP1, HANDLER, APP_ID));
+    }
+
+    @Test
+    public void testUnregister() {
+        // Register a handler and verify the registration is there
+        neighbourManager.registerNeighbourHandler(CP1, HANDLER, APP_ID);
+        assertTrue(verifyRegistration(CP1, HANDLER, APP_ID));
+
+        // Unregister the handler but supply a different connect point
+        neighbourManager.unregisterNeighbourHandler(CP2, HANDLER, APP_ID);
+
+        // Verify the original registration is still there on the original
+        // connect point
+        assertTrue(verifyRegistration(CP1, HANDLER, APP_ID));
+
+        assertTrue(verifyNoRegistration(CP2));
+
+        // Unregister the handler from the original connect point
+        neighbourManager.unregisterNeighbourHandler(CP1, HANDLER, APP_ID);
+
+        // Verify that it is gone
+        assertTrue(verifyNoRegistration(CP1));
+    }
+
+    @Test
+    public void testRegisterInterface() {
+        neighbourManager.registerNeighbourHandler(INTF1, HANDLER, APP_ID);
+
+        assertTrue(verifyRegistration(INTF1, HANDLER, APP_ID));
+    }
+
+    @Test
+    public void testUnregisterInterface() {
+        // Register a handler for an interface and verify it is there
+        neighbourManager.registerNeighbourHandler(INTF1, HANDLER, APP_ID);
+        assertTrue(verifyRegistration(INTF1, HANDLER, APP_ID));
+
+        // Unregister the handler but use the connect point rather than the interface
+        neighbourManager.unregisterNeighbourHandler(CP1, HANDLER, APP_ID);
+
+        // Verify the interface registration is still there
+        assertTrue(verifyRegistration(INTF1, HANDLER, APP_ID));
+
+        // Unregister the handler from the interface
+        neighbourManager.unregisterNeighbourHandler(INTF1, HANDLER, APP_ID);
+
+        // Verify the registration is gone
+        assertTrue(verifyNoRegistration(INTF1));
+    }
+
+    @Test
+    public void testUnregisterByAppId() {
+        // Register some handlers and verify they are there
+        neighbourManager.registerNeighbourHandler(CP1, HANDLER, APP_ID);
+        neighbourManager.registerNeighbourHandler(CP2, HANDLER, APP_ID);
+
+        assertEquals(2, neighbourManager.getHandlerRegistrations().size());
+
+        // Unregister all handlers for the given app ID
+        neighbourManager.unregisterNeighbourHandlers(APP_ID);
+
+        // Verify the handlers are gone
+        assertEquals(0, neighbourManager.getHandlerRegistrations().size());
+    }
+
+    @Test
+    public void testPacketDistribution() {
+        Ethernet arpRequest = createArpRequest(IP1);
+
+        NeighbourMessageHandler handler = createMock(NeighbourMessageHandler.class);
+        handler.handleMessage(eq(createContext(arpRequest, CP1, null)), anyObject(HostService.class));
+        expectLastCall().once();
+        replay(handler);
+        neighbourManager.registerNeighbourHandler(CP1, handler, APP_ID);
+
+        // Incoming packet on the connect point where the handler is registered
+        packetProcessor.process(context(arpRequest, CP1));
+
+        // Send a packet from a different connect point that should not be
+        // delivered to the handler
+        packetProcessor.process(context(arpRequest, CP2));
+
+        verify(handler);
+    }
+
+    @Test
+    public void testPacketDistributionToInterface() {
+        Ethernet arpRequest = createArpRequest(IP1);
+
+        NeighbourMessageHandler handler = createMock(NeighbourMessageHandler.class);
+        handler.handleMessage(eq(createContext(arpRequest, CP1, null)), anyObject(HostService.class));
+        expectLastCall().once();
+        replay(handler);
+        neighbourManager.registerNeighbourHandler(INTF1, handler, APP_ID);
+
+        // Incoming packet matching the interface where the handler is registered
+        packetProcessor.process(context(arpRequest, CP1));
+
+        verify(handler);
+
+        reset(handler);
+        replay(handler);
+
+        // Incoming packet on same connect point but not matching the interface
+        packetProcessor.process(context(createArpRequest(IP2), CP1));
+
+        verify(handler);
+    }
+
+    /**
+     * Verifies that there is one registration for the given connect point and
+     * that the registration matches the given handler and appId.
+     *
+     * @param cp connect point to verify registration for
+     * @param handler neighbour message handler
+     * @param appId application ID
+     * @return true if the registration is the only registration present for
+     * this connect point, otherwise false
+     */
+    private boolean verifyRegistration(ConnectPoint cp, NeighbourMessageHandler handler, ApplicationId appId) {
+        Collection<NeighbourHandlerRegistration> registrations =
+                neighbourManager.getHandlerRegistrations().get(cp);
+
+        if (registrations == null) {
+            return false;
+        }
+
+        if (registrations.size() != 1) {
+            return false;
+        }
+
+        NeighbourHandlerRegistration reg = registrations.stream().findFirst().get();
+
+        return reg.appId().equals(appId) &&
+                reg.handler().equals(handler);
+    }
+
+    /**
+     * Verifies that there is one registration for the given interface and
+     * that the registration matches the given handler and appId.
+     *
+     * @param intf interface to verify registration for
+     * @param handler neighbour message handler
+     * @param appId application ID
+     * @return true if the registration is the only registration present for
+     * this interface, otherwise false
+     */
+    private boolean verifyRegistration(Interface intf, NeighbourMessageHandler handler, ApplicationId appId) {
+        return verifyRegistration(intf.connectPoint(), handler, appId);
+    }
+
+    /**
+     * Verifies that there are no registrations for the given connect point.
+     *
+     * @param cp connect point
+     * @return true if there are no registrations for this connect point,
+     * otherwise false
+     */
+    private boolean verifyNoRegistration(ConnectPoint cp) {
+        return neighbourManager.getHandlerRegistrations().get(cp) == null;
+    }
+
+    /**
+     * Verifies that there are no registrations for the given interface.
+     *
+     * @param intf interface
+     * @return true if there are no registrations for this interface,
+     * otherwise false
+     */
+    private boolean verifyNoRegistration(Interface intf) {
+        return verifyNoRegistration(intf.connectPoint());
+    }
+
+    /**
+     * Creates a packet context for the given packet coming in the given port.
+     *
+     * @param packet packet to wrap in a packet context
+     * @param inPort input port of the packet
+     * @return packet context
+     */
+    private static PacketContext context(Ethernet packet, ConnectPoint inPort) {
+        InboundPacket inboundPacket = new DefaultInboundPacket(inPort, packet, null);
+        OutboundPacket outboundPacket = new DefaultOutboundPacket(null, null, null);
+        return new PacketContextAdapter(0, inboundPacket, outboundPacket, false);
+    }
+
+    private class TestPacketService extends PacketServiceAdapter {
+
+        @Override
+        public void addProcessor(PacketProcessor processor, int priority) {
+            NeighbourResolutionManagerTest.this.packetProcessor = processor;
+        }
+    }
+
+    private static class TestNeighbourHandler implements NeighbourMessageHandler {
+
+        @Override
+        public void handleMessage(NeighbourMessageContext context, HostService hostService) {
+
+        }
+    }
+
+}
diff --git a/incubator/net/src/test/java/org/onosproject/incubator/net/neighbour/impl/NeighbourTestUtils.java b/incubator/net/src/test/java/org/onosproject/incubator/net/neighbour/impl/NeighbourTestUtils.java
new file mode 100644
index 0000000..8c7896a
--- /dev/null
+++ b/incubator/net/src/test/java/org/onosproject/incubator/net/neighbour/impl/NeighbourTestUtils.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.incubator.net.neighbour.impl;
+
+import org.onlab.packet.ARP;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.host.InterfaceIpAddress;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Test utilities.
+ */
+public final class NeighbourTestUtils {
+
+    private static final MacAddress MAC1 = MacAddress.valueOf(1);
+    private static final MacAddress MAC2 = MacAddress.valueOf(2);
+    private static final IpAddress IP2 = IpAddress.valueOf(2);
+
+    private NeighbourTestUtils() {
+
+    }
+
+    /**
+     * Creates an ARP request for the given target IP.
+     *
+     * @param targetIp IP address
+     * @return ARP request packet
+     */
+    public static Ethernet createArpRequest(IpAddress targetIp) {
+        Ethernet eth = new Ethernet();
+        eth.setDestinationMACAddress(MAC1);
+        eth.setSourceMACAddress(MAC2);
+        eth.setEtherType(Ethernet.TYPE_ARP);
+
+        ARP arp = new ARP();
+        arp.setOpCode(ARP.OP_REPLY);
+        arp.setProtocolType(ARP.PROTO_TYPE_IP);
+        arp.setHardwareType(ARP.HW_TYPE_ETHERNET);
+
+        arp.setProtocolAddressLength((byte) Ip4Address.BYTE_LENGTH);
+        arp.setHardwareAddressLength((byte) Ethernet.DATALAYER_ADDRESS_LENGTH);
+        arp.setSenderHardwareAddress(MAC2.toBytes());
+        arp.setTargetHardwareAddress(MacAddress.ZERO.toBytes());
+
+        arp.setTargetProtocolAddress(targetIp.toOctets());
+        arp.setSenderProtocolAddress(IP2.toOctets());
+
+        eth.setPayload(arp);
+        return eth;
+    }
+
+    /**
+     * Creates an interface with the given parameters. The IP prefix is assumed
+     * to be a /24.
+     *
+     * @param cp connect point
+     * @param ip IP address
+     * @param mac MAC address
+     * @param vlan VLAN ID
+     * @return interface
+     */
+    public static Interface intf(ConnectPoint cp, IpAddress ip, MacAddress mac, VlanId vlan) {
+        List<InterfaceIpAddress> ips =
+                Collections.singletonList(InterfaceIpAddress.valueOf(ip.toString() + "/24"));
+        return new Interface("foo", cp, ips, mac, vlan);
+    }
+}
