diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/VplsNeighbourHandler.java b/apps/vpls/src/main/java/org/onosproject/vpls/VplsNeighbourHandler.java
index 69b8e34..d706dca 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/VplsNeighbourHandler.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/VplsNeighbourHandler.java
@@ -16,8 +16,7 @@
 
 package org.onosproject.vpls;
 
-import com.google.common.collect.Maps;
-
+import com.google.common.collect.SetMultimap;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
@@ -33,20 +32,28 @@
 import org.onosproject.incubator.net.neighbour.NeighbourMessageHandler;
 import org.onosproject.incubator.net.neighbour.NeighbourResolutionService;
 import org.onosproject.net.Host;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigService;
 import org.onosproject.net.host.HostService;
+import org.onosproject.vpls.config.VplsConfigurationService;
 import org.slf4j.Logger;
 
-import java.util.Map;
+import java.util.Collection;
+import java.util.Set;
 
 import static org.slf4j.LoggerFactory.getLogger;
 
 /**
  * Handles neighbour messages for VPLS use case.
- * Handlers will be changed automatically by interface or network configuration
- * events.
+ * Handlers will be changed automatically by interface or network configuration events.
  */
 @Component(immediate = true)
 public class VplsNeighbourHandler {
+    private static final String UNKNOWN_CONTEXT = "Unknown context type: {}";
+
+    private static final String CAN_NOT_FIND_NETWORK =
+            "Cannot find VPLS for port {} with VLAN Id {}.";
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected CoreService coreService;
@@ -57,16 +64,22 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected NeighbourResolutionService neighbourService;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected VplsConfigurationService vplsConfigService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigService configService;
+
     private VplsInterfaceListener interfaceListener
             = new VplsInterfaceListener();
 
-    private VplsNeighbourMessageHandler neighbourHandler =
+    protected VplsNeighbourMessageHandler neighbourHandler =
             new VplsNeighbourMessageHandler();
 
-    private final Logger log = getLogger(getClass());
+    protected VplsConfigListener configListener =
+            new VplsConfigListener();
 
-    private Map<Interface, NeighbourMessageHandler> neighbourHandlers =
-            Maps.newHashMap();
+    private final Logger log = getLogger(getClass());
 
     private ApplicationId appId;
 
@@ -75,42 +88,29 @@
     protected void activate() {
         appId = coreService.registerApplication(Vpls.VPLS_APP);
         interfaceService.addListener(interfaceListener);
-
-        interfaceService.getInterfaces().forEach(intf -> {
-            neighbourHandlers.put(intf, neighbourHandler);
-
-            neighbourService.registerNeighbourHandler(intf, neighbourHandler, appId);
-        });
-
-        log.debug("Activated");
+        configService.addListener(configListener);
+        configNeighbourHandler();
     }
 
     @Deactivate
     protected void deactivate() {
         interfaceService.removeListener(interfaceListener);
-        neighbourHandlers.entrySet().forEach(e -> {
-            neighbourService.unregisterNeighbourHandler(e.getKey(), e.getValue(), appId);
-        });
-        log.debug("Deactivated");
+        configService.removeListener(configListener);
+        neighbourService.unregisterNeighbourHandlers(appId);
     }
 
-    private void configNeighbourHandler(Interface intf,
-                                          NeighbourMessageHandler handler,
-                                          InterfaceEvent.Type eventType) {
-        switch (eventType) {
-            case INTERFACE_ADDED:
-                neighbourHandlers.put(intf, handler);
-                neighbourService.registerNeighbourHandler(intf, handler, appId);
-                break;
-            case INTERFACE_REMOVED:
-                neighbourHandlers.remove(intf, handler);
-                neighbourService.unregisterNeighbourHandler(intf, handler, appId);
-                break;
-            case INTERFACE_UPDATED:
-                break;
-            default:
-                break;
-        }
+    private void configNeighbourHandler() {
+        neighbourService.unregisterNeighbourHandlers(appId);
+        Set<Interface> interfaces = vplsConfigService.getAllInterfaces();
+
+        interfaceService.getInterfaces()
+                .stream()
+                .filter(interfaces::contains)
+                .forEach(intf -> {
+                    neighbourService.registerNeighbourHandler(intf,
+                                                              neighbourHandler,
+                                                              appId);
+                });
     }
 
     /**
@@ -124,34 +124,84 @@
 
             switch (context.type()) {
                 case REQUEST:
-                    interfaceService.getInterfacesByVlan(context.vlan())
-                            .stream()
-                            .filter(intf -> !context.inPort().equals(intf.connectPoint()))
-                            .forEach(context::forward);
+                    handleRequest(context);
                     break;
+
                 case REPLY:
-                    hostService.getHostsByMac(context.dstMac())
-                            .stream()
-                            .filter(host -> host.vlan().equals(context.vlan()))
-                            .map(Host::location)
-                            .forEach(context::forward);
+                    handleReply(context, hostService);
                     break;
 
                 default:
-                    log.warn("Unknown context type: {}", context.type());
+                    log.warn(UNKNOWN_CONTEXT, context.type());
                     break;
             }
         }
     }
 
     /**
+     * Handles request messages.
+     *
+     * @param context the message context
+     */
+    protected void handleRequest(NeighbourMessageContext context) {
+
+        SetMultimap<String, Interface> vplsNetwork =
+                vplsConfigService.getVplsNetwork(context.vlan(), context.inPort());
+
+        if (vplsNetwork != null) {
+            Collection<Interface> vplsInterfaces = vplsNetwork.values();
+            vplsInterfaces.stream()
+                    .filter(intf -> !context.inPort().equals(intf.connectPoint()))
+                    .forEach(context::forward);
+
+        } else {
+            log.debug(CAN_NOT_FIND_NETWORK, context.inPort(), context.vlan());
+        }
+    }
+
+    /**
+     * Handles reply messages between VLAN tagged interfaces.
+     *
+     * @param context the message context
+     * @param hostService the host service
+     */
+    protected void handleReply(NeighbourMessageContext context,
+                               HostService hostService) {
+
+        SetMultimap<String, Interface> vplsNetwork =
+                vplsConfigService.getVplsNetwork(context.vlan(), context.inPort());
+
+        Set<Host> hosts = hostService.getHostsByMac(context.dstMac());
+        if (vplsNetwork != null) {
+            Collection<Interface> vplsInterfaces = vplsNetwork.values();
+            hosts.forEach(host -> vplsInterfaces.stream()
+                    .filter(intf -> intf.connectPoint().equals(host.location()))
+                    .filter(intf -> intf.vlan().equals(host.vlan()))
+                    .forEach(context::forward));
+        } else {
+            log.debug(CAN_NOT_FIND_NETWORK, context.inPort(), context.vlan());
+        }
+    }
+
+    /**
      * Listener for interface configuration events.
      */
     private class VplsInterfaceListener implements InterfaceListener {
 
         @Override
         public void event(InterfaceEvent event) {
-            configNeighbourHandler(event.subject(), neighbourHandler, event.type());
+            configNeighbourHandler();
+        }
+    }
+
+    /**
+     * Listener for network configuration events.
+     */
+    private class VplsConfigListener implements NetworkConfigListener {
+
+        @Override
+        public void event(NetworkConfigEvent event) {
+            configNeighbourHandler();
         }
     }
 
diff --git a/apps/vpls/src/test/java/org/onosproject/vpls/VplsNeighbourHandlerTest.java b/apps/vpls/src/test/java/org/onosproject/vpls/VplsNeighbourHandlerTest.java
new file mode 100644
index 0000000..90e3415
--- /dev/null
+++ b/apps/vpls/src/test/java/org/onosproject/vpls/VplsNeighbourHandlerTest.java
@@ -0,0 +1,699 @@
+/*
+ * 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.vpls;
+
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSetMultimap;
+import com.google.common.collect.SetMultimap;
+import com.google.common.collect.Sets;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.incubator.net.intf.InterfaceListener;
+import org.onosproject.incubator.net.intf.InterfaceService;
+import org.onosproject.incubator.net.neighbour.NeighbourHandlerRegistration;
+import org.onosproject.incubator.net.neighbour.NeighbourMessageContext;
+import org.onosproject.incubator.net.neighbour.NeighbourMessageHandler;
+import org.onosproject.incubator.net.neighbour.NeighbourMessageType;
+import org.onosproject.incubator.net.neighbour.NeighbourProtocol;
+import org.onosproject.incubator.net.neighbour.NeighbourResolutionService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultHost;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.host.HostServiceAdapter;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.vpls.config.VplsConfigurationService;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static junit.framework.TestCase.assertEquals;
+
+/**
+ * Tests the the {@link VplsNeighbourHandler} class.
+ */
+public class VplsNeighbourHandlerTest {
+    private final ConnectPoint of1p1 =
+            new ConnectPoint(DeviceId.deviceId("of:1"),
+                             PortNumber.portNumber(1));
+    private final ConnectPoint of4p1 =
+            new ConnectPoint(DeviceId.deviceId("of:4"),
+                             PortNumber.portNumber(1));
+    private final ConnectPoint of3p1 =
+            new ConnectPoint(DeviceId.deviceId("of:3"),
+                             PortNumber.portNumber(1));
+    private final ConnectPoint of4p2 =
+            new ConnectPoint(DeviceId.deviceId("of:4"),
+                             PortNumber.portNumber(2));
+    private final ConnectPoint of2p1 =
+            new ConnectPoint(DeviceId.deviceId("of:2"),
+                             PortNumber.portNumber(1));
+
+    private final VlanId vlan100 = VlanId.vlanId("100");
+    private final VlanId vlan200 = VlanId.vlanId("200");
+    private final VlanId vlan300 = VlanId.vlanId("300");
+
+    private final Interface v100h1 =
+            new Interface("v100h1", of1p1, null, null, vlan100);
+    private final Interface v100h2 =
+            new Interface("v100h2", of4p1, null, null, vlan100);
+    private final Interface v200h1 =
+            new Interface("v200h1", of4p2, null, null, vlan200);
+    private final Interface v300h1 =
+            new Interface("v300h1", of3p1, null, null, vlan300);
+    private final Interface v200h2 =
+            new Interface("v200h2", of2p1, null, null, vlan200);
+
+    private final MacAddress mac1 = MacAddress.valueOf("00:00:00:00:00:01");
+    private final MacAddress mac2 = MacAddress.valueOf("00:00:00:00:00:02");
+    private final MacAddress mac3 = MacAddress.valueOf("00:00:00:00:00:03");
+    private final MacAddress mac4 = MacAddress.valueOf("00:00:00:00:00:04");
+    private final MacAddress mac5 = MacAddress.valueOf("00:00:00:00:00:05");
+
+    private final ProviderId pid = new ProviderId("of", "foo");
+
+    private final Host v100host1 = makeHost(mac1, vlan100, of1p1);
+    private final Host v100host2 = makeHost(mac2, vlan100, of4p1);
+    private final Host v200host1 = makeHost(mac3, vlan200, of4p2);
+    private final Host v300host1 = makeHost(mac4, vlan300, of3p1);
+    private final Host v200host2 = makeHost(mac5, vlan200, of2p1);
+
+    private final Set<Host> availableHosts = ImmutableSet.of(v100host1,
+                                                             v100host2,
+                                                             v200host1,
+                                                             v300host1,
+                                                             v200host2);
+
+    private final Set<Interface> avaliableInterfaces =
+            ImmutableSet.of(v100h1, v100h2, v200h1, v200h2, v300h1);
+
+    private VplsNeighbourHandler vplsNeighbourHandler;
+
+    private HostService hostService;
+
+    /**
+     * Sets up 2 VPLS which contain 2 networks and 5 hosts.
+     * net1 contains 3 hosts: v100h1, v200h1 and v300h1
+     * net2 contains 2 hosts: v100h2, v200h2
+     */
+    @Before
+    public void setUp() {
+        vplsNeighbourHandler = new VplsNeighbourHandler();
+        SetMultimap<String, Interface> vplsNetworks =
+                HashMultimap.create();
+        vplsNetworks.put("net1", v100h1);
+        vplsNetworks.put("net1", v200h1);
+        vplsNetworks.put("net1", v300h1);
+        vplsNetworks.put("net2", v100h2);
+        vplsNetworks.put("net2", v200h2);
+        vplsNeighbourHandler.vplsConfigService =
+                new TestVplsConfigService(vplsNetworks);
+        vplsNeighbourHandler.interfaceService =
+                new TestInterfaceService();
+        vplsNeighbourHandler.neighbourService =
+                new TestNeighbourService();
+
+        hostService = new TestHostService();
+    }
+
+    @After
+    public void tearDown() {
+
+    }
+
+    /**
+     * Sends request messages to all hosts in VPLS net1.
+     * Request messages should be received from other hosts in net1.
+     */
+    @Test
+    public void testNet1RequestMessage() {
+        // Request from v100h1 (net1)
+        // Should be received by v200h1 and v300h1
+        TestMessageContext requestMessage =
+                makeBroadcastRequestContext(v100host1);
+        Set<Interface> expectInterfaces = ImmutableSet.of(v200h1, v300h1);
+        vplsNeighbourHandler.handleRequest(requestMessage);
+        assertEquals(expectInterfaces, requestMessage.forwardResults);
+
+        // Request from v200h1 (net1)
+        // Should be received by v100h1 and v300h1
+        requestMessage = makeBroadcastRequestContext(v200host1);
+        expectInterfaces = ImmutableSet.of(v100h1, v300h1);
+        vplsNeighbourHandler.handleRequest(requestMessage);
+        assertEquals(expectInterfaces, requestMessage.forwardResults);
+
+        // Request from v300h1 (net1)
+        // Should be received by v100h1 and v200h1
+        requestMessage = makeBroadcastRequestContext(v300host1);
+        expectInterfaces = ImmutableSet.of(v100h1, v200h1);
+        vplsNeighbourHandler.handleRequest(requestMessage);
+        assertEquals(expectInterfaces, requestMessage.forwardResults);
+    }
+
+    /**
+     * Sends request messages to all hosts in VPLS net2.
+     * Request messages should be received from other hosts in net2.
+     */
+    @Test
+    public void testNet2RequestMessage() {
+        // Request from v100h2
+        // Should be received by v200h2
+        TestMessageContext requestMessage =
+                makeBroadcastRequestContext(v100host2);
+        Set<Interface> expectInterfaces = ImmutableSet.of(v200h2);
+        vplsNeighbourHandler.handleRequest(requestMessage);
+        assertEquals(expectInterfaces, requestMessage.forwardResults);
+
+        // Request from v200h2
+        // Should be received by v100h2
+        requestMessage = makeBroadcastRequestContext(v200host2);
+        expectInterfaces = ImmutableSet.of(v100h2);
+        vplsNeighbourHandler.handleRequest(requestMessage);
+        assertEquals(expectInterfaces, requestMessage.forwardResults);
+    }
+
+    /**
+     * Sends reply messages to hosts in VPLS net1.
+     * Reply messages should be received by the host with MAC address equal to
+     * the dstMac of the message context.
+     */
+    @Test
+    public void testNet1ReplyMessage() {
+        // Response from v100h1 (net1) to v200h1 (net1)
+        // Should be received by v200h1
+        TestMessageContext replyMessage =
+                makeReplyContext(v100host1, v200host1);
+        Set<Interface> expectInterfaces = ImmutableSet.of(v200h1);
+        vplsNeighbourHandler.handleReply(replyMessage, hostService);
+        assertEquals(expectInterfaces, replyMessage.forwardResults);
+
+        // Response from v200h1 (net1) to v300h1 (net1)
+        // Should be received by v300h1
+        replyMessage = makeReplyContext(v200host1, v300host1);
+        expectInterfaces = ImmutableSet.of(v300h1);
+        vplsNeighbourHandler.handleReply(replyMessage, hostService);
+        assertEquals(expectInterfaces, replyMessage.forwardResults);
+
+        // Response from v300h1 (net1) to v100h1 (net1)
+        // Should be received by v100h1
+        replyMessage = makeReplyContext(v300host1, v100host1);
+        expectInterfaces = ImmutableSet.of(v100h1);
+        vplsNeighbourHandler.handleReply(replyMessage, hostService);
+        assertEquals(expectInterfaces, replyMessage.forwardResults);
+    }
+
+    /**
+     * Sends reply messages to hosts in VPLS net2.
+     * Reply messages should be received by the host with MAC address equal to
+     * the dstMac of the message context.
+     */
+    @Test
+    public void testNet2ReplyMessage() {
+        // Response from v100h2 (net2) to v200h2 (net2)
+        // Should be received by v200h2
+        TestMessageContext replyMessage =
+                makeReplyContext(v100host2, v200host2);
+        Set<Interface> expectInterfaces = ImmutableSet.of(v200h2);
+        vplsNeighbourHandler.handleReply(replyMessage, hostService);
+        assertEquals(expectInterfaces, replyMessage.forwardResults);
+
+        // Response from v200h2 (net2) to v100h2 (net2)
+        // Should be received by v100h2
+        replyMessage = makeReplyContext(v200host2, v100host2);
+        expectInterfaces = ImmutableSet.of(v100h2);
+        vplsNeighbourHandler.handleReply(replyMessage, hostService);
+        assertEquals(expectInterfaces, replyMessage.forwardResults);
+    }
+
+    /**
+     * Sends wrong reply messages to hosts.
+     * The source and the destination MAC addresses are not set on any host of the VPLS.
+     * The reply messages won't be received by any hosts.
+     */
+    @Test
+    public void testWrongReplyMessage() {
+        // Response from v100h1 (net1) to v100h2 (net2)
+        // forward results should be empty
+        TestMessageContext replyMessage = makeReplyContext(v100host1, v100host2);
+        Set<Interface> expectInterfaces = ImmutableSet.of();
+        vplsNeighbourHandler.handleReply(replyMessage, hostService);
+        assertEquals(expectInterfaces, replyMessage.forwardResults);
+
+        // Response from v200h2 (net2) to v300h1 (net1)
+        // forward results should be empty
+        replyMessage = makeReplyContext(v200host2, v300host1);
+        expectInterfaces = ImmutableSet.of();
+        vplsNeighbourHandler.handleReply(replyMessage, hostService);
+        assertEquals(expectInterfaces, replyMessage.forwardResults);
+    }
+
+    private Host makeHost(MacAddress mac, VlanId vlan, ConnectPoint cp) {
+        return new DefaultHost(pid,
+                               HostId.hostId(mac, vlan),
+                               mac,
+                               vlan,
+                               new HostLocation(cp, 0),
+                               Sets.newHashSet());
+    }
+
+    private TestMessageContext makeBroadcastRequestContext(Host host) {
+        return new TestMessageContext(host.location(),
+                                      host.mac(),
+                                      MacAddress.BROADCAST,
+                                      host.vlan(),
+                                      NeighbourMessageType.REQUEST);
+    }
+
+    private TestMessageContext makeReplyContext(Host src, Host dst) {
+        return new TestMessageContext(src.location(),
+                                      src.mac(),
+                                      dst.mac(),
+                                      src.vlan(),
+                                      NeighbourMessageType.REPLY);
+    }
+
+    private class TestMessageContext implements NeighbourMessageContext {
+
+
+        private final NeighbourMessageType type;
+        private final MacAddress srcMac;
+        private final MacAddress dstMac;
+        private final ConnectPoint inPort;
+        private final VlanId vlanId;
+
+        public Set<Interface> forwardResults;
+
+        /**
+         * Creates new neighbour message context for test.
+         *
+         * @param inPort the input port
+         * @param srcMac the source Mac
+         * @param dstMac the destination Mac
+         * @param vlanId the VLAN Id
+         * @param type the message context type
+         */
+        public TestMessageContext(
+                ConnectPoint inPort,
+                MacAddress srcMac,
+                MacAddress dstMac,
+                VlanId vlanId,
+                NeighbourMessageType type) {
+
+            this.inPort = inPort;
+            this.srcMac = srcMac;
+            this.dstMac = dstMac;
+            this.vlanId = vlanId;
+            this.type = type;
+
+            this.forwardResults = Sets.newHashSet();
+
+        }
+        @Override
+        public ConnectPoint inPort() {
+            return inPort;
+        }
+
+        @Override
+        public NeighbourMessageType type() {
+            return type;
+        }
+
+        @Override
+        public VlanId vlan() {
+            return vlanId;
+        }
+
+        @Override
+        public MacAddress srcMac() {
+            return srcMac;
+        }
+
+        @Override
+        public MacAddress dstMac() {
+            return dstMac;
+        }
+
+        @Override
+        public IpAddress target() {
+            return null;
+        }
+
+        @Override
+        public IpAddress sender() {
+            return null;
+        }
+
+        @Override
+        public void forward(ConnectPoint outPort) {
+
+        }
+
+        @Override
+        public void forward(Interface outIntf) {
+            forwardResults.add(outIntf);
+        }
+
+        @Override
+        public void reply(MacAddress targetMac) {
+
+        }
+
+        @Override
+        public void flood() {
+
+        }
+
+        @Override
+        public void drop() {
+
+        }
+
+        @Override
+        public Ethernet packet() {
+            return null;
+        }
+
+        @Override
+        public NeighbourProtocol protocol() {
+            return null;
+        }
+    }
+
+    private class TestVplsConfigService implements VplsConfigurationService {
+
+        private final SetMultimap<String, Interface> vplsNetworks;
+
+        public TestVplsConfigService(SetMultimap<String, Interface> networks) {
+            this.vplsNetworks = networks;
+        }
+
+        @Override
+        public void addVpls(String name, Set<String> ifaceNames) {
+            if (!vplsNetworks.containsKey(name)) {
+                ifaceNames.forEach(ifaceName -> {
+                    avaliableInterfaces.forEach(intf -> {
+                        if (intf.name().equals(ifaceName)) {
+                            vplsNetworks.put(name, intf);
+                        }
+                    });
+                });
+            }
+        }
+
+        @Override
+        public void removeVpls(String name) {
+            if (vplsNetworks.containsKey(name)) {
+                vplsNetworks.removeAll(name);
+            }
+        }
+
+        @Override
+        public void addInterfaceToVpls(String name, String ifaceName) {
+            avaliableInterfaces.forEach(intf -> {
+                if (intf.name().equals(ifaceName)) {
+                    vplsNetworks.put(name, intf);
+                }
+            });
+        }
+
+        @Override
+        public void removeInterfaceFromVpls(String ifaceName) {
+            SetMultimap<String, Interface> toBeRemoved = HashMultimap.create();
+            vplsNetworks.entries().forEach(e -> {
+                if (e.getValue().name().equals(ifaceName)) {
+                    toBeRemoved.put(e.getKey(), e.getValue());
+                }
+            });
+
+            toBeRemoved.entries()
+                    .forEach(e -> vplsNetworks.remove(e.getKey(),
+                                                      e.getValue()));
+        }
+
+        @Override
+        public void cleanVpls() {
+            vplsNetworks.clear();
+        }
+
+        @Override
+        public Set<String> getVplsAffectedByApi() {
+            return null;
+        }
+
+        @Override
+        public Set<Interface> getAllInterfaces() {
+            return ImmutableSet.copyOf(vplsNetworks.values());
+        }
+
+        @Override
+        public Set<Interface> getVplsInterfaces(String name) {
+            return vplsNetworks.get(name)
+                    .stream()
+                    .collect(Collectors.toSet());
+        }
+
+        @Override
+        public Set<String> getAllVpls() {
+            return vplsNetworks.keySet();
+        }
+
+        @Override
+        public Set<String> getOldVpls() {
+            return null;
+        }
+
+        @Override
+        public SetMultimap<String, Interface> getVplsNetworks() {
+            return ImmutableSetMultimap.copyOf(vplsNetworks);
+        }
+
+        @Override
+        public SetMultimap<String, Interface> getVplsNetwork(VlanId vlan,
+                                                             ConnectPoint connectPoint) {
+            String vplsNetworkName =
+                    vplsNetworks.entries().stream()
+                            .filter(e -> e.getValue().connectPoint().equals(connectPoint))
+                            .filter(e -> e.getValue().vlan().equals(vlan))
+                            .map(e -> e.getKey())
+                            .findFirst()
+                            .orElse(null);
+            SetMultimap<String, Interface> result = HashMultimap.create();
+            if (vplsNetworkName != null &&
+                    vplsNetworks.containsKey(vplsNetworkName)) {
+                vplsNetworks.get(vplsNetworkName)
+                        .forEach(intf -> result.put(vplsNetworkName, intf));
+                return result;
+            }
+            return null;
+        }
+    }
+
+    class TestHostService extends HostServiceAdapter {
+        @Override
+        public Set<Host> getHostsByMac(MacAddress mac) {
+            return availableHosts.stream()
+                    .filter(host -> host.mac().equals(mac))
+                    .collect(Collectors.toSet());
+        }
+
+        @Override
+        public Iterable<Host> getHosts() {
+            return availableHosts;
+        }
+
+        @Override
+        public Set<Host> getHostsByVlan(VlanId vlanId) {
+            return availableHosts.stream()
+                    .filter(host -> host.vlan().equals(vlanId))
+                    .collect(Collectors.toSet());
+        }
+
+        @Override
+        public int getHostCount() {
+            return availableHosts.size();
+        }
+
+        @Override
+        public Host getHost(HostId hostId) {
+            return availableHosts.stream()
+                    .filter(host -> host.id().equals(hostId))
+                    .findFirst()
+                    .orElse(null);
+        }
+    }
+
+    private class TestNeighbourService implements NeighbourResolutionService {
+        private SetMultimap<ConnectPoint, NeighbourHandlerRegistration> handlerRegs;
+
+        public TestNeighbourService() {
+            handlerRegs = HashMultimap.create();
+        }
+
+        @Override
+        public void registerNeighbourHandler(ConnectPoint connectPoint,
+                                             NeighbourMessageHandler handler,
+                                             ApplicationId appId) {
+            Interface intf =
+                    new Interface(null, connectPoint, null, null, null);
+
+            NeighbourHandlerRegistration reg =
+                    new HandlerRegistration(handler, intf, appId);
+
+            handlerRegs.put(connectPoint, reg);
+        }
+
+        @Override
+        public void registerNeighbourHandler(Interface intf,
+                                             NeighbourMessageHandler handler,
+                                             ApplicationId appId) {
+            NeighbourHandlerRegistration reg =
+                    new HandlerRegistration(handler, intf, appId);
+            handlerRegs.put(intf.connectPoint(), reg);
+        }
+
+        @Override
+        public void unregisterNeighbourHandler(ConnectPoint connectPoint,
+                                               NeighbourMessageHandler handler,
+                                               ApplicationId appId) {
+            handlerRegs.removeAll(connectPoint);
+        }
+
+        @Override
+        public void unregisterNeighbourHandler(Interface intf,
+                                               NeighbourMessageHandler handler,
+                                               ApplicationId appId) {
+            handlerRegs.removeAll(intf.connectPoint());
+        }
+
+        @Override
+        public void unregisterNeighbourHandlers(ApplicationId appId) {
+            handlerRegs.clear();
+        }
+
+        @Override
+        public Map<ConnectPoint, Collection<NeighbourHandlerRegistration>> getHandlerRegistrations() {
+            return handlerRegs.asMap();
+        }
+
+        private class HandlerRegistration implements NeighbourHandlerRegistration {
+            private final Interface intf;
+            private final NeighbourMessageHandler handler;
+            private final ApplicationId appId;
+
+            /**
+             * Creates a new registration handler.
+             *
+             * @param handler the neighbour message handler
+             * @param intf the interface
+             */
+            public HandlerRegistration(NeighbourMessageHandler handler,
+                                       Interface intf,
+                                       ApplicationId appId) {
+                this.intf = intf;
+                this.handler = handler;
+                this.appId = appId;
+            }
+
+            @Override
+            public Interface intf() {
+                return intf;
+            }
+
+            @Override
+            public NeighbourMessageHandler handler() {
+                return handler;
+            }
+
+            @Override
+            public ApplicationId appId() {
+                return appId;
+            }
+
+        }
+    }
+
+    class TestInterfaceService implements InterfaceService {
+
+        @Override
+        public void addListener(InterfaceListener listener) {
+
+        }
+
+        @Override
+        public void removeListener(InterfaceListener listener) {
+
+        }
+
+        @Override
+        public Set<Interface> getInterfaces() {
+            return avaliableInterfaces;
+        }
+
+        @Override
+        public Interface getInterfaceByName(ConnectPoint connectPoint,
+                                            String name) {
+            return avaliableInterfaces.stream()
+                    .filter(intf -> intf.name().equals(name))
+                    .findFirst()
+                    .orElse(null);
+
+        }
+
+        @Override
+        public Set<Interface> getInterfacesByPort(ConnectPoint port) {
+            return avaliableInterfaces.stream()
+                    .filter(intf -> intf.connectPoint().equals(port))
+                    .collect(Collectors.toSet());
+        }
+
+        @Override
+        public Set<Interface> getInterfacesByIp(IpAddress ip) {
+            return avaliableInterfaces.stream()
+                    .filter(intf -> intf.ipAddressesList().contains(ip))
+                    .collect(Collectors.toSet());
+        }
+
+        @Override
+        public Set<Interface> getInterfacesByVlan(VlanId vlan) {
+            return avaliableInterfaces.stream()
+                    .filter(intf -> intf.vlan().equals(vlan))
+                    .collect(Collectors.toSet());
+        }
+
+        @Override
+        public Interface getMatchingInterface(IpAddress ip) {
+            return avaliableInterfaces.stream()
+                    .filter(intf -> intf.ipAddressesList().contains(ip))
+                    .findFirst()
+                    .orElse(null);
+        }
+    }
+}
