diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java
index 8a68db2..6b35a55 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java
@@ -239,16 +239,9 @@
         }
 
         // Add VLAN treatment for traffic going from BGP speaker to BGP peer
-        if (!vlanOne.equals(vlanTwo)) {
-            if (vlanTwo.equals(VlanId.NONE)) {
-                treatmentToPeer.popVlan();
-            } else {
-                treatmentToPeer.setVlanId(vlanTwo);
-            }
-        }
+        treatmentToPeer = applyVlanTreatment(vlanOne, vlanTwo, treatmentToPeer);
 
         // Path from BGP speaker to BGP peer matching destination TCP port 179
-
         selector = buildSelector(tcpProtocol,
                 vlanOne,
                 ipOne,
@@ -309,13 +302,7 @@
                             .build());
 
         // Add VLAN treatment for traffic going from BGP peer to BGP speaker
-        if (!vlanTwo.equals(vlanOne)) {
-            if (vlanOne.equals(VlanId.NONE)) {
-                treatmentToSpeaker.popVlan();
-            } else {
-                treatmentToSpeaker.setVlanId(vlanOne);
-            }
-        }
+        treatmentToSpeaker = applyVlanTreatment(vlanTwo, vlanOne, treatmentToSpeaker);
 
         // Path from BGP peer to BGP speaker matching destination TCP port 179
         selector = buildSelector(tcpProtocol,
@@ -396,9 +383,9 @@
                                           Short dstTcpPort) {
         TrafficSelector.Builder builder = DefaultTrafficSelector.builder().matchIPProtocol(ipProto);
 
-        // Match on any VLAN Id if a VLAN Id configured on the ingress interface
+        // Match on VLAN Id if a VLAN Id configured on the ingress interface
         if (!ingressVlanId.equals(VlanId.NONE)) {
-            builder.matchVlanId(VlanId.ANY);
+            builder.matchVlanId(ingressVlanId);
         }
 
         if (dstIp.isIp4()) {
@@ -422,6 +409,31 @@
         return builder.build();
     }
 
+    /*
+     * Adds the VLAN Id treatment before building the intents, depending on how
+     * the VLAN Ids of the BGP speakers and the BGP peers are configured.
+     */
+    private TrafficTreatment.Builder applyVlanTreatment(VlanId vlanOne,
+                                                        VlanId vlanTwo,
+                                                        TrafficTreatment.Builder treatment) {
+        if (!vlanOne.equals(vlanTwo)) {
+            // VLANs are different. Do some VLAN treatment
+            if (vlanTwo.equals(VlanId.NONE)) {
+                // VLAN two is none. VLAN one is set. Do a pop
+                treatment.popVlan();
+            } else {
+                // Either both VLANs are set or vlanOne is not
+                if (vlanOne.equals(VlanId.NONE)) {
+                    // VLAN one is none. VLAN two is set. Push the VLAN header
+                    treatment.pushVlan();
+                }
+                // Set the VLAN Id to the egress VLAN Id
+                treatment.setVlanId(vlanTwo);
+            }
+        }
+        return treatment;
+    }
+
     /**
      * Builds an intent Key for a point-to-point intent based off the source
      * and destination IP address, as well as a suffix String to distinguish
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpFib.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpFib.java
index 1b6c7fa..d26d9de 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpFib.java
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpFib.java
@@ -39,6 +39,7 @@
 import org.onosproject.incubator.net.routing.RouteListener;
 import org.onosproject.incubator.net.routing.RouteService;
 import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.FilteredConnectPoint;
 import org.onosproject.net.flow.DefaultTrafficSelector;
 import org.onosproject.net.flow.DefaultTrafficTreatment;
 import org.onosproject.net.flow.TrafficSelector;
@@ -51,7 +52,6 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
@@ -160,35 +160,151 @@
         }
         ConnectPoint egressPort = egressInterface.connectPoint();
 
-        Set<Interface> ingressInterfaces = new HashSet<>();
-        Set<ConnectPoint> ingressPorts = new HashSet<>();
         log.debug("Generating intent for prefix {}, next hop mac {}",
                 prefix, nextHopMacAddress);
 
-        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        Set<FilteredConnectPoint> ingressFilteredCPs = Sets.newHashSet();
 
-        // Get ingress interfaces and ports
         // TODO this should be only peering interfaces
         interfaceService.getInterfaces().stream()
-                .filter(intf -> !intf.equals(egressInterface))
-                .filter(intf -> !intf.connectPoint().equals(egressPort))
                 .forEach(intf -> {
-                    ingressInterfaces.add(intf);
-                    ConnectPoint ingressPort = intf.connectPoint();
-                    ingressPorts.add(ingressPort);
+                    // Get ony ingress interfaces with IPs configured
+                    if (validIngressIntf(intf, egressInterface)) {
+                        TrafficSelector.Builder selector =
+                                buildIngressTrafficSelector(intf, prefix);
+                        FilteredConnectPoint ingressFilteredCP =
+                                new FilteredConnectPoint(intf.connectPoint(), selector.build());
+                        ingressFilteredCPs.add(ingressFilteredCP);
+                    }
                 });
 
-        // By default the ingress traffic is not tagged
-        VlanId ingressVlanId = VlanId.NONE;
+        // Build treatment: rewrite the destination MAC address
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder()
+                .setEthDst(nextHopMacAddress);
 
-        // Match VLAN Id ANY if the source VLAN Id is not null
-        // TODO need to be able to set a different VLAN Id per ingress interface
-        for (Interface intf : ingressInterfaces) {
-            if (!intf.vlan().equals(VlanId.NONE)) {
-                selector.matchVlanId(VlanId.ANY);
-                ingressVlanId = intf.vlan();
+        // Build the egress selector for VLAN Id
+        TrafficSelector.Builder selector =
+                buildTrafficSelector(egressInterface);
+        FilteredConnectPoint egressFilteredCP =
+                new FilteredConnectPoint(egressPort, selector.build());
+
+        // Set priority
+        int priority =
+                prefix.prefixLength() * PRIORITY_MULTIPLIER + PRIORITY_OFFSET;
+
+        // Set key
+        Key key = Key.of(prefix.toString(), appId);
+
+        return MultiPointToSinglePointIntent.builder()
+                .appId(appId)
+                .key(key)
+                .filteredIngressPoints(ingressFilteredCPs)
+                .filteredEgressPoint(egressFilteredCP)
+                .treatment(treatment.build())
+                .priority(priority)
+                .constraints(CONSTRAINTS)
+                .build();
+    }
+
+    private void addInterface(Interface intf) {
+        synchronized (this) {
+            for (Map.Entry<IpPrefix, MultiPointToSinglePointIntent> entry : routeIntents.entrySet()) {
+                // Retrieve the IP prefix and affected intent
+                IpPrefix prefix = entry.getKey();
+                MultiPointToSinglePointIntent intent = entry.getValue();
+
+                // Add new ingress FilteredConnectPoint
+                Set<FilteredConnectPoint> ingressFilteredCPs =
+                        Sets.newHashSet(intent.filteredIngressPoints());
+
+                // Create the new traffic selector
+                TrafficSelector.Builder selector =
+                        buildIngressTrafficSelector(intf, prefix);
+
+                // Create the Filtered ConnectPoint and add it to the existing set
+                FilteredConnectPoint newIngressFilteredCP =
+                        new FilteredConnectPoint(intf.connectPoint(), selector.build());
+                ingressFilteredCPs.add(newIngressFilteredCP);
+
+                // Create new intent
+                MultiPointToSinglePointIntent newIntent =
+                        MultiPointToSinglePointIntent.builder(intent)
+                                .filteredIngressPoints(ingressFilteredCPs)
+                                .build();
+
+                routeIntents.put(entry.getKey(), newIntent);
+                intentSynchronizer.submit(newIntent);
             }
         }
+    }
+
+    /*
+     * Handles the case in which an existing interface gets removed.
+     */
+    private void removeInterface(Interface intf) {
+        synchronized (this) {
+            for (Map.Entry<IpPrefix, MultiPointToSinglePointIntent> entry : routeIntents.entrySet()) {
+                // Retrieve the IP prefix and intent possibly affected
+                IpPrefix prefix = entry.getKey();
+                MultiPointToSinglePointIntent intent = entry.getValue();
+
+                // The interface removed might be an ingress interface, so the
+                // selector needs to match on the interface tagging params and
+                // on the prefix
+                TrafficSelector.Builder ingressSelector =
+                        buildIngressTrafficSelector(intf, prefix);
+                FilteredConnectPoint removedIngressFilteredCP =
+                        new FilteredConnectPoint(intf.connectPoint(),
+                                                 ingressSelector.build());
+
+                // The interface removed might be an egress interface, so the
+                // selector needs to match only on the interface tagging params
+                TrafficSelector.Builder selector = buildTrafficSelector(intf);
+                FilteredConnectPoint removedEgressFilteredCP =
+                        new FilteredConnectPoint(intf.connectPoint(), selector.build());
+
+                if (intent.filteredEgressPoint().equals(removedEgressFilteredCP)) {
+                     // The interface is an egress interface for the intent.
+                     // This intent just lost its head. Remove it and let higher
+                     // layer routing reroute
+                    intentSynchronizer.withdraw(routeIntents.remove(entry.getKey()));
+                } else {
+                    if (intent.filteredIngressPoints().contains(removedIngressFilteredCP)) {
+                         // The FilteredConnectPoint is an ingress
+                         // FilteredConnectPoint for the intent
+                        Set<FilteredConnectPoint> ingressFilteredCPs =
+                                Sets.newHashSet(intent.filteredIngressPoints());
+
+                        // Remove FilteredConnectPoint from the existing set
+                        ingressFilteredCPs.remove(removedIngressFilteredCP);
+
+                        if (!ingressFilteredCPs.isEmpty()) {
+                             // There are still ingress points. Create a new
+                             // intent and resubmit
+                            MultiPointToSinglePointIntent newIntent =
+                                    MultiPointToSinglePointIntent.builder(intent)
+                                            .filteredIngressPoints(ingressFilteredCPs)
+                                            .build();
+
+                            routeIntents.put(entry.getKey(), newIntent);
+                            intentSynchronizer.submit(newIntent);
+                        } else {
+                             // No more ingress FilteredConnectPoint. Withdraw
+                             //the intent
+                            intentSynchronizer.withdraw(routeIntents.remove(entry.getKey()));
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /*
+     * Builds an ingress traffic selector builder given an ingress interface and
+     * the IP prefix to be reached.
+     */
+    private TrafficSelector.Builder buildIngressTrafficSelector(Interface intf, IpPrefix prefix) {
+        TrafficSelector.Builder selector = buildTrafficSelector(intf);
 
         // Match the destination IP prefix at the first hop
         if (prefix.isIp4()) {
@@ -206,83 +322,33 @@
                 selector.matchIPv6Dst(prefix);
             }
         }
-
-        // Rewrite the destination MAC address
-        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder()
-                .setEthDst(nextHopMacAddress);
-
-        // Set egress VLAN Id
-        // TODO need to make the comparison with different ingress VLAN Ids
-        if (!ingressVlanId.equals(egressInterface.vlan())) {
-            if (egressInterface.vlan().equals(VlanId.NONE)) {
-                treatment.popVlan();
-            } else {
-                treatment.setVlanId(egressInterface.vlan());
-            }
-        }
-
-        // Set priority
-        int priority =
-                prefix.prefixLength() * PRIORITY_MULTIPLIER + PRIORITY_OFFSET;
-
-        // Set key
-        Key key = Key.of(prefix.toString(), appId);
-
-        return MultiPointToSinglePointIntent.builder()
-                .appId(appId)
-                .key(key)
-                .selector(selector.build())
-                .treatment(treatment.build())
-                .ingressPoints(ingressPorts)
-                .egressPoint(egressPort)
-                .priority(priority)
-                .constraints(CONSTRAINTS)
-                .build();
+        return selector;
     }
 
-    private void updateInterface(Interface intf) {
-        synchronized (this) {
-            for (Map.Entry<IpPrefix, MultiPointToSinglePointIntent> entry : routeIntents.entrySet()) {
-                MultiPointToSinglePointIntent intent = entry.getValue();
-                Set<ConnectPoint> ingress = Sets.newHashSet(intent.ingressPoints());
-                ingress.add(intf.connectPoint());
+    /*
+     * Builds a traffic selector builder based on interface tagging settings.
+     */
+    private TrafficSelector.Builder buildTrafficSelector(Interface intf) {
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
 
-                MultiPointToSinglePointIntent newIntent =
-                        MultiPointToSinglePointIntent.builder(intent)
-                                .ingressPoints(ingress)
-                                .build();
-
-                routeIntents.put(entry.getKey(), newIntent);
-                intentSynchronizer.submit(newIntent);
-            }
+        // TODO: Consider other tag types
+        // Match the VlanId if specified in the network interface configuration
+        VlanId vlanId = intf.vlan();
+        if (!vlanId.equals(VlanId.NONE)) {
+            selector.matchVlanId(vlanId);
         }
+        return selector;
     }
 
-    private void removeInterface(Interface intf) {
-        synchronized (this) {
-            for (Map.Entry<IpPrefix, MultiPointToSinglePointIntent> entry : routeIntents.entrySet()) {
-                MultiPointToSinglePointIntent intent = entry.getValue();
-                if (intent.egressPoint().equals(intf.connectPoint())) {
-                    // This intent just lost its head. Remove it and let
-                    // higher layer routing reroute.
-                    intentSynchronizer.withdraw(routeIntents.remove(entry.getKey()));
-                } else {
-                    if (intent.ingressPoints().contains(intf.connectPoint())) {
-
-                        Set<ConnectPoint> ingress = Sets.newHashSet(intent.ingressPoints());
-                        ingress.remove(intf.connectPoint());
-
-                        MultiPointToSinglePointIntent newIntent =
-                                MultiPointToSinglePointIntent.builder(intent)
-                                .ingressPoints(ingress)
-                                .build();
-
-                        routeIntents.put(entry.getKey(), newIntent);
-                        intentSynchronizer.submit(newIntent);
-                    }
-                }
-            }
+    // Check if the interface is an ingress interface with IPs configured
+    private boolean validIngressIntf(Interface intf, Interface egressInterface) {
+        if (!intf.equals(egressInterface) &&
+                !intf.ipAddressesList().isEmpty() &&
+                // TODO: An egress point might have two routers connected on different interfaces
+                !intf.connectPoint().equals(egressInterface.connectPoint())) {
+            return true;
         }
+        return false;
     }
 
     private class InternalRouteListener implements RouteListener {
@@ -308,9 +374,11 @@
         public void event(InterfaceEvent event) {
             switch (event.type()) {
             case INTERFACE_ADDED:
-                updateInterface(event.subject());
+                addInterface(event.subject());
                 break;
             case INTERFACE_UPDATED:
+                removeInterface(event.prevSubject());
+                addInterface(event.subject());
                 break;
             case INTERFACE_REMOVED:
                 removeInterface(event.subject());
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/PeerConnectivityManagerTest.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/PeerConnectivityManagerTest.java
index 0d5d2b1..b8e4e1b 100644
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/PeerConnectivityManagerTest.java
+++ b/apps/sdnip/src/test/java/org/onosproject/sdnip/PeerConnectivityManagerTest.java
@@ -316,7 +316,7 @@
                 .matchIPDst(IpPrefix.valueOf(dstPrefix));
 
         if (!srcVlanId.equals(VlanId.NONE)) {
-            builder.matchVlanId(VlanId.ANY);
+            builder.matchVlanId(srcVlanId);
         }
 
         TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
@@ -495,7 +495,7 @@
                 .matchIPDst(IpPrefix.valueOf(dstPrefix));
 
         if (!srcVlanId.equals(VlanId.NONE)) {
-            builder.matchVlanId(VlanId.ANY);
+            builder.matchVlanId(srcVlanId);
         }
 
         TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibNoVlansTest.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibNoVlansTest.java
deleted file mode 100644
index 3f44a01..0000000
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibNoVlansTest.java
+++ /dev/null
@@ -1,426 +0,0 @@
-/*
- * 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.sdnip;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import org.junit.Before;
-import org.junit.Test;
-import org.onlab.packet.Ethernet;
-import org.onlab.packet.Ip4Address;
-import org.onlab.packet.Ip4Prefix;
-import org.onlab.packet.IpPrefix;
-import org.onlab.packet.MacAddress;
-import org.onlab.packet.VlanId;
-import org.onosproject.TestApplicationId;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.core.CoreServiceAdapter;
-import org.onosproject.incubator.net.intf.Interface;
-import org.onosproject.incubator.net.intf.InterfaceEvent;
-import org.onosproject.incubator.net.intf.InterfaceListener;
-import org.onosproject.incubator.net.intf.InterfaceService;
-import org.onosproject.incubator.net.intf.InterfaceServiceAdapter;
-import org.onosproject.incubator.net.routing.ResolvedRoute;
-import org.onosproject.incubator.net.routing.RouteEvent;
-import org.onosproject.incubator.net.routing.RouteListener;
-import org.onosproject.incubator.net.routing.RouteServiceAdapter;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.host.InterfaceIpAddress;
-import org.onosproject.net.intent.AbstractIntentTest;
-import org.onosproject.net.intent.Key;
-import org.onosproject.net.intent.MultiPointToSinglePointIntent;
-import org.onosproject.routing.IntentSynchronizationService;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import static org.easymock.EasyMock.anyObject;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-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.onosproject.routing.TestIntentServiceHelper.eqExceptId;
-
-/**
- * Unit tests for SdnIpFib.
- */
-public class SdnIpFibNoVlansTest extends AbstractIntentTest {
-
-    private InterfaceService interfaceService;
-
-    private static final ConnectPoint SW1_ETH1 = new ConnectPoint(
-            DeviceId.deviceId("of:0000000000000001"),
-            PortNumber.portNumber(1));
-
-    private static final ConnectPoint SW2_ETH1 = new ConnectPoint(
-            DeviceId.deviceId("of:0000000000000002"),
-            PortNumber.portNumber(1));
-
-    private static final ConnectPoint SW3_ETH1 = new ConnectPoint(
-            DeviceId.deviceId("of:0000000000000003"),
-            PortNumber.portNumber(1));
-
-    private static final ConnectPoint SW4_ETH1 = new ConnectPoint(
-            DeviceId.deviceId("of:0000000000000004"),
-            PortNumber.portNumber(1));
-
-    private static final IpPrefix PREFIX1 = Ip4Prefix.valueOf("1.1.1.0/24");
-
-    private SdnIpFib sdnipFib;
-    private IntentSynchronizationService intentSynchronizer;
-    private final Set<Interface> interfaces = Sets.newHashSet();
-
-    private static final ApplicationId APPID = TestApplicationId.create("SDNIP");
-
-    private RouteListener routeListener;
-    private InterfaceListener interfaceListener;
-
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-
-        interfaceService = createMock(InterfaceService.class);
-
-        interfaceService.addListener(anyObject(InterfaceListener.class));
-        expectLastCall().andDelegateTo(new InterfaceServiceDelegate());
-
-        // These will set expectations on routingConfig and interfaceService
-        setUpInterfaceService();
-
-        replay(interfaceService);
-
-        intentSynchronizer = createMock(IntentSynchronizationService.class);
-
-        sdnipFib = new SdnIpFib();
-        sdnipFib.routeService = new TestRouteService();
-        sdnipFib.coreService = new TestCoreService();
-        sdnipFib.interfaceService = interfaceService;
-        sdnipFib.intentSynchronizer = intentSynchronizer;
-
-        sdnipFib.activate();
-    }
-
-    /**
-     * Sets up the interface service.
-     */
-    private void setUpInterfaceService() {
-        List<InterfaceIpAddress> interfaceIpAddresses1 = Lists.newArrayList();
-        interfaceIpAddresses1.add(InterfaceIpAddress.valueOf("192.168.10.101/24"));
-        Interface sw1Eth1 = new Interface("sw1-eth1", SW1_ETH1,
-                                          interfaceIpAddresses1, MacAddress.valueOf("00:00:00:00:00:01"),
-                                          VlanId.NONE);
-        interfaces.add(sw1Eth1);
-
-        List<InterfaceIpAddress> interfaceIpAddresses2 = Lists.newArrayList();
-        interfaceIpAddresses2.add(InterfaceIpAddress.valueOf("192.168.20.101/24"));
-        Interface sw2Eth1 = new Interface("sw2-eth1", SW2_ETH1,
-                                          interfaceIpAddresses2, MacAddress.valueOf("00:00:00:00:00:02"),
-                                          VlanId.NONE);
-        interfaces.add(sw2Eth1);
-
-        InterfaceIpAddress interfaceIpAddress3 = InterfaceIpAddress.valueOf("192.168.30.101/24");
-        Interface sw3Eth1 = new Interface("sw3-eth1", SW3_ETH1,
-                                          Lists.newArrayList(interfaceIpAddress3),
-                                          MacAddress.valueOf("00:00:00:00:00:03"),
-                                          VlanId.NONE);
-        interfaces.add(sw3Eth1);
-
-        expect(interfaceService.getInterfacesByPort(SW1_ETH1)).andReturn(
-                Collections.singleton(sw1Eth1)).anyTimes();
-        expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.10.1")))
-                .andReturn(sw1Eth1).anyTimes();
-        expect(interfaceService.getInterfacesByPort(SW2_ETH1)).andReturn(
-                Collections.singleton(sw2Eth1)).anyTimes();
-        expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.20.1")))
-                .andReturn(sw2Eth1).anyTimes();
-        expect(interfaceService.getInterfacesByPort(SW3_ETH1)).andReturn(
-                Collections.singleton(sw3Eth1)).anyTimes();
-        expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.30.1")))
-                .andReturn(sw3Eth1).anyTimes();
-        expect(interfaceService.getInterfaces()).andReturn(interfaces).anyTimes();
-    }
-
-    /**
-     * Tests adding a route. All interfaces have no VLAN Ids configured.
-     *
-     * We verify that the synchronizer records the correct state and that the
-     * correct intent is submitted to the IntentService.
-     */
-    @Test
-    public void testRouteAddNoVlans() {
-        ResolvedRoute route = new ResolvedRoute(PREFIX1,
-                                                Ip4Address.valueOf("192.168.30.1"),
-                                                MacAddress.valueOf("00:00:00:00:00:03"));
-
-        // Construct a MultiPointToSinglePointIntent intent
-        TrafficSelector.Builder selectorBuilder =
-                DefaultTrafficSelector.builder();
-        selectorBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(PREFIX1);
-
-        TrafficTreatment.Builder treatmentBuilder =
-                DefaultTrafficTreatment.builder();
-        treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:03"));
-
-        Set<ConnectPoint> ingressPoints = new HashSet<>();
-        ingressPoints.add(SW1_ETH1);
-        ingressPoints.add(SW2_ETH1);
-
-        MultiPointToSinglePointIntent intent =
-                MultiPointToSinglePointIntent.builder()
-                        .appId(APPID)
-                        .key(Key.of(PREFIX1.toString(), APPID))
-                        .selector(selectorBuilder.build())
-                        .treatment(treatmentBuilder.build())
-                        .ingressPoints(ingressPoints)
-                        .egressPoint(SW3_ETH1)
-                        .constraints(SdnIpFib.CONSTRAINTS)
-                        .build();
-
-        // Setup the expected intents
-        intentSynchronizer.submit(eqExceptId(intent));
-        replay(intentSynchronizer);
-
-        // Send in the added event
-        routeListener.event(new RouteEvent(RouteEvent.Type.ROUTE_ADDED, route));
-
-        verify(intentSynchronizer);
-    }
-
-    /**
-     * Tests updating a route.
-     *
-     * We verify that the synchronizer records the correct state and that the
-     * correct intent is submitted to the IntentService.
-     */
-    @Test
-    public void testRouteUpdate() {
-        // Add a route first
-        testRouteAddNoVlans();
-
-        // Start to construct a new route entry and new intent
-        ResolvedRoute route = new ResolvedRoute(PREFIX1,
-                Ip4Address.valueOf("192.168.20.1"),
-                MacAddress.valueOf("00:00:00:00:00:02"));
-
-        // Construct a new MultiPointToSinglePointIntent intent
-        TrafficSelector.Builder selectorBuilderNew =
-                DefaultTrafficSelector.builder();
-        selectorBuilderNew.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(PREFIX1);
-
-        TrafficTreatment.Builder treatmentBuilderNew =
-                DefaultTrafficTreatment.builder();
-        treatmentBuilderNew.setEthDst(MacAddress.valueOf("00:00:00:00:00:02"));
-
-        Set<ConnectPoint> ingressPointsNew = new HashSet<>();
-        ingressPointsNew.add(SW1_ETH1);
-        ingressPointsNew.add(SW3_ETH1);
-
-        MultiPointToSinglePointIntent intentNew =
-                MultiPointToSinglePointIntent.builder()
-                        .appId(APPID)
-                        .key(Key.of(PREFIX1.toString(), APPID))
-                        .selector(selectorBuilderNew.build())
-                        .treatment(treatmentBuilderNew.build())
-                        .ingressPoints(ingressPointsNew)
-                        .egressPoint(SW2_ETH1)
-                        .constraints(SdnIpFib.CONSTRAINTS)
-                        .build();
-
-        // Set up test expectation
-        reset(intentSynchronizer);
-
-        // Setup the expected intents
-        intentSynchronizer.submit(eqExceptId(intentNew));
-        replay(intentSynchronizer);
-
-        // Send in the update event
-        routeListener.event(new RouteEvent(RouteEvent.Type.ROUTE_UPDATED, route));
-
-        verify(intentSynchronizer);
-    }
-
-    /**
-     * Tests deleting a route.
-     *
-     * We verify that the synchronizer records the correct state and that the
-     * correct intent is withdrawn from the IntentService.
-     */
-    @Test
-    public void testRouteDelete() {
-        // Add a route first
-        testRouteAddNoVlans();
-
-        // Construct the existing route entry
-        ResolvedRoute route = new ResolvedRoute(PREFIX1, null, null);
-
-        // Construct the existing MultiPointToSinglePoint intent
-        TrafficSelector.Builder selectorBuilder =
-                DefaultTrafficSelector.builder();
-        selectorBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(PREFIX1);
-
-        TrafficTreatment.Builder treatmentBuilder =
-                DefaultTrafficTreatment.builder();
-        treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:03"));
-
-        Set<ConnectPoint> ingressPoints = new HashSet<>();
-        ingressPoints.add(SW1_ETH1);
-        ingressPoints.add(SW2_ETH1);
-
-        MultiPointToSinglePointIntent addedIntent =
-                MultiPointToSinglePointIntent.builder()
-                        .appId(APPID)
-                        .key(Key.of(PREFIX1.toString(), APPID))
-                        .selector(selectorBuilder.build())
-                        .treatment(treatmentBuilder.build())
-                        .ingressPoints(ingressPoints)
-                        .egressPoint(SW3_ETH1)
-                        .constraints(SdnIpFib.CONSTRAINTS)
-                        .build();
-
-        // Set up expectation
-        reset(intentSynchronizer);
-        // Setup the expected intents
-        intentSynchronizer.withdraw(eqExceptId(addedIntent));
-        replay(intentSynchronizer);
-
-        // Send in the removed event
-        routeListener.event(new RouteEvent(RouteEvent.Type.ROUTE_REMOVED, route));
-
-        verify(intentSynchronizer);
-    }
-
-    @Test
-    public void testAddInterface() {
-        // Add a route first
-        testRouteAddNoVlans();
-
-        // Construct the existing MultiPointToSinglePoint intent
-        TrafficSelector.Builder selectorBuilder =
-                DefaultTrafficSelector.builder();
-        selectorBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(PREFIX1);
-
-        TrafficTreatment.Builder treatmentBuilder =
-                DefaultTrafficTreatment.builder();
-        treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:03"));
-
-        Set<ConnectPoint> ingressPoints = new HashSet<>();
-        ingressPoints.add(SW1_ETH1);
-        ingressPoints.add(SW2_ETH1);
-        ingressPoints.add(SW4_ETH1);
-
-        MultiPointToSinglePointIntent addedIntent =
-                MultiPointToSinglePointIntent.builder()
-                        .appId(APPID)
-                        .key(Key.of(PREFIX1.toString(), APPID))
-                        .selector(selectorBuilder.build())
-                        .treatment(treatmentBuilder.build())
-                        .ingressPoints(ingressPoints)
-                        .egressPoint(SW3_ETH1)
-                        .constraints(SdnIpFib.CONSTRAINTS)
-                        .build();
-
-        reset(intentSynchronizer);
-
-        intentSynchronizer.submit(eqExceptId(addedIntent));
-        expectLastCall().once();
-
-        replay(intentSynchronizer);
-
-        Interface intf = new Interface("sw4-eth1", SW4_ETH1,
-                Collections.singletonList(InterfaceIpAddress.valueOf("192.168.40.101/24")),
-                MacAddress.valueOf("00:00:00:00:00:04"), VlanId.NONE);
-        InterfaceEvent intfEvent = new InterfaceEvent(InterfaceEvent.Type.INTERFACE_ADDED, intf);
-        interfaceListener.event(intfEvent);
-
-        verify(intentSynchronizer);
-    }
-
-    @Test
-    public void testRemoveInterface() {
-        // Add a route first
-        testRouteAddNoVlans();
-
-        // Construct the existing MultiPointToSinglePoint intent
-        TrafficSelector.Builder selectorBuilder =
-                DefaultTrafficSelector.builder();
-        selectorBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(PREFIX1);
-
-        TrafficTreatment.Builder treatmentBuilder =
-                DefaultTrafficTreatment.builder();
-        treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:03"));
-
-        Set<ConnectPoint> ingressPoints = new HashSet<>();
-        ingressPoints.add(SW2_ETH1);
-
-        MultiPointToSinglePointIntent addedIntent =
-                MultiPointToSinglePointIntent.builder()
-                        .appId(APPID)
-                        .key(Key.of(PREFIX1.toString(), APPID))
-                        .selector(selectorBuilder.build())
-                        .treatment(treatmentBuilder.build())
-                        .ingressPoints(ingressPoints)
-                        .egressPoint(SW3_ETH1)
-                        .constraints(SdnIpFib.CONSTRAINTS)
-                        .build();
-
-        reset(intentSynchronizer);
-
-        intentSynchronizer.submit(eqExceptId(addedIntent));
-        expectLastCall().once();
-
-        replay(intentSynchronizer);
-
-        Interface intf = new Interface("sw1-eth1", SW1_ETH1,
-                Collections.singletonList(InterfaceIpAddress.valueOf("192.168.10.101/24")),
-                MacAddress.valueOf("00:00:00:00:00:01"), VlanId.NONE);
-        InterfaceEvent intfEvent = new InterfaceEvent(InterfaceEvent.Type.INTERFACE_REMOVED, intf);
-        interfaceListener.event(intfEvent);
-
-        verify(intentSynchronizer);
-    }
-
-    private class TestCoreService extends CoreServiceAdapter {
-        @Override
-        public ApplicationId getAppId(String name) {
-            return APPID;
-        }
-    }
-
-    private class TestRouteService extends RouteServiceAdapter {
-        @Override
-        public void addListener(RouteListener routeListener) {
-            SdnIpFibNoVlansTest.this.routeListener = routeListener;
-        }
-    }
-
-    private class InterfaceServiceDelegate extends InterfaceServiceAdapter {
-        @Override
-        public void addListener(InterfaceListener listener) {
-            SdnIpFibNoVlansTest.this.interfaceListener = listener;
-        }
-    }
-}
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibNoVlanstoVlanTest.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibNoVlanstoVlanTest.java
deleted file mode 100644
index 84657c8..0000000
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibNoVlanstoVlanTest.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * 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.sdnip;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import org.junit.Before;
-import org.junit.Test;
-import org.onlab.packet.Ethernet;
-import org.onlab.packet.Ip4Address;
-import org.onlab.packet.Ip4Prefix;
-import org.onlab.packet.IpPrefix;
-import org.onlab.packet.MacAddress;
-import org.onlab.packet.VlanId;
-import org.onosproject.TestApplicationId;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.core.CoreServiceAdapter;
-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.intf.InterfaceServiceAdapter;
-import org.onosproject.incubator.net.routing.ResolvedRoute;
-import org.onosproject.incubator.net.routing.RouteEvent;
-import org.onosproject.incubator.net.routing.RouteListener;
-import org.onosproject.incubator.net.routing.RouteServiceAdapter;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.host.InterfaceIpAddress;
-import org.onosproject.net.intent.AbstractIntentTest;
-import org.onosproject.net.intent.Key;
-import org.onosproject.net.intent.MultiPointToSinglePointIntent;
-import org.onosproject.routing.IntentSynchronizationService;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import static org.easymock.EasyMock.*;
-import static org.onosproject.routing.TestIntentServiceHelper.eqExceptId;
-
-/**
- * Unit tests for SdnIpFib.
- */
-public class SdnIpFibNoVlanstoVlanTest extends AbstractIntentTest {
-
-    private InterfaceService interfaceService;
-
-    private static final ConnectPoint SW1_ETH1 = new ConnectPoint(
-            DeviceId.deviceId("of:0000000000000001"),
-            PortNumber.portNumber(1));
-
-    private static final ConnectPoint SW2_ETH1 = new ConnectPoint(
-            DeviceId.deviceId("of:0000000000000002"),
-            PortNumber.portNumber(1));
-
-    private static final ConnectPoint SW3_ETH1 = new ConnectPoint(
-            DeviceId.deviceId("of:0000000000000003"),
-            PortNumber.portNumber(1));
-
-    private static final IpPrefix PREFIX1 = Ip4Prefix.valueOf("1.1.1.0/24");
-
-    private SdnIpFib sdnipFib;
-    private IntentSynchronizationService intentSynchronizer;
-    private final Set<Interface> interfaces = Sets.newHashSet();
-
-    private static final ApplicationId APPID = TestApplicationId.create("SDNIP");
-
-    private RouteListener routeListener;
-    private InterfaceListener interfaceListener;
-
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-
-        interfaceService = createMock(InterfaceService.class);
-
-        interfaceService.addListener(anyObject(InterfaceListener.class));
-        expectLastCall().andDelegateTo(new InterfaceServiceDelegate());
-
-        // These will set expectations on routingConfig and interfaceService
-        setUpInterfaceService();
-
-        replay(interfaceService);
-
-        intentSynchronizer = createMock(IntentSynchronizationService.class);
-
-        sdnipFib = new SdnIpFib();
-        sdnipFib.routeService = new TestRouteService();
-        sdnipFib.coreService = new TestCoreService();
-        sdnipFib.interfaceService = interfaceService;
-        sdnipFib.intentSynchronizer = intentSynchronizer;
-
-        sdnipFib.activate();
-    }
-
-    /**
-     * Sets up the interface service.
-     */
-    private void setUpInterfaceService() {
-        List<InterfaceIpAddress> interfaceIpAddresses1 = Lists.newArrayList();
-        interfaceIpAddresses1.add(InterfaceIpAddress.valueOf("192.168.10.101/24"));
-        Interface sw1Eth1 = new Interface("sw1-eth1", SW1_ETH1,
-                                          interfaceIpAddresses1, MacAddress.valueOf("00:00:00:00:00:01"),
-                                          VlanId.NONE);
-        interfaces.add(sw1Eth1);
-
-        List<InterfaceIpAddress> interfaceIpAddresses2 = Lists.newArrayList();
-        interfaceIpAddresses2.add(InterfaceIpAddress.valueOf("192.168.20.101/24"));
-        Interface sw2Eth1 = new Interface("sw2-eth1", SW2_ETH1,
-                                          interfaceIpAddresses2, MacAddress.valueOf("00:00:00:00:00:02"),
-                                          VlanId.NONE);
-        interfaces.add(sw2Eth1);
-
-        InterfaceIpAddress interfaceIpAddress3 = InterfaceIpAddress.valueOf("192.168.30.101/24");
-        Interface sw3Eth1 = new Interface("sw3-eth1", SW3_ETH1,
-                                          Lists.newArrayList(interfaceIpAddress3),
-                                          MacAddress.valueOf("00:00:00:00:00:03"),
-                                          VlanId.vlanId((short) 1));
-        interfaces.add(sw3Eth1);
-
-        expect(interfaceService.getInterfacesByPort(SW1_ETH1)).andReturn(
-                Collections.singleton(sw1Eth1)).anyTimes();
-        expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.10.1")))
-                .andReturn(sw1Eth1).anyTimes();
-        expect(interfaceService.getInterfacesByPort(SW2_ETH1)).andReturn(
-                Collections.singleton(sw2Eth1)).anyTimes();
-        expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.20.1")))
-                .andReturn(sw2Eth1).anyTimes();
-        expect(interfaceService.getInterfacesByPort(SW3_ETH1)).andReturn(
-                Collections.singleton(sw3Eth1)).anyTimes();
-        expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.30.1")))
-                .andReturn(sw3Eth1).anyTimes();
-        expect(interfaceService.getInterfaces()).andReturn(interfaces).anyTimes();
-    }
-
-    /**
-     * Tests adding a route. Ingresses with no VLAN and next hop with VLAN.
-     *
-     * We verify that the synchronizer records the correct state and that the
-     * correct intent is submitted to the IntentService.
-     */
-    @Test
-    public void testRouteAdd() {
-        ResolvedRoute route = new ResolvedRoute(PREFIX1,
-                Ip4Address.valueOf("192.168.30.1"),
-                MacAddress.valueOf("00:00:00:00:00:03"));
-
-        // Construct a MultiPointToSinglePointIntent intent
-        TrafficSelector.Builder selectorBuilder =
-                DefaultTrafficSelector.builder();
-        selectorBuilder.matchEthType(Ethernet.TYPE_IPV4)
-                .matchIPDst(PREFIX1);
-
-        TrafficTreatment.Builder treatmentBuilder =
-                DefaultTrafficTreatment.builder();
-        treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:03"))
-                .setVlanId(VlanId.vlanId((short) 1));
-
-        Set<ConnectPoint> ingressPoints = new HashSet<>();
-        ingressPoints.add(SW1_ETH1);
-        ingressPoints.add(SW2_ETH1);
-
-        MultiPointToSinglePointIntent intent =
-                MultiPointToSinglePointIntent.builder()
-                        .appId(APPID)
-                        .key(Key.of(PREFIX1.toString(), APPID))
-                        .selector(selectorBuilder.build())
-                        .treatment(treatmentBuilder.build())
-                        .ingressPoints(ingressPoints)
-                        .egressPoint(SW3_ETH1)
-                        .constraints(SdnIpFib.CONSTRAINTS)
-                        .build();
-
-        // Setup the expected intents
-        intentSynchronizer.submit(eqExceptId(intent));
-
-        replay(intentSynchronizer);
-
-        // Send in the added event
-        routeListener.event(new RouteEvent(RouteEvent.Type.ROUTE_ADDED, route));
-
-        verify(intentSynchronizer);
-    }
-
-    private class TestCoreService extends CoreServiceAdapter {
-        @Override
-        public ApplicationId getAppId(String name) {
-            return APPID;
-        }
-    }
-
-    private class TestRouteService extends RouteServiceAdapter {
-        @Override
-        public void addListener(RouteListener routeListener) {
-            SdnIpFibNoVlanstoVlanTest.this.routeListener = routeListener;
-        }
-    }
-
-    private class InterfaceServiceDelegate extends InterfaceServiceAdapter {
-        @Override
-        public void addListener(InterfaceListener listener) {
-            SdnIpFibNoVlanstoVlanTest.this.interfaceListener = listener;
-        }
-    }
-}
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibTest.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibTest.java
new file mode 100644
index 0000000..762ce52
--- /dev/null
+++ b/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibTest.java
@@ -0,0 +1,643 @@
+/*
+ * Copyright 2015-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.sdnip;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.TestApplicationId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.incubator.net.intf.InterfaceEvent;
+import org.onosproject.incubator.net.intf.InterfaceListener;
+import org.onosproject.incubator.net.intf.InterfaceService;
+import org.onosproject.incubator.net.intf.InterfaceServiceAdapter;
+import org.onosproject.incubator.net.routing.ResolvedRoute;
+import org.onosproject.incubator.net.routing.RouteEvent;
+import org.onosproject.incubator.net.routing.RouteListener;
+import org.onosproject.incubator.net.routing.RouteServiceAdapter;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.FilteredConnectPoint;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.host.InterfaceIpAddress;
+import org.onosproject.net.intent.AbstractIntentTest;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.MultiPointToSinglePointIntent;
+import org.onosproject.routing.IntentSynchronizationService;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+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.onosproject.routing.TestIntentServiceHelper.eqExceptId;
+
+/**
+ * Unit tests for SdnIpFib.
+ */
+public class SdnIpFibTest extends AbstractIntentTest {
+
+    private InterfaceService interfaceService;
+
+    private static final ConnectPoint SW1_ETH1 = new ConnectPoint(
+            DeviceId.deviceId("of:0000000000000001"),
+            PortNumber.portNumber(1));
+
+    private static final ConnectPoint SW2_ETH1 = new ConnectPoint(
+            DeviceId.deviceId("of:0000000000000002"),
+            PortNumber.portNumber(1));
+
+    private static final ConnectPoint SW3_ETH1 = new ConnectPoint(
+            DeviceId.deviceId("of:0000000000000003"),
+            PortNumber.portNumber(1));
+
+    private static final ConnectPoint SW4_ETH1 = new ConnectPoint(
+            DeviceId.deviceId("of:0000000000000004"),
+            PortNumber.portNumber(1));
+
+    private static final MacAddress MAC1 = MacAddress.valueOf("00:00:00:00:00:01");
+    private static final MacAddress MAC2 = MacAddress.valueOf("00:00:00:00:00:02");
+    private static final MacAddress MAC3 = MacAddress.valueOf("00:00:00:00:00:03");
+    private static final MacAddress MAC4 = MacAddress.valueOf("00:00:00:00:00:04");
+
+    private static final VlanId NO_VLAN = VlanId.NONE;
+    private static final VlanId VLAN10 = VlanId.vlanId(Short.valueOf("10"));
+    private static final VlanId VLAN20 = VlanId.vlanId(Short.valueOf("20"));
+
+    private static final InterfaceIpAddress IIP1 =
+            InterfaceIpAddress.valueOf("192.168.10.101/24");
+    private static final InterfaceIpAddress IIP2 =
+            InterfaceIpAddress.valueOf("192.168.20.101/24");
+    private static final InterfaceIpAddress IIP3 =
+            InterfaceIpAddress.valueOf("192.168.30.101/24");
+    private static final InterfaceIpAddress IIP4 =
+            InterfaceIpAddress.valueOf("192.168.40.101/24");
+
+    private static final IpAddress IP1 = Ip4Address.valueOf("192.168.10.1");
+    private static final IpAddress IP2 = Ip4Address.valueOf("192.168.20.1");
+    private static final IpAddress IP3 = Ip4Address.valueOf("192.168.30.1");
+
+    private static final IpPrefix PREFIX1 = Ip4Prefix.valueOf("1.1.1.0/24");
+    private static final IpPrefix PREFIX2 = Ip4Prefix.valueOf("1.1.2.0/24");
+
+    private SdnIpFib sdnipFib;
+    private IntentSynchronizationService intentSynchronizer;
+    private final Set<Interface> interfaces = Sets.newHashSet();
+
+    private static final ApplicationId APPID = TestApplicationId.create("SDNIP");
+
+    private RouteListener routeListener;
+    private InterfaceListener interfaceListener;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+
+        interfaceService = createMock(InterfaceService.class);
+
+        interfaceService.addListener(anyObject(InterfaceListener.class));
+        expectLastCall().andDelegateTo(new InterfaceServiceDelegate());
+
+        // These will set expectations on routingConfig and interfaceService
+        setUpInterfaceService();
+
+        replay(interfaceService);
+
+        intentSynchronizer = createMock(IntentSynchronizationService.class);
+
+        sdnipFib = new SdnIpFib();
+        sdnipFib.routeService = new TestRouteService();
+        sdnipFib.coreService = new TestCoreService();
+        sdnipFib.interfaceService = interfaceService;
+        sdnipFib.intentSynchronizer = intentSynchronizer;
+
+        sdnipFib.activate();
+    }
+
+    /**
+     * Sets up the interface service.
+     */
+    private void setUpInterfaceService() {
+        List<InterfaceIpAddress> iIps1 = Lists.newArrayList();
+        iIps1.add(IIP1);
+        Interface sw1Eth1 = new Interface("sw1-eth1", SW1_ETH1, iIps1, MAC1, VLAN10);
+        interfaces.add(sw1Eth1);
+
+        List<InterfaceIpAddress> iIps2 = Lists.newArrayList();
+        iIps2.add(IIP2);
+        Interface sw2Eth1 = new Interface("sw2-eth1", SW2_ETH1, iIps2, MAC2, VLAN20);
+        interfaces.add(sw2Eth1);
+
+        List<InterfaceIpAddress> iIps3 = Lists.newArrayList();
+        iIps3.add(IIP3);
+        Interface sw3Eth1 = new Interface("sw3-eth1", SW3_ETH1, iIps3, MAC3, NO_VLAN);
+        interfaces.add(sw3Eth1);
+
+        expect(interfaceService.getInterfacesByPort(SW1_ETH1)).andReturn(
+                Collections.singleton(sw1Eth1)).anyTimes();
+        expect(interfaceService.getMatchingInterface(IP1))
+                .andReturn(sw1Eth1).anyTimes();
+        expect(interfaceService.getInterfacesByPort(SW2_ETH1)).andReturn(
+                Collections.singleton(sw2Eth1)).anyTimes();
+        expect(interfaceService.getMatchingInterface(IP2))
+                .andReturn(sw2Eth1).anyTimes();
+        expect(interfaceService.getInterfacesByPort(SW3_ETH1)).andReturn(
+                Collections.singleton(sw3Eth1)).anyTimes();
+        expect(interfaceService.getMatchingInterface(IP3))
+                .andReturn(sw3Eth1).anyTimes();
+        expect(interfaceService.getInterfaces()).andReturn(interfaces).anyTimes();
+    }
+
+    /**
+     * Tests adding a route. The egress interface has no VLAN configured.
+     *
+     * We verify that the synchronizer records the correct state and that the
+     * correct intent is submitted to the IntentService.
+     */
+    @Test
+    public void testRouteAddToNoVlan() {
+        // Build the expected route
+        ResolvedRoute route = new ResolvedRoute(PREFIX1, IP3, MAC3);
+
+        MultiPointToSinglePointIntent intent =
+                createIntentToThreeSrcOneTwo(PREFIX1);
+
+        // Setup the expected intents
+        intentSynchronizer.submit(eqExceptId(intent));
+        replay(intentSynchronizer);
+
+        // Send in the added event
+        routeListener.event(new RouteEvent(RouteEvent.Type.ROUTE_ADDED, route));
+
+        verify(intentSynchronizer);
+    }
+
+    /**
+     * Tests adding a route. The egress interface has a VLAN configured.
+     *
+     * We verify that the synchronizer records the correct state and that the
+     * correct intent is submitted to the IntentService.
+     */
+    @Test
+    public void testRouteAddToVlan() {
+        // Build the expected route
+        ResolvedRoute route = new ResolvedRoute(PREFIX2, IP1, MAC1);
+
+        MultiPointToSinglePointIntent intent = createIntentToOne(PREFIX2);
+
+        // Setup the expected intents
+        intentSynchronizer.submit(eqExceptId(intent));
+        replay(intentSynchronizer);
+
+        // Send in the added event
+        routeListener.event(new RouteEvent(RouteEvent.Type.ROUTE_ADDED, route));
+
+        verify(intentSynchronizer);
+    }
+
+    /**
+     * Tests updating a route.
+     *
+     * We first add a route from a next-hop with no vlan. We then announce the
+     * same route from another next-hop with a vlan.
+     *
+     * We verify that the synchronizer records the correct state and that the
+     * correct intent is submitted to the IntentService.
+     */
+    @Test
+    public void testRouteUpdatesToVlan() {
+        // Add a route first to a destination with no VLAN
+        testRouteAddToNoVlan();
+
+        // Build the new route entries for prefix1 and prefix2
+        ResolvedRoute routePrefixOne = new ResolvedRoute(PREFIX1, IP1, MAC1);
+
+        // Create the new expected intents
+        MultiPointToSinglePointIntent newPrefixOneIntent = createIntentToOne(PREFIX1);
+
+        // Set up test expectation
+        reset(intentSynchronizer);
+
+        // Setup the expected intents
+        intentSynchronizer.submit(eqExceptId(newPrefixOneIntent));
+        replay(intentSynchronizer);
+
+        // Send in the update events
+        routeListener.event(new RouteEvent(RouteEvent.Type.ROUTE_UPDATED,
+                                           routePrefixOne));
+
+        verify(intentSynchronizer);
+    }
+
+    /**
+     * Tests updating a route.
+     *
+     * We first add a route from a next-hop with a vlan. We then announce the
+     * same route from another next-hop with no vlan.
+     *
+     * We verify that the synchronizer records the correct state and that the
+     * correct intent is submitted to the IntentService.
+     */
+    @Test
+    public void testRouteUpdatesToNoVlan() {
+        // Add a route first to a destination with no VLAN
+        testRouteAddToVlan();
+
+        // Build the new route entries for prefix1 and prefix2
+        ResolvedRoute routePrefix = new ResolvedRoute(PREFIX2, IP3, MAC3);
+
+        // Create the new expected intents
+        MultiPointToSinglePointIntent newPrefixIntent =
+                createIntentToThreeSrcOneTwo(PREFIX2);
+
+        // Set up test expectation
+        reset(intentSynchronizer);
+
+        // Setup the expected intents
+        intentSynchronizer.submit(eqExceptId(newPrefixIntent));
+        replay(intentSynchronizer);
+
+        // Send in the update events
+        routeListener.event(new RouteEvent(RouteEvent.Type.ROUTE_UPDATED,
+                                           routePrefix));
+
+        verify(intentSynchronizer);
+    }
+
+    /**
+     * Tests deleting a route.
+     *
+     * We verify that the synchronizer records the correct state and that the
+     * correct intent is withdrawn from the IntentService.
+     */
+    @Test
+    public void testRouteDelete() {
+        // Add a route first
+        testRouteAddToNoVlan();
+
+        // Construct the existing route entry
+        ResolvedRoute route = new ResolvedRoute(PREFIX1, null, null);
+
+        // Create existing intent
+        MultiPointToSinglePointIntent removedIntent =
+                createIntentToThreeSrcOneTwo(PREFIX1);
+
+        // Set up expectation
+        reset(intentSynchronizer);
+        // Setup the expected intents
+        intentSynchronizer.withdraw(eqExceptId(removedIntent));
+        replay(intentSynchronizer);
+
+        // Send in the removed event
+        routeListener.event(new RouteEvent(RouteEvent.Type.ROUTE_REMOVED, route));
+
+        verify(intentSynchronizer);
+    }
+
+    /**
+     * Tests adding a new interface.
+     *
+     * We verify that the synchronizer records the correct state and that the
+     * correct intent is withdrawn from the IntentService.
+     */
+    @Test
+    public void testAddInterface() {
+        // Add a route first
+        testRouteAddToNoVlan();
+
+        // Create the new expected intent
+        MultiPointToSinglePointIntent addedIntent =
+                createIntentToThreeSrcOneTwoFour(PREFIX1);
+
+        reset(intentSynchronizer);
+
+        intentSynchronizer.submit(eqExceptId(addedIntent));
+        expectLastCall().once();
+
+        replay(intentSynchronizer);
+
+        // Create the new interface and add notify it
+        Interface intf = new Interface("sw4-eth1", SW4_ETH1,
+                                       Collections.singletonList(IIP4),
+                                       MAC4, NO_VLAN);
+        InterfaceEvent intfEvent =
+                new InterfaceEvent(InterfaceEvent.Type.INTERFACE_ADDED, intf);
+
+        interfaceListener.event(intfEvent);
+
+        verify(intentSynchronizer);
+    }
+
+    /**
+     * Tests removing an existing interface.
+     *
+     * We first push an intent with destination sw3 and source sw1 and sw2. We
+     * then remove the ingress interface on sw1.
+     *
+     * We verify that the synchronizer records the correct state and that the
+     * correct intent is withdrawn from the IntentService.
+     */
+    @Test
+    public void testRemoveIngressInterface() {
+        // Add a route first
+        testRouteAddToNoVlan();
+
+        // Create the new expected intent
+        MultiPointToSinglePointIntent remainingIntent =
+                createIntentToThreeSrcTwo(PREFIX1);
+
+        reset(intentSynchronizer);
+
+        intentSynchronizer.submit(eqExceptId(remainingIntent));
+        expectLastCall().once();
+
+        replay(intentSynchronizer);
+
+        // Define the existing ingress interface and remove it
+        Interface intf = new Interface("sw1-eth1", SW1_ETH1,
+                                       Collections.singletonList(IIP1),
+                                       MAC1, VLAN10);
+        InterfaceEvent intfEvent =
+                new InterfaceEvent(InterfaceEvent.Type.INTERFACE_REMOVED, intf);
+        interfaceListener.event(intfEvent);
+
+        verify(intentSynchronizer);
+    }
+
+    /**
+     * Tests removing an existing egress interface.
+     *
+     * We first push an intent with destination sw3 and source sw1 and sw2. We
+     * then remove the egress interface on sw3.
+     *
+     * We verify that the synchronizer records the correct state and that the
+     * correct intent is withdrawn from the IntentService.
+     */
+    @Test
+    public void testRemoveEgressInterface() {
+        // Add a route first
+        testRouteAddToNoVlan();
+
+        // Create existing intent
+        MultiPointToSinglePointIntent removedIntent =
+                createIntentToThreeSrcOneTwo(PREFIX1);
+
+        // Set up expectation
+        reset(intentSynchronizer);
+        // Setup the expected intents
+        intentSynchronizer.withdraw(eqExceptId(removedIntent));
+        replay(intentSynchronizer);
+
+        // Define the existing egress interface and remove it
+        Interface intf = new Interface("sw3-eth1", SW3_ETH1,
+                                       Collections.singletonList(IIP3),
+                                       MAC3, VlanId.NONE);
+        InterfaceEvent intfEvent =
+                new InterfaceEvent(InterfaceEvent.Type.INTERFACE_REMOVED, intf);
+        interfaceListener.event(intfEvent);
+
+        verify(intentSynchronizer);
+    }
+
+    /*
+     * Builds a MultiPointToSinglePointIntent with dest sw1 (VLAN Id) and src
+     * sw2, sw3.
+     */
+    private MultiPointToSinglePointIntent createIntentToOne(IpPrefix ipPrefix) {
+        // Build the expected treatment
+        TrafficTreatment.Builder treatmentBuilder =
+                DefaultTrafficTreatment.builder();
+        treatmentBuilder.setEthDst(MAC1);
+
+        // Build the expected egress FilteredConnectPoint
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        selector.matchVlanId(VLAN10);
+        FilteredConnectPoint egressFilteredCP =
+                new FilteredConnectPoint(SW1_ETH1, selector.build());
+
+        // Build the expected selectors
+        Set<FilteredConnectPoint> ingressFilteredCPs = Sets.newHashSet();
+
+        // Build the expected ingress FilteredConnectPoint for sw2
+        selector = DefaultTrafficSelector.builder();
+        selector.matchVlanId(VLAN20);
+        selector.matchEthType(Ethernet.TYPE_IPV4);
+        selector.matchIPDst(ipPrefix);
+        FilteredConnectPoint ingressFilteredCP =
+                new FilteredConnectPoint(SW2_ETH1, selector.build());
+        ingressFilteredCPs.add(ingressFilteredCP);
+
+        // Build the expected ingress FilteredConnectPoint for sw3
+        selector = DefaultTrafficSelector.builder();
+        selector.matchEthType(Ethernet.TYPE_IPV4);
+        selector.matchIPDst(ipPrefix);
+        ingressFilteredCP = new FilteredConnectPoint(SW3_ETH1, selector.build());
+        ingressFilteredCPs.add(ingressFilteredCP);
+
+        // Build the expected intent
+        MultiPointToSinglePointIntent intent =
+                MultiPointToSinglePointIntent.builder()
+                        .appId(APPID)
+                        .key(Key.of(ipPrefix.toString(), APPID))
+                        .filteredIngressPoints(ingressFilteredCPs)
+                        .filteredEgressPoint(egressFilteredCP)
+                        .treatment(treatmentBuilder.build())
+                        .constraints(SdnIpFib.CONSTRAINTS)
+                        .build();
+
+        return intent;
+    }
+
+    /*
+     * Builds a MultiPointToSinglePointIntent with dest sw3 (no VLAN Id) and src
+     * sw1, sw2.
+     */
+    private MultiPointToSinglePointIntent createIntentToThreeSrcOneTwo(IpPrefix ipPrefix) {
+        // Build the expected treatment
+        TrafficTreatment.Builder treatmentBuilder =
+                DefaultTrafficTreatment.builder();
+        treatmentBuilder.setEthDst(MAC3);
+
+        // Build the expected egress FilteredConnectPoint
+        FilteredConnectPoint egressFilteredCP = new FilteredConnectPoint(SW3_ETH1);
+
+        // Build the expected selectors
+        Set<FilteredConnectPoint> ingressFilteredCPs = Sets.newHashSet();
+
+        // Build the expected ingress FilteredConnectPoint for sw1
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        selector.matchVlanId(VLAN10);
+        selector.matchEthType(Ethernet.TYPE_IPV4);
+        selector.matchIPDst(ipPrefix);
+        FilteredConnectPoint ingressFilteredCP =
+                new FilteredConnectPoint(SW1_ETH1, selector.build());
+        ingressFilteredCPs.add(ingressFilteredCP);
+
+        // Build the expected ingress FilteredConnectPoint for sw2
+        selector = DefaultTrafficSelector.builder();
+        selector.matchVlanId(VLAN20);
+        selector.matchEthType(Ethernet.TYPE_IPV4);
+        selector.matchIPDst(ipPrefix);
+        ingressFilteredCP = new FilteredConnectPoint(SW2_ETH1, selector.build());
+        ingressFilteredCPs.add(ingressFilteredCP);
+
+        // Build the expected intent
+        MultiPointToSinglePointIntent intent =
+                MultiPointToSinglePointIntent.builder()
+                        .appId(APPID)
+                        .key(Key.of(ipPrefix.toString(), APPID))
+                        .filteredIngressPoints(ingressFilteredCPs)
+                        .filteredEgressPoint(egressFilteredCP)
+                        .treatment(treatmentBuilder.build())
+                        .constraints(SdnIpFib.CONSTRAINTS)
+                        .build();
+
+        return intent;
+    }
+
+    /*
+     * Builds a MultiPointToSinglePointIntent with dest sw3 (no VLAN Id) and src
+     * sw2.
+     */
+    private MultiPointToSinglePointIntent createIntentToThreeSrcTwo(IpPrefix ipPrefix) {
+        // Build the expected treatment
+        TrafficTreatment.Builder treatmentBuilder =
+                DefaultTrafficTreatment.builder();
+        treatmentBuilder.setEthDst(MAC3);
+
+        // Build the expected egress FilteredConnectPoint
+        FilteredConnectPoint egressFilteredCP = new FilteredConnectPoint(SW3_ETH1);
+
+        // Build the expected ingress FilteredConnectPoint for sw2
+        Set<FilteredConnectPoint> ingressFilteredCPs = Sets.newHashSet();
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        selector.matchVlanId(VLAN20);
+        selector.matchEthType(Ethernet.TYPE_IPV4);
+        selector.matchIPDst(ipPrefix);
+        FilteredConnectPoint ingressFilteredCP =
+                new FilteredConnectPoint(SW2_ETH1, selector.build());
+        ingressFilteredCPs.add(ingressFilteredCP);
+
+        // Build the expected intent
+        MultiPointToSinglePointIntent intent =
+                MultiPointToSinglePointIntent.builder()
+                        .appId(APPID)
+                        .key(Key.of(ipPrefix.toString(), APPID))
+                        .filteredIngressPoints(ingressFilteredCPs)
+                        .filteredEgressPoint(egressFilteredCP)
+                        .treatment(treatmentBuilder.build())
+                        .constraints(SdnIpFib.CONSTRAINTS)
+                        .build();
+
+        return intent;
+    }
+
+    /*
+     * Builds a MultiPointToSinglePointIntent with dest sw3 (no VLAN Id) and src
+     * sw1, sw2, sw4.
+     */
+    private MultiPointToSinglePointIntent createIntentToThreeSrcOneTwoFour(IpPrefix ipPrefix) {
+        // Build the expected treatment
+        TrafficTreatment.Builder treatmentBuilder =
+                DefaultTrafficTreatment.builder();
+        treatmentBuilder.setEthDst(MAC3);
+
+        // Build the expected egress FilteredConnectPoint
+        FilteredConnectPoint egressFilteredCP = new FilteredConnectPoint(SW3_ETH1);
+
+        // Build the expected selectors
+        Set<FilteredConnectPoint> ingressFilteredCPs = Sets.newHashSet();
+
+        // Build the expected ingress FilteredConnectPoint for sw1
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        selector.matchVlanId(VLAN10);
+        selector.matchEthType(Ethernet.TYPE_IPV4);
+        selector.matchIPDst(ipPrefix);
+        FilteredConnectPoint ingressFilteredCP =
+                new FilteredConnectPoint(SW1_ETH1, selector.build());
+        ingressFilteredCPs.add(ingressFilteredCP);
+
+        // Build the expected ingress FilteredConnectPoint for sw2
+        selector = DefaultTrafficSelector.builder();
+        selector.matchVlanId(VLAN20);
+        selector.matchEthType(Ethernet.TYPE_IPV4);
+        selector.matchIPDst(ipPrefix);
+        ingressFilteredCP = new FilteredConnectPoint(SW2_ETH1, selector.build());
+        ingressFilteredCPs.add(ingressFilteredCP);
+
+        // Build the expected ingress FilteredConnectPoint for sw4
+        selector = DefaultTrafficSelector.builder();
+        selector.matchEthType(Ethernet.TYPE_IPV4);
+        selector.matchIPDst(ipPrefix);
+        ingressFilteredCP = new FilteredConnectPoint(SW4_ETH1, selector.build());
+        ingressFilteredCPs.add(ingressFilteredCP);
+
+        // Build the expected intent
+        MultiPointToSinglePointIntent intent =
+                MultiPointToSinglePointIntent.builder()
+                        .appId(APPID)
+                        .key(Key.of(ipPrefix.toString(), APPID))
+                        .filteredIngressPoints(ingressFilteredCPs)
+                        .filteredEgressPoint(egressFilteredCP)
+                        .treatment(treatmentBuilder.build())
+                        .constraints(SdnIpFib.CONSTRAINTS)
+                        .build();
+
+        return intent;
+    }
+
+    private class TestCoreService extends CoreServiceAdapter {
+        @Override
+        public ApplicationId getAppId(String name) {
+            return APPID;
+        }
+    }
+
+    private class TestRouteService extends RouteServiceAdapter {
+        @Override
+        public void addListener(RouteListener routeListener) {
+            SdnIpFibTest.this.routeListener = routeListener;
+        }
+    }
+
+    private class InterfaceServiceDelegate extends InterfaceServiceAdapter {
+        @Override
+        public void addListener(InterfaceListener listener) {
+            SdnIpFibTest.this.interfaceListener = listener;
+        }
+    }
+}
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibVlansToVlanDifferentTest.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibVlansToVlanDifferentTest.java
deleted file mode 100644
index 62d4183..0000000
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibVlansToVlanDifferentTest.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * 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.sdnip;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import org.junit.Before;
-import org.junit.Test;
-import org.onlab.packet.Ethernet;
-import org.onlab.packet.Ip4Address;
-import org.onlab.packet.Ip4Prefix;
-import org.onlab.packet.IpPrefix;
-import org.onlab.packet.MacAddress;
-import org.onlab.packet.VlanId;
-import org.onosproject.TestApplicationId;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.core.CoreServiceAdapter;
-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.intf.InterfaceServiceAdapter;
-import org.onosproject.incubator.net.routing.ResolvedRoute;
-import org.onosproject.incubator.net.routing.RouteEvent;
-import org.onosproject.incubator.net.routing.RouteListener;
-import org.onosproject.incubator.net.routing.RouteServiceAdapter;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.host.InterfaceIpAddress;
-import org.onosproject.net.intent.AbstractIntentTest;
-import org.onosproject.net.intent.Key;
-import org.onosproject.net.intent.MultiPointToSinglePointIntent;
-import org.onosproject.routing.IntentSynchronizationService;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import static org.easymock.EasyMock.*;
-import static org.onosproject.routing.TestIntentServiceHelper.eqExceptId;
-
-/**
- * Unit tests for SdnIpFib.
- */
-public class SdnIpFibVlansToVlanDifferentTest extends AbstractIntentTest {
-
-    private InterfaceService interfaceService;
-
-    private static final ConnectPoint SW1_ETH1 = new ConnectPoint(
-            DeviceId.deviceId("of:0000000000000001"),
-            PortNumber.portNumber(1));
-
-    private static final ConnectPoint SW2_ETH1 = new ConnectPoint(
-            DeviceId.deviceId("of:0000000000000002"),
-            PortNumber.portNumber(1));
-
-    private static final ConnectPoint SW3_ETH1 = new ConnectPoint(
-            DeviceId.deviceId("of:0000000000000003"),
-            PortNumber.portNumber(1));
-
-    private static final IpPrefix PREFIX1 = Ip4Prefix.valueOf("1.1.1.0/24");
-
-    private SdnIpFib sdnipFib;
-    private IntentSynchronizationService intentSynchronizer;
-    private final Set<Interface> interfaces = Sets.newHashSet();
-
-    private static final ApplicationId APPID = TestApplicationId.create("SDNIP");
-
-    private RouteListener routeListener;
-    private InterfaceListener interfaceListener;
-
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-
-        interfaceService = createMock(InterfaceService.class);
-
-        interfaceService.addListener(anyObject(InterfaceListener.class));
-        expectLastCall().andDelegateTo(new InterfaceServiceDelegate());
-
-        // These will set expectations on routingConfig and interfaceService
-        setUpInterfaceService();
-
-        replay(interfaceService);
-
-        intentSynchronizer = createMock(IntentSynchronizationService.class);
-
-        sdnipFib = new SdnIpFib();
-        sdnipFib.routeService = new TestRouteService();
-        sdnipFib.coreService = new TestCoreService();
-        sdnipFib.interfaceService = interfaceService;
-        sdnipFib.intentSynchronizer = intentSynchronizer;
-
-        sdnipFib.activate();
-    }
-
-    /**
-     * Sets up the interface service.
-     */
-    private void setUpInterfaceService() {
-        List<InterfaceIpAddress> interfaceIpAddresses1 = Lists.newArrayList();
-        interfaceIpAddresses1.add(InterfaceIpAddress.valueOf("192.168.10.101/24"));
-        Interface sw1Eth1 = new Interface("sw1-eth1", SW1_ETH1,
-                                          interfaceIpAddresses1, MacAddress.valueOf("00:00:00:00:00:01"),
-                                          VlanId.vlanId((short) 1));
-        interfaces.add(sw1Eth1);
-
-        List<InterfaceIpAddress> interfaceIpAddresses2 = Lists.newArrayList();
-        interfaceIpAddresses2.add(InterfaceIpAddress.valueOf("192.168.20.101/24"));
-        Interface sw2Eth1 = new Interface("sw2-eth1", SW2_ETH1,
-                                          interfaceIpAddresses2, MacAddress.valueOf("00:00:00:00:00:02"),
-                                          VlanId.vlanId((short) 1));
-        interfaces.add(sw2Eth1);
-
-        InterfaceIpAddress interfaceIpAddress3 = InterfaceIpAddress.valueOf("192.168.30.101/24");
-        Interface sw3Eth1 = new Interface("sw3-eth1", SW3_ETH1,
-                                          Lists.newArrayList(interfaceIpAddress3),
-                                          MacAddress.valueOf("00:00:00:00:00:03"),
-                                          VlanId.vlanId((short) 2));
-        interfaces.add(sw3Eth1);
-
-        expect(interfaceService.getInterfacesByPort(SW1_ETH1)).andReturn(
-                Collections.singleton(sw1Eth1)).anyTimes();
-        expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.10.1")))
-                .andReturn(sw1Eth1).anyTimes();
-        expect(interfaceService.getInterfacesByPort(SW2_ETH1)).andReturn(
-                Collections.singleton(sw2Eth1)).anyTimes();
-        expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.20.1")))
-                .andReturn(sw2Eth1).anyTimes();
-        expect(interfaceService.getInterfacesByPort(SW3_ETH1)).andReturn(
-                Collections.singleton(sw3Eth1)).anyTimes();
-        expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.30.1")))
-                .andReturn(sw3Eth1).anyTimes();
-        expect(interfaceService.getInterfaces()).andReturn(interfaces).anyTimes();
-    }
-
-    /**
-     * Tests adding a route. Ingresses with VLAN and next hop with no VLAN.
-     *
-     * We verify that the synchronizer records the correct state and that the
-     * correct intent is submitted to the IntentService.
-     */
-    @Test
-    public void testRouteAdd() {
-        ResolvedRoute route = new ResolvedRoute(PREFIX1,
-                Ip4Address.valueOf("192.168.30.1"),
-                MacAddress.valueOf("00:00:00:00:00:03"));
-
-        // Construct a MultiPointToSinglePointIntent intent
-        TrafficSelector.Builder selectorBuilder =
-                DefaultTrafficSelector.builder();
-        selectorBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(PREFIX1)
-                .matchVlanId(VlanId.ANY);
-
-        TrafficTreatment.Builder treatmentBuilder =
-                DefaultTrafficTreatment.builder();
-        treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:03"))
-                .setVlanId(VlanId.vlanId((short) 2));
-
-        Set<ConnectPoint> ingressPoints = new HashSet<>();
-        ingressPoints.add(SW1_ETH1);
-        ingressPoints.add(SW2_ETH1);
-
-        MultiPointToSinglePointIntent intent =
-                MultiPointToSinglePointIntent.builder()
-                        .appId(APPID)
-                        .key(Key.of(PREFIX1.toString(), APPID))
-                        .selector(selectorBuilder.build())
-                        .treatment(treatmentBuilder.build())
-                        .ingressPoints(ingressPoints)
-                        .egressPoint(SW3_ETH1)
-                        .constraints(SdnIpFib.CONSTRAINTS)
-                        .build();
-
-        // Setup the expected intents
-        intentSynchronizer.submit(eqExceptId(intent));
-        replay(intentSynchronizer);
-
-        // Send in the added event
-        routeListener.event(new RouteEvent(RouteEvent.Type.ROUTE_ADDED, route));
-
-        verify(intentSynchronizer);
-    }
-
-    private class TestCoreService extends CoreServiceAdapter {
-        @Override
-        public ApplicationId getAppId(String name) {
-            return APPID;
-        }
-    }
-
-    private class TestRouteService extends RouteServiceAdapter {
-        @Override
-        public void addListener(RouteListener routeListener) {
-            SdnIpFibVlansToVlanDifferentTest.this.routeListener = routeListener;
-        }
-    }
-
-    private class InterfaceServiceDelegate extends InterfaceServiceAdapter {
-        @Override
-        public void addListener(InterfaceListener listener) {
-            SdnIpFibVlansToVlanDifferentTest.this.interfaceListener = listener;
-        }
-    }
-}
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibVlansToVlanSameTest.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibVlansToVlanSameTest.java
deleted file mode 100644
index e60e355..0000000
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibVlansToVlanSameTest.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * 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.sdnip;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import org.junit.Before;
-import org.junit.Test;
-import org.onlab.packet.Ethernet;
-import org.onlab.packet.Ip4Address;
-import org.onlab.packet.Ip4Prefix;
-import org.onlab.packet.IpPrefix;
-import org.onlab.packet.MacAddress;
-import org.onlab.packet.VlanId;
-import org.onosproject.TestApplicationId;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.core.CoreServiceAdapter;
-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.intf.InterfaceServiceAdapter;
-import org.onosproject.incubator.net.routing.ResolvedRoute;
-import org.onosproject.incubator.net.routing.RouteEvent;
-import org.onosproject.incubator.net.routing.RouteListener;
-import org.onosproject.incubator.net.routing.RouteServiceAdapter;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.host.InterfaceIpAddress;
-import org.onosproject.net.intent.AbstractIntentTest;
-import org.onosproject.net.intent.Key;
-import org.onosproject.net.intent.MultiPointToSinglePointIntent;
-import org.onosproject.routing.IntentSynchronizationService;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import static org.easymock.EasyMock.*;
-import static org.onosproject.routing.TestIntentServiceHelper.eqExceptId;
-
-/**
- * Unit tests for SdnIpFib.
- */
-public class SdnIpFibVlansToVlanSameTest extends AbstractIntentTest {
-
-    private InterfaceService interfaceService;
-
-    private static final ConnectPoint SW1_ETH1 = new ConnectPoint(
-            DeviceId.deviceId("of:0000000000000001"),
-            PortNumber.portNumber(1));
-
-    private static final ConnectPoint SW2_ETH1 = new ConnectPoint(
-            DeviceId.deviceId("of:0000000000000002"),
-            PortNumber.portNumber(1));
-
-    private static final ConnectPoint SW3_ETH1 = new ConnectPoint(
-            DeviceId.deviceId("of:0000000000000003"),
-            PortNumber.portNumber(1));
-
-    private static final IpPrefix PREFIX1 = Ip4Prefix.valueOf("1.1.1.0/24");
-
-    private SdnIpFib sdnipFib;
-    private IntentSynchronizationService intentSynchronizer;
-    private final Set<Interface> interfaces = Sets.newHashSet();
-
-    private static final ApplicationId APPID = TestApplicationId.create("SDNIP");
-
-    private RouteListener routeListener;
-    private InterfaceListener interfaceListener;
-
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-
-        interfaceService = createMock(InterfaceService.class);
-
-        interfaceService.addListener(anyObject(InterfaceListener.class));
-        expectLastCall().andDelegateTo(new InterfaceServiceDelegate());
-
-        // These will set expectations on routingConfig and interfaceService
-        setUpInterfaceService();
-
-        replay(interfaceService);
-
-        intentSynchronizer = createMock(IntentSynchronizationService.class);
-
-        sdnipFib = new SdnIpFib();
-        sdnipFib.routeService = new TestRouteService();
-        sdnipFib.coreService = new TestCoreService();
-        sdnipFib.interfaceService = interfaceService;
-        sdnipFib.intentSynchronizer = intentSynchronizer;
-
-        sdnipFib.activate();
-    }
-
-    /**
-     * Sets up the interface service.
-     */
-    private void setUpInterfaceService() {
-        List<InterfaceIpAddress> interfaceIpAddresses1 = Lists.newArrayList();
-        interfaceIpAddresses1.add(InterfaceIpAddress.valueOf("192.168.10.101/24"));
-        Interface sw1Eth1 = new Interface("sw1-eth1", SW1_ETH1,
-                                          interfaceIpAddresses1, MacAddress.valueOf("00:00:00:00:00:01"),
-                                          VlanId.vlanId((short) 1));
-        interfaces.add(sw1Eth1);
-
-        List<InterfaceIpAddress> interfaceIpAddresses2 = Lists.newArrayList();
-        interfaceIpAddresses2.add(InterfaceIpAddress.valueOf("192.168.20.101/24"));
-        Interface sw2Eth1 = new Interface("sw2-eth1", SW2_ETH1,
-                                          interfaceIpAddresses2, MacAddress.valueOf("00:00:00:00:00:02"),
-                                          VlanId.vlanId((short) 1));
-        interfaces.add(sw2Eth1);
-
-        InterfaceIpAddress interfaceIpAddress3 = InterfaceIpAddress.valueOf("192.168.30.101/24");
-        Interface sw3Eth1 = new Interface("sw3-eth1", SW3_ETH1,
-                                          Lists.newArrayList(interfaceIpAddress3),
-                                          MacAddress.valueOf("00:00:00:00:00:03"),
-                                          VlanId.vlanId((short) 1));
-        interfaces.add(sw3Eth1);
-
-        expect(interfaceService.getInterfacesByPort(SW1_ETH1)).andReturn(
-                Collections.singleton(sw1Eth1)).anyTimes();
-        expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.10.1")))
-                .andReturn(sw1Eth1).anyTimes();
-        expect(interfaceService.getInterfacesByPort(SW2_ETH1)).andReturn(
-                Collections.singleton(sw2Eth1)).anyTimes();
-        expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.20.1")))
-                .andReturn(sw2Eth1).anyTimes();
-        expect(interfaceService.getInterfacesByPort(SW3_ETH1)).andReturn(
-                Collections.singleton(sw3Eth1)).anyTimes();
-        expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.30.1")))
-                .andReturn(sw3Eth1).anyTimes();
-        expect(interfaceService.getInterfaces()).andReturn(interfaces).anyTimes();
-    }
-
-    /**
-     * Tests adding a route. Ingresses with VLAN and next hop with no VLAN.
-     *
-     * We verify that the synchronizer records the correct state and that the
-     * correct intent is submitted to the IntentService.
-     */
-    @Test
-    public void testRouteAdd() {
-        ResolvedRoute route = new ResolvedRoute(PREFIX1,
-                Ip4Address.valueOf("192.168.30.1"),
-                MacAddress.valueOf("00:00:00:00:00:03"));
-
-        // Construct a MultiPointToSinglePointIntent intent
-        TrafficSelector.Builder selectorBuilder =
-                DefaultTrafficSelector.builder();
-        selectorBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(PREFIX1)
-                .matchVlanId(VlanId.ANY);
-
-        TrafficTreatment.Builder treatmentBuilder =
-                DefaultTrafficTreatment.builder();
-        treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:03"));
-
-        Set<ConnectPoint> ingressPoints = new HashSet<>();
-        ingressPoints.add(SW1_ETH1);
-        ingressPoints.add(SW2_ETH1);
-
-        MultiPointToSinglePointIntent intent =
-                MultiPointToSinglePointIntent.builder()
-                        .appId(APPID)
-                        .key(Key.of(PREFIX1.toString(), APPID))
-                        .selector(selectorBuilder.build())
-                        .treatment(treatmentBuilder.build())
-                        .ingressPoints(ingressPoints)
-                        .egressPoint(SW3_ETH1)
-                        .constraints(SdnIpFib.CONSTRAINTS)
-                        .build();
-
-        // Setup the expected intents
-        intentSynchronizer.submit(eqExceptId(intent));
-        replay(intentSynchronizer);
-
-        // Send in the added event
-        routeListener.event(new RouteEvent(RouteEvent.Type.ROUTE_ADDED, route));
-
-        verify(intentSynchronizer);
-    }
-
-    private class TestCoreService extends CoreServiceAdapter {
-        @Override
-        public ApplicationId getAppId(String name) {
-            return APPID;
-        }
-    }
-
-    private class TestRouteService extends RouteServiceAdapter {
-        @Override
-        public void addListener(RouteListener routeListener) {
-            SdnIpFibVlansToVlanSameTest.this.routeListener = routeListener;
-        }
-    }
-
-    private class InterfaceServiceDelegate extends InterfaceServiceAdapter {
-        @Override
-        public void addListener(InterfaceListener listener) {
-            SdnIpFibVlansToVlanSameTest.this.interfaceListener = listener;
-        }
-    }
-}
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibVlanstoNoVlanTest.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibVlanstoNoVlanTest.java
deleted file mode 100644
index 5198bc9..0000000
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibVlanstoNoVlanTest.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * 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.sdnip;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import org.junit.Before;
-import org.junit.Test;
-import org.onlab.packet.Ethernet;
-import org.onlab.packet.Ip4Address;
-import org.onlab.packet.Ip4Prefix;
-import org.onlab.packet.IpPrefix;
-import org.onlab.packet.MacAddress;
-import org.onlab.packet.VlanId;
-import org.onosproject.TestApplicationId;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.core.CoreServiceAdapter;
-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.intf.InterfaceServiceAdapter;
-import org.onosproject.incubator.net.routing.ResolvedRoute;
-import org.onosproject.incubator.net.routing.RouteEvent;
-import org.onosproject.incubator.net.routing.RouteListener;
-import org.onosproject.incubator.net.routing.RouteServiceAdapter;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.host.InterfaceIpAddress;
-import org.onosproject.net.intent.AbstractIntentTest;
-import org.onosproject.net.intent.Key;
-import org.onosproject.net.intent.MultiPointToSinglePointIntent;
-import org.onosproject.routing.IntentSynchronizationService;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import static org.easymock.EasyMock.*;
-import static org.onosproject.routing.TestIntentServiceHelper.eqExceptId;
-
-/**
- * Unit tests for SdnIpFib.
- */
-public class SdnIpFibVlanstoNoVlanTest extends AbstractIntentTest {
-
-    private InterfaceService interfaceService;
-
-    private static final ConnectPoint SW1_ETH1 = new ConnectPoint(
-            DeviceId.deviceId("of:0000000000000001"),
-            PortNumber.portNumber(1));
-
-    private static final ConnectPoint SW2_ETH1 = new ConnectPoint(
-            DeviceId.deviceId("of:0000000000000002"),
-            PortNumber.portNumber(1));
-
-    private static final ConnectPoint SW3_ETH1 = new ConnectPoint(
-            DeviceId.deviceId("of:0000000000000003"),
-            PortNumber.portNumber(1));
-
-    private static final IpPrefix PREFIX1 = Ip4Prefix.valueOf("1.1.1.0/24");
-
-    private SdnIpFib sdnipFib;
-    private IntentSynchronizationService intentSynchronizer;
-    private final Set<Interface> interfaces = Sets.newHashSet();
-
-    private static final ApplicationId APPID = TestApplicationId.create("SDNIP");
-
-    private RouteListener routeListener;
-    private InterfaceListener interfaceListener;
-
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-
-        interfaceService = createMock(InterfaceService.class);
-
-        interfaceService.addListener(anyObject(InterfaceListener.class));
-        expectLastCall().andDelegateTo(new InterfaceServiceDelegate());
-
-        // These will set expectations on routingConfig and interfaceService
-        setUpInterfaceService();
-
-        replay(interfaceService);
-
-        intentSynchronizer = createMock(IntentSynchronizationService.class);
-
-        sdnipFib = new SdnIpFib();
-        sdnipFib.routeService = new TestRouteService();
-        sdnipFib.coreService = new TestCoreService();
-        sdnipFib.interfaceService = interfaceService;
-        sdnipFib.intentSynchronizer = intentSynchronizer;
-
-        sdnipFib.activate();
-    }
-
-    /**
-     * Sets up the interface service.
-     */
-    private void setUpInterfaceService() {
-        List<InterfaceIpAddress> interfaceIpAddresses1 = Lists.newArrayList();
-        interfaceIpAddresses1.add(InterfaceIpAddress.valueOf("192.168.10.101/24"));
-        Interface sw1Eth1 = new Interface("sw1-eth1", SW1_ETH1,
-                                          interfaceIpAddresses1, MacAddress.valueOf("00:00:00:00:00:01"),
-                                          VlanId.vlanId((short) 1));
-        interfaces.add(sw1Eth1);
-
-        List<InterfaceIpAddress> interfaceIpAddresses2 = Lists.newArrayList();
-        interfaceIpAddresses2.add(InterfaceIpAddress.valueOf("192.168.20.101/24"));
-        Interface sw2Eth1 = new Interface("sw2-eth1", SW2_ETH1,
-                                          interfaceIpAddresses2, MacAddress.valueOf("00:00:00:00:00:02"),
-                                          VlanId.vlanId((short) 1));
-        interfaces.add(sw2Eth1);
-
-        InterfaceIpAddress interfaceIpAddress3 = InterfaceIpAddress.valueOf("192.168.30.101/24");
-        Interface sw3Eth1 = new Interface("sw3-eth1", SW3_ETH1,
-                                          Lists.newArrayList(interfaceIpAddress3),
-                                          MacAddress.valueOf("00:00:00:00:00:03"),
-                                          VlanId.NONE);
-        interfaces.add(sw3Eth1);
-
-        expect(interfaceService.getInterfacesByPort(SW1_ETH1)).andReturn(
-                Collections.singleton(sw1Eth1)).anyTimes();
-        expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.10.1")))
-                .andReturn(sw1Eth1).anyTimes();
-        expect(interfaceService.getInterfacesByPort(SW2_ETH1)).andReturn(
-                Collections.singleton(sw2Eth1)).anyTimes();
-        expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.20.1")))
-                .andReturn(sw2Eth1).anyTimes();
-        expect(interfaceService.getInterfacesByPort(SW3_ETH1)).andReturn(
-                Collections.singleton(sw3Eth1)).anyTimes();
-        expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.30.1")))
-                .andReturn(sw3Eth1).anyTimes();
-        expect(interfaceService.getInterfaces()).andReturn(interfaces).anyTimes();
-    }
-
-    /**
-     * Tests adding a route. Ingresses with VLAN and next hop with no VLAN.
-     *
-     * We verify that the synchronizer records the correct state and that the
-     * correct intent is submitted to the IntentService.
-     */
-    @Test
-    public void testRouteAdd() {
-        ResolvedRoute route = new ResolvedRoute(PREFIX1,
-                Ip4Address.valueOf("192.168.30.1"),
-                MacAddress.valueOf("00:00:00:00:00:03"));
-
-        // Construct a MultiPointToSinglePointIntent intent
-        TrafficSelector.Builder selectorBuilder =
-                DefaultTrafficSelector.builder();
-        selectorBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(PREFIX1)
-                .matchVlanId(VlanId.ANY);
-
-        TrafficTreatment.Builder treatmentBuilder =
-                DefaultTrafficTreatment.builder();
-        treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:03"))
-                .popVlan();
-
-        Set<ConnectPoint> ingressPoints = new HashSet<>();
-        ingressPoints.add(SW1_ETH1);
-        ingressPoints.add(SW2_ETH1);
-
-        MultiPointToSinglePointIntent intent =
-                MultiPointToSinglePointIntent.builder()
-                        .appId(APPID)
-                        .key(Key.of(PREFIX1.toString(), APPID))
-                        .selector(selectorBuilder.build())
-                        .treatment(treatmentBuilder.build())
-                        .ingressPoints(ingressPoints)
-                        .egressPoint(SW3_ETH1)
-                        .constraints(SdnIpFib.CONSTRAINTS)
-                        .build();
-
-        // Setup the expected intents
-        intentSynchronizer.submit(eqExceptId(intent));
-        replay(intentSynchronizer);
-
-        // Send in the added event
-        routeListener.event(new RouteEvent(RouteEvent.Type.ROUTE_ADDED, route));
-
-        verify(intentSynchronizer);
-    }
-
-    private class TestCoreService extends CoreServiceAdapter {
-        @Override
-        public ApplicationId getAppId(String name) {
-            return APPID;
-        }
-    }
-
-    private class TestRouteService extends RouteServiceAdapter {
-        @Override
-        public void addListener(RouteListener routeListener) {
-            SdnIpFibVlanstoNoVlanTest.this.routeListener = routeListener;
-        }
-    }
-
-    private class InterfaceServiceDelegate extends InterfaceServiceAdapter {
-        @Override
-        public void addListener(InterfaceListener listener) {
-            SdnIpFibVlanstoNoVlanTest.this.interfaceListener = listener;
-        }
-    }
-}
