diff --git a/apps/segmentrouting/src/test/java/org/onosproject/segmentrouting/HostHandlerTest.java b/apps/segmentrouting/src/test/java/org/onosproject/segmentrouting/HostHandlerTest.java
index 314fef6..3ad2d52 100644
--- a/apps/segmentrouting/src/test/java/org/onosproject/segmentrouting/HostHandlerTest.java
+++ b/apps/segmentrouting/src/test/java/org/onosproject/segmentrouting/HostHandlerTest.java
@@ -18,7 +18,6 @@
 
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
@@ -28,10 +27,8 @@
 import org.onlab.packet.IpPrefix;
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.VlanId;
-import org.onosproject.core.DefaultApplicationId;
-import org.onosproject.mastership.MastershipServiceAdapter;
+import org.onosproject.net.config.ConfigApplyDelegate;
 import org.onosproject.net.intf.Interface;
-import org.onosproject.net.intf.InterfaceServiceAdapter;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DefaultHost;
 import org.onosproject.net.DeviceId;
@@ -39,47 +36,32 @@
 import org.onosproject.net.HostId;
 import org.onosproject.net.HostLocation;
 import org.onosproject.net.PortNumber;
-import org.onosproject.net.config.Config;
-import org.onosproject.net.config.ConfigApplyDelegate;
 import org.onosproject.net.config.NetworkConfigRegistryAdapter;
-import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.flow.criteria.Criterion;
-import org.onosproject.net.flow.criteria.EthCriterion;
-import org.onosproject.net.flow.criteria.VlanIdCriterion;
-import org.onosproject.net.flow.instructions.Instruction;
-import org.onosproject.net.flow.instructions.Instructions;
-import org.onosproject.net.flow.instructions.L2ModificationInstruction;
-import org.onosproject.net.flowobjective.FlowObjectiveServiceAdapter;
-import org.onosproject.net.flowobjective.ForwardingObjective;
-import org.onosproject.net.flowobjective.Objective;
 import org.onosproject.net.host.HostEvent;
-import org.onosproject.net.host.HostServiceAdapter;
 import org.onosproject.net.host.InterfaceIpAddress;
 import org.onosproject.net.provider.ProviderId;
 import org.onosproject.segmentrouting.config.DeviceConfiguration;
 import org.onosproject.segmentrouting.config.SegmentRoutingDeviceConfig;
 
 import java.util.Map;
-import java.util.Objects;
 import java.util.Set;
-import java.util.concurrent.atomic.AtomicInteger;
 
 import static org.junit.Assert.*;
 
-/**
+/**r
  * Unit test for {@link HostHandler}.
  */
 public class HostHandlerTest {
-    private SegmentRoutingManager srManager;
     private HostHandler hostHandler;
 
     // Mocked routing and bridging tables
-    private Map<BridingTableKey, BridingTableValue> bridgingTable = Maps.newConcurrentMap();
-    private Map<RoutingTableKey, RoutingTableValue> routingTable = Maps.newConcurrentMap();
+    private static final Map<MockBridgingTableKey, MockBridgingTableValue> BRIDGING_TABLE =
+            Maps.newConcurrentMap();
+    private static final Map<MockRoutingTableKey, MockRoutingTableValue> ROUTING_TABLE =
+            Maps.newConcurrentMap();
     // Mocked Next Id
-    private Map<Integer, TrafficTreatment> nextTable = Maps.newConcurrentMap();
-    private AtomicInteger atomicNextId = new AtomicInteger();
+    private static final Map<Integer, TrafficTreatment> NEXT_TABLE = Maps.newConcurrentMap();
 
     // Host Mac, VLAN
     private static final ProviderId PROVIDER_ID = ProviderId.NONE;
@@ -142,44 +124,99 @@
             new InterfaceIpAddress(INTF_PREFIX1.address(), INTF_PREFIX1);
     private static final InterfaceIpAddress INTF_IP2 =
             new InterfaceIpAddress(INTF_PREFIX2.address(), INTF_PREFIX2);
+    // Interfaces
+    private static final Interface INTF11 =
+            new Interface(null, CP11, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
+                    INTF_VLAN_UNTAGGED, null, null);
+    private static final Interface INTF12 =
+            new Interface(null, CP12, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
+                    INTF_VLAN_UNTAGGED, null, null);
+    private static final Interface INTF13 =
+            new Interface(null, CP13, Lists.newArrayList(INTF_IP2), MacAddress.NONE, null,
+                    null, INTF_VLAN_TAGGED, INTF_VLAN_NATIVE);
+    private static final Interface INTF21 =
+            new Interface(null, CP21, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
+                    INTF_VLAN_UNTAGGED, null, null);
+    private static final Interface INTF22 =
+            new Interface(null, CP22, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
+                    INTF_VLAN_UNTAGGED, null, null);
+    private static final Interface INTF31 =
+            new Interface(null, CP31, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
+                    INTF_VLAN_UNTAGGED, null, null);
+    private static final Interface INTF39 =
+            new Interface(null, CP39, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
+                    null, INTF_VLAN_PAIR, null);
+    private static final Interface INTF41 =
+            new Interface(null, CP41, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
+                    INTF_VLAN_UNTAGGED, null, null);
+    private static final Interface INTF49 =
+            new Interface(null, CP49, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
+                    null, INTF_VLAN_PAIR, null);
     // Host
     private static final Host HOST1 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC,
             HOST_VLAN_UNTAGGED, Sets.newHashSet(HOST_LOC11, HOST_LOC21), Sets.newHashSet(HOST_IP11),
             false);
 
+    // A set of hosts
+    private static final Set<Host> HOSTS = Sets.newHashSet(HOST1);
+    // A set of devices of which we have mastership
+    private static final Set<DeviceId> LOCAL_DEVICES = Sets.newHashSet(DEV1, DEV2, DEV3, DEV4);
+    // A set of interfaces
+    private static final Set<Interface> INTERFACES = Sets.newHashSet(INTF11, INTF12, INTF13, INTF21,
+            INTF22, INTF31, INTF39, INTF41, INTF49);
+
     @Before
     public void setUp() throws Exception {
-        srManager = new MockSegmentRoutingManager();
+        // Initialize pairDevice and pairLocalPort config
+        ObjectMapper mapper = new ObjectMapper();
+        ConfigApplyDelegate delegate = config -> { };
+
+        SegmentRoutingDeviceConfig dev3Config = new SegmentRoutingDeviceConfig();
+        JsonNode dev3Tree = mapper.createObjectNode();
+        dev3Config.init(DEV3, "host-handler-test", dev3Tree, mapper, delegate);
+        dev3Config.setPairDeviceId(DEV4).setPairLocalPort(P9);
+
+        SegmentRoutingDeviceConfig dev4Config = new SegmentRoutingDeviceConfig();
+        JsonNode dev4Tree = mapper.createObjectNode();
+        dev4Config.init(DEV4, "host-handler-test", dev4Tree, mapper, delegate);
+        dev4Config.setPairDeviceId(DEV3).setPairLocalPort(P9);
+
+        MockNetworkConfigRegistry mockNetworkConfigRegistry = new MockNetworkConfigRegistry();
+        mockNetworkConfigRegistry.applyConfig(dev3Config);
+        mockNetworkConfigRegistry.applyConfig(dev4Config);
+
+        // Initialize Segment Routing Manager
+        SegmentRoutingManager srManager = new MockSegmentRoutingManager(NEXT_TABLE);
         srManager.cfgService = new NetworkConfigRegistryAdapter();
         srManager.deviceConfiguration = new DeviceConfiguration(srManager);
-        srManager.flowObjectiveService = new MockFlowObjectiveService();
-        srManager.routingRulePopulator = new MockRoutingRulePopulator();
-        srManager.interfaceService = new MockInterfaceService();
-        srManager.mastershipService = new MockMastershipService();
-        srManager.hostService = new MockHostService();
-        srManager.cfgService = new MockNetworkConfigRegistry();
+        srManager.flowObjectiveService = new MockFlowObjectiveService(BRIDGING_TABLE, NEXT_TABLE);
+        srManager.routingRulePopulator = new MockRoutingRulePopulator(srManager, ROUTING_TABLE);
+        srManager.interfaceService = new MockInterfaceService(INTERFACES);
+        srManager.mastershipService = new MockMastershipService(LOCAL_DEVICES);
+        srManager.hostService = new MockHostService(HOSTS);
+        srManager.cfgService = mockNetworkConfigRegistry;
 
         hostHandler = new HostHandler(srManager);
 
-        routingTable.clear();
-        bridgingTable.clear();
+        ROUTING_TABLE.clear();
+        BRIDGING_TABLE.clear();
     }
 
     @Test
     public void init() throws Exception {
         hostHandler.init(DEV1);
-        assertEquals(1, routingTable.size());
-        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
-        assertEquals(1, bridgingTable.size());
-        assertNotNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertEquals(1, ROUTING_TABLE.size());
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertEquals(1, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
 
         hostHandler.init(DEV2);
-        assertEquals(2, routingTable.size());
-        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
-        assertNotNull(routingTable.get(new RoutingTableKey(DEV2, HOST_IP11.toIpPrefix())));
-        assertEquals(2, bridgingTable.size());
-        assertNotNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
-        assertNotNull(bridgingTable.get(new BridingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertEquals(2, ROUTING_TABLE.size());
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP11.toIpPrefix())));
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
     }
 
     @Test(expected = IllegalArgumentException.class)
@@ -191,10 +228,10 @@
     @Test()
     public void testHostAddedAtCorrectLocation() throws Exception {
         hostHandler.processHostAddedAtLocation(HOST1, HOST_LOC11);
-        assertEquals(1, routingTable.size());
-        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
-        assertEquals(1, bridgingTable.size());
-        assertNotNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertEquals(1, ROUTING_TABLE.size());
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertEquals(1, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
     }
 
     @Test
@@ -206,40 +243,40 @@
         subject = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
                 Sets.newHashSet(HOST_LOC11), Sets.newHashSet(HOST_IP11), false);
         hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, subject));
-        assertEquals(1, routingTable.size());
-        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
-        assertEquals(1, bridgingTable.size());
-        assertNotNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertEquals(1, ROUTING_TABLE.size());
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertEquals(1, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
 
         // Untagged host discovered on tagged/native port
         // Expect: add one routing rule and one bridging rule
         subject = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
                 Sets.newHashSet(HOST_LOC13), Sets.newHashSet(HOST_IP21), false);
         hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, subject));
-        assertEquals(2, routingTable.size());
-        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP21.toIpPrefix())));
-        assertEquals(2, bridgingTable.size());
-        assertNotNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_NATIVE)));
+        assertEquals(2, ROUTING_TABLE.size());
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP21.toIpPrefix())));
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_NATIVE)));
 
         // Tagged host discovered on untagged port
         // Expect: ignore the host. No rule is added.
         subject = new DefaultHost(PROVIDER_ID, HOST_ID_TAGGED, HOST_MAC, HOST_VLAN_TAGGED,
                 Sets.newHashSet(HOST_LOC11), Sets.newHashSet(HOST_IP11), false);
         hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, subject));
-        assertEquals(2, routingTable.size());
-        assertEquals(2, bridgingTable.size());
+        assertEquals(2, ROUTING_TABLE.size());
+        assertEquals(2, BRIDGING_TABLE.size());
 
         // Tagged host discovered on tagged port with the same IP
         // Expect: update existing route, add one bridging rule
         subject = new DefaultHost(PROVIDER_ID, HOST_ID_TAGGED, HOST_MAC, HOST_VLAN_TAGGED,
                 Sets.newHashSet(HOST_LOC13), Sets.newHashSet(HOST_IP21), false);
         hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, subject));
-        assertEquals(2, routingTable.size());
-        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP21.toIpPrefix())));
-        assertEquals(HOST_VLAN_TAGGED, routingTable.get(new RoutingTableKey(HOST_LOC13.deviceId(),
+        assertEquals(2, ROUTING_TABLE.size());
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP21.toIpPrefix())));
+        assertEquals(HOST_VLAN_TAGGED, ROUTING_TABLE.get(new MockRoutingTableKey(HOST_LOC13.deviceId(),
                 HOST_IP21.toIpPrefix())).vlanId);
-        assertEquals(3, bridgingTable.size());
-        assertNotNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, HOST_VLAN_TAGGED)));
+        assertEquals(3, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, HOST_VLAN_TAGGED)));
     }
 
     @Test
@@ -249,12 +286,12 @@
         Host subject = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
                 Sets.newHashSet(HOST_LOC11, HOST_LOC21), Sets.newHashSet(HOST_IP11), false);
         hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, subject));
-        assertEquals(2, routingTable.size());
-        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
-        assertNotNull(routingTable.get(new RoutingTableKey(DEV2, HOST_IP11.toIpPrefix())));
-        assertEquals(2, bridgingTable.size());
-        assertNotNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
-        assertNotNull(bridgingTable.get(new BridingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertEquals(2, ROUTING_TABLE.size());
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP11.toIpPrefix())));
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
     }
 
     @Test
@@ -265,16 +302,16 @@
         // Add a host
         // Expect: add one routing rule and one bridging rule
         hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, subject));
-        assertEquals(1, routingTable.size());
-        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
-        assertEquals(1, bridgingTable.size());
-        assertNotNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertEquals(1, ROUTING_TABLE.size());
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertEquals(1, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
 
         // Remove the host
         // Expect: add the routing rule and the bridging rule
         hostHandler.processHostRemovedEvent(new HostEvent(HostEvent.Type.HOST_REMOVED, subject));
-        assertEquals(0, routingTable.size());
-        assertEquals(0, bridgingTable.size());
+        assertEquals(0, ROUTING_TABLE.size());
+        assertEquals(0, BRIDGING_TABLE.size());
     }
 
     @Test
@@ -284,18 +321,18 @@
         Host subject = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
                 Sets.newHashSet(HOST_LOC11, HOST_LOC21), Sets.newHashSet(HOST_IP11), false);
         hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, subject));
-        assertEquals(2, routingTable.size());
-        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
-        assertNotNull(routingTable.get(new RoutingTableKey(DEV2, HOST_IP11.toIpPrefix())));
-        assertEquals(2, bridgingTable.size());
-        assertNotNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
-        assertNotNull(bridgingTable.get(new BridingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertEquals(2, ROUTING_TABLE.size());
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP11.toIpPrefix())));
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
 
         // Remove a dual-homed host that has 2 locations
         // Expect: all routing and bridging rules are removed
         hostHandler.processHostRemovedEvent(new HostEvent(HostEvent.Type.HOST_REMOVED, subject));
-        assertEquals(0, routingTable.size());
-        assertEquals(0, bridgingTable.size());
+        assertEquals(0, ROUTING_TABLE.size());
+        assertEquals(0, BRIDGING_TABLE.size());
     }
 
     @Test
@@ -310,32 +347,32 @@
         // Add a host
         // Expect: add one new routing rule, one new bridging rule
         hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, host1));
-        assertEquals(1, routingTable.size());
-        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
-        assertNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP21.toIpPrefix())));
-        assertNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP13.toIpPrefix())));
-        assertEquals(1, bridgingTable.size());
-        assertNotNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
-        assertNull(bridgingTable.get(new BridingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertEquals(1, ROUTING_TABLE.size());
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP21.toIpPrefix())));
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP13.toIpPrefix())));
+        assertEquals(1, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
 
         // Move the host to CP13, which has different subnet setting
         // Expect: remove routing rule. Change vlan in bridging rule.
         hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host3, host1));
-        assertEquals(0, routingTable.size());
-        assertEquals(1, bridgingTable.size());
-        assertNotNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_NATIVE)));
-        assertNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertEquals(0, ROUTING_TABLE.size());
+        assertEquals(1, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_NATIVE)));
+        assertNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
 
         // Move the host to CP21, which has same subnet setting
         // Expect: add a new routing rule. Change vlan in bridging rule.
         hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host2, host3));
-        assertEquals(1, routingTable.size());
-        assertNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
-        assertNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
-        assertNotNull(routingTable.get(new RoutingTableKey(DEV2, HOST_IP11.toIpPrefix())));
-        assertEquals(1, bridgingTable.size());
-        assertNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
-        assertNotNull(bridgingTable.get(new BridingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertEquals(1, ROUTING_TABLE.size());
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP11.toIpPrefix())));
+        assertEquals(1, BRIDGING_TABLE.size());
+        assertNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
     }
 
     @Test
@@ -352,50 +389,50 @@
         // Add a host with IP11, IP12 and LOC11, LOC21
         // Expect: 4 routing rules and 2 bridging rules
         hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, host1));
-        assertEquals(4, routingTable.size());
-        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())).portNumber);
-        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV1, HOST_IP12.toIpPrefix())).portNumber);
-        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV2, HOST_IP11.toIpPrefix())).portNumber);
-        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV2, HOST_IP12.toIpPrefix())).portNumber);
-        assertEquals(2, bridgingTable.size());
-        assertEquals(P1, bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
-        assertEquals(P1, bridgingTable.get(new BridingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(4, ROUTING_TABLE.size());
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
 
         // Move the host to LOC12, LOC22 and keep the IP
         // Expect: 4 routing rules and 2 bridging rules all at the new location
         hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host2, host1));
-        assertEquals(4, routingTable.size());
-        assertEquals(P2, routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())).portNumber);
-        assertEquals(P2, routingTable.get(new RoutingTableKey(DEV1, HOST_IP12.toIpPrefix())).portNumber);
-        assertEquals(P2, routingTable.get(new RoutingTableKey(DEV2, HOST_IP11.toIpPrefix())).portNumber);
-        assertEquals(P2, routingTable.get(new RoutingTableKey(DEV2, HOST_IP12.toIpPrefix())).portNumber);
-        assertEquals(2, bridgingTable.size());
-        assertEquals(P2, bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
-        assertEquals(P2, bridgingTable.get(new BridingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(4, ROUTING_TABLE.size());
+        assertEquals(P2, ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P2, ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(P2, ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P2, ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertEquals(P2, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(P2, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
 
         // Move the host to LOC11, LOC21 and change the IP to IP13, IP14 at the same time
         // Expect: 4 routing rules and 2 bridging rules all at the new location
         hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host3, host2));
-        assertEquals(4, routingTable.size());
-        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV1, HOST_IP13.toIpPrefix())).portNumber);
-        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV1, HOST_IP14.toIpPrefix())).portNumber);
-        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV2, HOST_IP13.toIpPrefix())).portNumber);
-        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV2, HOST_IP14.toIpPrefix())).portNumber);
-        assertEquals(2, bridgingTable.size());
-        assertEquals(P1, bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
-        assertEquals(P1, bridgingTable.get(new BridingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(4, ROUTING_TABLE.size());
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP13.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP14.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP13.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP14.toIpPrefix())).portNumber);
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
 
         // Move the host to LOC11, LOC22 and change the IP to IP12, IP13 at the same time
         // Expect: 4 routing rules and 2 bridging rules all at the new location
         hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host4, host3));
-        assertEquals(4, routingTable.size());
-        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV1, HOST_IP12.toIpPrefix())).portNumber);
-        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV1, HOST_IP13.toIpPrefix())).portNumber);
-        assertEquals(P2, routingTable.get(new RoutingTableKey(DEV2, HOST_IP12.toIpPrefix())).portNumber);
-        assertEquals(P2, routingTable.get(new RoutingTableKey(DEV2, HOST_IP13.toIpPrefix())).portNumber);
-        assertEquals(2, bridgingTable.size());
-        assertEquals(P1, bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
-        assertEquals(P2, bridgingTable.get(new BridingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(4, ROUTING_TABLE.size());
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP13.toIpPrefix())).portNumber);
+        assertEquals(P2, ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(P2, ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP13.toIpPrefix())).portNumber);
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(P2, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
     }
 
     @Test
@@ -408,28 +445,28 @@
         // Add a host
         // Expect: add one new routing rule, one new bridging rule
         hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, host1));
-        assertEquals(1, routingTable.size());
-        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
-        assertNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP21.toIpPrefix())));
-        assertEquals(1, bridgingTable.size());
-        assertNotNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
-        assertNull(bridgingTable.get(new BridingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertEquals(1, ROUTING_TABLE.size());
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP21.toIpPrefix())));
+        assertEquals(1, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
 
         // Move the host to an invalid location
         // Expect: Old flow is removed. New flow is not created
         hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host2, host1));
-        assertEquals(0, routingTable.size());
-        assertEquals(0, bridgingTable.size());
+        assertEquals(0, ROUTING_TABLE.size());
+        assertEquals(0, BRIDGING_TABLE.size());
 
         // Move the host to a valid location
         // Expect: add one new routing rule, one new bridging rule
         hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host1, host2));
-        assertEquals(1, routingTable.size());
-        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
-        assertNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP21.toIpPrefix())));
-        assertEquals(1, bridgingTable.size());
-        assertNotNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
-        assertNull(bridgingTable.get(new BridingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertEquals(1, ROUTING_TABLE.size());
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP21.toIpPrefix())));
+        assertEquals(1, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
     }
 
     @Test
@@ -444,44 +481,44 @@
         // Add a host
         // Expect: add two new routing rules, two new bridging rules
         hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, host1));
-        assertEquals(2, routingTable.size());
-        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())).portNumber);
-        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV2, HOST_IP11.toIpPrefix())).portNumber);
-        assertEquals(2, bridgingTable.size());
-        assertEquals(P1, bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
-        assertEquals(P1, bridgingTable.get(new BridingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(2, ROUTING_TABLE.size());
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
 
         // Move first host location to an invalid location
         // Expect: One routing and one bridging flow
         hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host2, host1));
-        assertEquals(1, routingTable.size());
-        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())).portNumber);
-        assertEquals(1, bridgingTable.size());
-        assertEquals(P1, bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(1, ROUTING_TABLE.size());
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(1, BRIDGING_TABLE.size());
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
 
         // Move second host location to an invalid location
         // Expect: No routing or bridging rule
         hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host3, host2));
-        assertEquals(0, routingTable.size());
-        assertEquals(0, bridgingTable.size());
+        assertEquals(0, ROUTING_TABLE.size());
+        assertEquals(0, BRIDGING_TABLE.size());
 
         // Move second host location back to a valid location
         // Expect: One routing and one bridging flow
         hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host2, host3));
-        assertEquals(1, routingTable.size());
-        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())).portNumber);
-        assertEquals(1, bridgingTable.size());
-        assertEquals(P1, bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(1, ROUTING_TABLE.size());
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(1, BRIDGING_TABLE.size());
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
 
         // Move first host location back to a valid location
         // Expect: Two routing and two bridging flow
         hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host1, host2));
-        assertEquals(2, routingTable.size());
-        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())).portNumber);
-        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV2, HOST_IP11.toIpPrefix())).portNumber);
-        assertEquals(2, bridgingTable.size());
-        assertEquals(P1, bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
-        assertEquals(P1, bridgingTable.get(new BridingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(2, ROUTING_TABLE.size());
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
     }
 
     @Test
@@ -494,38 +531,38 @@
         // Add a host
         // Expect: add four new routing rules, two new bridging rules
         hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, host1));
-        assertEquals(4, routingTable.size());
-        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV3, HOST_IP11.toIpPrefix())).portNumber);
-        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV3, HOST_IP12.toIpPrefix())).portNumber);
-        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV4, HOST_IP11.toIpPrefix())).portNumber);
-        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV4, HOST_IP12.toIpPrefix())).portNumber);
-        assertEquals(2, bridgingTable.size());
-        assertEquals(P1, bridgingTable.get(new BridingTableKey(DEV3, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
-        assertEquals(P1, bridgingTable.get(new BridingTableKey(DEV4, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(4, ROUTING_TABLE.size());
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV3, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV3, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV4, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV4, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV3, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV4, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
 
         // Host becomes single-homed
         // Expect: redirect flows from host location to pair link
         hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host2, host1));
-        assertEquals(4, routingTable.size());
-        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV3, HOST_IP11.toIpPrefix())).portNumber);
-        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV3, HOST_IP12.toIpPrefix())).portNumber);
-        assertEquals(P9, routingTable.get(new RoutingTableKey(DEV4, HOST_IP11.toIpPrefix())).portNumber);
-        assertEquals(P9, routingTable.get(new RoutingTableKey(DEV4, HOST_IP12.toIpPrefix())).portNumber);
-        assertEquals(2, bridgingTable.size());
-        assertEquals(P1, bridgingTable.get(new BridingTableKey(DEV3, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
-        assertEquals(P9, bridgingTable.get(new BridingTableKey(DEV4, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(4, ROUTING_TABLE.size());
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV3, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV3, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(P9, ROUTING_TABLE.get(new MockRoutingTableKey(DEV4, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P9, ROUTING_TABLE.get(new MockRoutingTableKey(DEV4, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV3, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(P9, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV4, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
 
         // Host becomes dual-homed again
         // Expect: Redirect flows from pair link back to host location
         hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host1, host2));
-        assertEquals(4, routingTable.size());
-        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV3, HOST_IP11.toIpPrefix())).portNumber);
-        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV3, HOST_IP12.toIpPrefix())).portNumber);
-        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV4, HOST_IP11.toIpPrefix())).portNumber);
-        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV4, HOST_IP12.toIpPrefix())).portNumber);
-        assertEquals(2, bridgingTable.size());
-        assertEquals(P1, bridgingTable.get(new BridingTableKey(DEV3, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
-        assertEquals(P1, bridgingTable.get(new BridingTableKey(DEV4, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(4, ROUTING_TABLE.size());
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV3, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV3, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV4, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV4, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV3, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV4, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
     }
 
     @Test
@@ -538,32 +575,32 @@
         // Add a host
         // Expect: add four new routing rules, two new bridging rules
         hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, host1));
-        assertEquals(4, routingTable.size());
-        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV3, HOST_IP11.toIpPrefix())).portNumber);
-        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV3, HOST_IP12.toIpPrefix())).portNumber);
-        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV4, HOST_IP11.toIpPrefix())).portNumber);
-        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV4, HOST_IP12.toIpPrefix())).portNumber);
-        assertEquals(2, bridgingTable.size());
-        assertEquals(P1, bridgingTable.get(new BridingTableKey(DEV3, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
-        assertEquals(P1, bridgingTable.get(new BridingTableKey(DEV4, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(4, ROUTING_TABLE.size());
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV3, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV3, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV4, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV4, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV3, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV4, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
 
         // Host becomes single-homed
         // Expect: redirect flows from host location to pair link
         hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host2, host1));
-        assertEquals(4, routingTable.size());
-        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV3, HOST_IP11.toIpPrefix())).portNumber);
-        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV3, HOST_IP12.toIpPrefix())).portNumber);
-        assertEquals(P9, routingTable.get(new RoutingTableKey(DEV4, HOST_IP11.toIpPrefix())).portNumber);
-        assertEquals(P9, routingTable.get(new RoutingTableKey(DEV4, HOST_IP12.toIpPrefix())).portNumber);
-        assertEquals(2, bridgingTable.size());
-        assertEquals(P1, bridgingTable.get(new BridingTableKey(DEV3, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
-        assertEquals(P9, bridgingTable.get(new BridingTableKey(DEV4, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(4, ROUTING_TABLE.size());
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV3, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV3, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(P9, ROUTING_TABLE.get(new MockRoutingTableKey(DEV4, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P9, ROUTING_TABLE.get(new MockRoutingTableKey(DEV4, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV3, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(P9, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV4, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
 
         // Host loses both locations
         // Expect: Remove last location and all previous redirection flows
         hostHandler.processHostRemovedEvent(new HostEvent(HostEvent.Type.HOST_REMOVED, host2));
-        assertEquals(0, routingTable.size());
-        assertEquals(0, bridgingTable.size());
+        assertEquals(0, ROUTING_TABLE.size());
+        assertEquals(0, BRIDGING_TABLE.size());
     }
 
     @Test
@@ -578,29 +615,30 @@
         // Add a host
         // Expect: add one new routing rule. Add one new bridging rule.
         hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, host1));
-        assertEquals(1, routingTable.size());
-        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
-        assertNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP21.toIpPrefix())));
-        assertNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP12.toIpPrefix())));
-        assertEquals(1, bridgingTable.size());
-        assertNotNull(bridgingTable.get(new BridingTableKey(HOST_LOC11.deviceId(), HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertEquals(1, ROUTING_TABLE.size());
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP21.toIpPrefix())));
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP12.toIpPrefix())));
+        assertEquals(1, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(HOST_LOC11.deviceId(), HOST_MAC,
+                INTF_VLAN_UNTAGGED)));
 
         // Update the host IP to same subnet
         // Expect: update routing rule with new IP. No change to bridging rule.
         hostHandler.processHostUpdatedEvent(new HostEvent(HostEvent.Type.HOST_UPDATED, host3, host1));
-        assertEquals(1, routingTable.size());
-        assertNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
-        assertNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP21.toIpPrefix())));
-        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP12.toIpPrefix())));
-        assertEquals(1, bridgingTable.size());
-        assertNotNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertEquals(1, ROUTING_TABLE.size());
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP21.toIpPrefix())));
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP12.toIpPrefix())));
+        assertEquals(1, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
 
         // Update the host IP to different subnet
         // Expect: Remove routing rule. No change to bridging rule.
         hostHandler.processHostUpdatedEvent(new HostEvent(HostEvent.Type.HOST_UPDATED, host2, host3));
-        assertEquals(0, routingTable.size());
-        assertEquals(1, bridgingTable.size());
-        assertNotNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertEquals(0, ROUTING_TABLE.size());
+        assertEquals(1, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
     }
 
     @Test
@@ -615,44 +653,44 @@
         // Add a dual-homed host with two locations and two IPs
         // Expect: add four new routing rules. Add two new bridging rules
         hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, host1));
-        assertEquals(4, routingTable.size());
-        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
-        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP12.toIpPrefix())));
-        assertNotNull(routingTable.get(new RoutingTableKey(DEV2, HOST_IP11.toIpPrefix())));
-        assertNotNull(routingTable.get(new RoutingTableKey(DEV2, HOST_IP12.toIpPrefix())));
-        assertEquals(2, bridgingTable.size());
-        assertNotNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
-        assertNotNull(bridgingTable.get(new BridingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertEquals(4, ROUTING_TABLE.size());
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP12.toIpPrefix())));
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP11.toIpPrefix())));
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP12.toIpPrefix())));
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
 
         // Update both host IPs
         // Expect: update routing rules with new IP. No change to bridging rule.
         hostHandler.processHostUpdatedEvent(new HostEvent(HostEvent.Type.HOST_UPDATED, host3, host1));
-        assertEquals(4, routingTable.size());
-        assertNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
-        assertNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP12.toIpPrefix())));
-        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP13.toIpPrefix())));
-        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP14.toIpPrefix())));
-        assertNull(routingTable.get(new RoutingTableKey(DEV2, HOST_IP11.toIpPrefix())));
-        assertNull(routingTable.get(new RoutingTableKey(DEV2, HOST_IP12.toIpPrefix())));
-        assertNotNull(routingTable.get(new RoutingTableKey(DEV2, HOST_IP13.toIpPrefix())));
-        assertNotNull(routingTable.get(new RoutingTableKey(DEV2, HOST_IP14.toIpPrefix())));
-        assertEquals(2, bridgingTable.size());
-        assertNotNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
-        assertNotNull(bridgingTable.get(new BridingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertEquals(4, ROUTING_TABLE.size());
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP12.toIpPrefix())));
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP13.toIpPrefix())));
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP14.toIpPrefix())));
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP11.toIpPrefix())));
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP12.toIpPrefix())));
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP13.toIpPrefix())));
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP14.toIpPrefix())));
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
 
         // Update one of the host IP to different subnet
         // Expect: update routing rule with new IP. No change to bridging rule.
         hostHandler.processHostUpdatedEvent(new HostEvent(HostEvent.Type.HOST_UPDATED, host2, host3));
-        assertEquals(2, routingTable.size());
-        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
-        assertNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP21.toIpPrefix())));
-        assertNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP12.toIpPrefix())));
-        assertNotNull(routingTable.get(new RoutingTableKey(DEV2, HOST_IP11.toIpPrefix())));
-        assertNull(routingTable.get(new RoutingTableKey(DEV2, HOST_IP21.toIpPrefix())));
-        assertNull(routingTable.get(new RoutingTableKey(DEV2, HOST_IP12.toIpPrefix())));
-        assertEquals(2, bridgingTable.size());
-        assertNotNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
-        assertNotNull(bridgingTable.get(new BridingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertEquals(2, ROUTING_TABLE.size());
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP21.toIpPrefix())));
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP12.toIpPrefix())));
+        assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP11.toIpPrefix())));
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP21.toIpPrefix())));
+        assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP12.toIpPrefix())));
+        assertEquals(2, BRIDGING_TABLE.size());
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
     }
 
     @Test
@@ -660,275 +698,4 @@
         assertNotNull(hostHandler.bridgingFwdObjBuilder(DEV2, HOST_MAC, HOST_VLAN_UNTAGGED, P1, false));
         assertNull(hostHandler.bridgingFwdObjBuilder(DEV2, HOST_MAC, HOST_VLAN_UNTAGGED, P3, false));
     }
-
-    class MockSegmentRoutingManager extends SegmentRoutingManager {
-        MockSegmentRoutingManager() {
-            appId = new DefaultApplicationId(1, SegmentRoutingManager.APP_NAME);
-        }
-
-        @Override
-        public int getPortNextObjectiveId(DeviceId deviceId, PortNumber portNum,
-                                          TrafficTreatment treatment,
-                                          TrafficSelector meta,
-                                          boolean createIfMissing) {
-            int nextId = atomicNextId.incrementAndGet();
-            nextTable.put(nextId, treatment);
-            return nextId;
-        }
-    }
-
-    class MockInterfaceService extends InterfaceServiceAdapter {
-        @Override
-        public Set<Interface> getInterfacesByPort(ConnectPoint cp) {
-            Interface intf = null;
-
-            if (CP11.equals(cp)) {
-                intf = new Interface(null, CP11, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
-                        INTF_VLAN_UNTAGGED, null, null);
-            } else if (CP12.equals(cp)) {
-                intf = new Interface(null, CP12, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
-                        INTF_VLAN_UNTAGGED, null, null);
-            } else if (CP13.equals(cp)) {
-                intf = new Interface(null, CP13, Lists.newArrayList(INTF_IP2), MacAddress.NONE, null,
-                        null, INTF_VLAN_TAGGED, INTF_VLAN_NATIVE);
-            } else if (CP21.equals(cp)) {
-                intf = new Interface(null, CP21, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
-                        INTF_VLAN_UNTAGGED, null, null);
-            } else if (CP22.equals(cp)) {
-                intf = new Interface(null, CP22, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
-                        INTF_VLAN_UNTAGGED, null, null);
-            } else if (CP31.equals(cp)) {
-                intf = new Interface(null, CP31, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
-                        INTF_VLAN_UNTAGGED, null, null);
-            } else if (CP39.equals(cp)) {
-                intf = new Interface(null, CP39, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
-                        null, INTF_VLAN_PAIR, null);
-            } else if (CP41.equals(cp)) {
-                intf = new Interface(null, CP41, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
-                        INTF_VLAN_UNTAGGED, null, null);
-            } else if (CP49.equals(cp)) {
-                intf = new Interface(null, CP49, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
-                        null, INTF_VLAN_PAIR, null);
-            }
-            return Objects.nonNull(intf) ? Sets.newHashSet(intf) : Sets.newHashSet();
-        }
-    }
-
-    class MockMastershipService extends MastershipServiceAdapter {
-        @Override
-        public boolean isLocalMaster(DeviceId deviceId) {
-            Set<DeviceId> localDevices = ImmutableSet.of(DEV1, DEV2, DEV3, DEV4);
-            return localDevices.contains(deviceId);
-        }
-    }
-
-    class MockNetworkConfigRegistry extends NetworkConfigRegistryAdapter {
-        @Override
-        public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
-            if (subject instanceof DeviceId) {
-                DeviceId deviceId = (DeviceId) subject;
-                ObjectMapper mapper = new ObjectMapper();
-                ConfigApplyDelegate delegate = new MockCfgDelegate();
-                JsonNode emptyTree = new ObjectMapper().createObjectNode();
-
-                SegmentRoutingDeviceConfig config = new SegmentRoutingDeviceConfig();
-                config.init(deviceId, "host-handler-test", emptyTree, mapper, delegate);
-                config.setPairDeviceId(subject.equals(DEV3) ? DEV4 : DEV3)
-                        .setPairLocalPort(P9);
-
-                return (C) config;
-            } else {
-                return null;
-            }
-        }
-    }
-
-    class MockCfgDelegate implements ConfigApplyDelegate {
-        @Override
-        public void onApply(@SuppressWarnings("rawtypes") Config config) {
-            config.apply();
-        }
-    }
-
-    class MockFlowObjectiveService extends FlowObjectiveServiceAdapter {
-        @Override
-        public void forward(DeviceId deviceId, ForwardingObjective forwardingObjective) {
-            TrafficSelector selector = forwardingObjective.selector();
-            TrafficTreatment treatment = nextTable.get(forwardingObjective.nextId());
-            MacAddress macAddress = ((EthCriterion) selector.getCriterion(Criterion.Type.ETH_DST)).mac();
-            VlanId vlanId = ((VlanIdCriterion) selector.getCriterion(Criterion.Type.VLAN_VID)).vlanId();
-
-            boolean popVlan = treatment.allInstructions().stream()
-                    .filter(instruction -> instruction.type().equals(Instruction.Type.L2MODIFICATION))
-                    .anyMatch(instruction -> ((L2ModificationInstruction) instruction).subtype()
-                            .equals(L2ModificationInstruction.L2SubType.VLAN_POP));
-            PortNumber portNumber = treatment.allInstructions().stream()
-                    .filter(instruction -> instruction.type().equals(Instruction.Type.OUTPUT))
-                    .map(instruction -> ((Instructions.OutputInstruction) instruction).port()).findFirst().orElse(null);
-            if (portNumber == null) {
-                throw new IllegalArgumentException();
-            }
-
-            Objective.Operation op = forwardingObjective.op();
-
-            BridingTableKey btKey = new BridingTableKey(deviceId, macAddress, vlanId);
-            BridingTableValue btValue = new BridingTableValue(popVlan, portNumber);
-
-            if (op.equals(Objective.Operation.ADD)) {
-                bridgingTable.put(btKey, btValue);
-            } else if (op.equals(Objective.Operation.REMOVE)) {
-                bridgingTable.remove(btKey, btValue);
-            } else {
-                throw new IllegalArgumentException();
-            }
-        }
-    }
-
-    class MockHostService extends HostServiceAdapter {
-        @Override
-        public Set<Host> getHosts() {
-            return Sets.newHashSet(HOST1);
-        }
-    }
-
-    class MockRoutingRulePopulator extends RoutingRulePopulator {
-        MockRoutingRulePopulator() {
-            super(srManager);
-        }
-
-        @Override
-        public void populateRoute(DeviceId deviceId, IpPrefix prefix,
-                                  MacAddress hostMac, VlanId hostVlanId, PortNumber outPort) {
-            RoutingTableKey rtKey = new RoutingTableKey(deviceId, prefix);
-            RoutingTableValue rtValue = new RoutingTableValue(outPort, hostMac, hostVlanId);
-            routingTable.put(rtKey, rtValue);
-        }
-
-        @Override
-        public void revokeRoute(DeviceId deviceId, IpPrefix prefix,
-                                MacAddress hostMac, VlanId hostVlanId, PortNumber outPort) {
-            RoutingTableKey rtKey = new RoutingTableKey(deviceId, prefix);
-            RoutingTableValue rtValue = new RoutingTableValue(outPort, hostMac, hostVlanId);
-            routingTable.remove(rtKey, rtValue);
-        }
-    }
-
-    class BridingTableKey {
-        DeviceId deviceId;
-        MacAddress macAddress;
-        VlanId vlanId;
-
-        BridingTableKey(DeviceId deviceId, MacAddress macAddress, VlanId vlanId) {
-            this.deviceId = deviceId;
-            this.macAddress = macAddress;
-            this.vlanId = vlanId;
-        }
-
-        @Override
-        public boolean equals(final Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (!(obj instanceof BridingTableKey)) {
-                return false;
-            }
-            final BridingTableKey other = (BridingTableKey) obj;
-            return Objects.equals(this.macAddress, other.macAddress) &&
-                    Objects.equals(this.deviceId, other.deviceId) &&
-                    Objects.equals(this.vlanId, other.vlanId);
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(macAddress, vlanId);
-        }
-    }
-
-    class BridingTableValue {
-        boolean popVlan;
-        PortNumber portNumber;
-
-        BridingTableValue(boolean popVlan, PortNumber portNumber) {
-            this.popVlan = popVlan;
-            this.portNumber = portNumber;
-        }
-
-        @Override
-        public boolean equals(final Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (!(obj instanceof BridingTableValue)) {
-                return false;
-            }
-            final BridingTableValue other = (BridingTableValue) obj;
-            return Objects.equals(this.popVlan, other.popVlan) &&
-                    Objects.equals(this.portNumber, other.portNumber);
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(popVlan, portNumber);
-        }
-    }
-
-    class RoutingTableKey {
-        DeviceId deviceId;
-        IpPrefix ipPrefix;
-
-        RoutingTableKey(DeviceId deviceId, IpPrefix ipPrefix) {
-            this.deviceId = deviceId;
-            this.ipPrefix = ipPrefix;
-        }
-
-        @Override
-        public boolean equals(final Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (!(obj instanceof RoutingTableKey)) {
-                return false;
-            }
-            final RoutingTableKey other = (RoutingTableKey) obj;
-            return Objects.equals(this.deviceId, other.deviceId) &&
-                    Objects.equals(this.ipPrefix, other.ipPrefix);
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(deviceId, ipPrefix);
-        }
-    }
-
-    class RoutingTableValue {
-        PortNumber portNumber;
-        MacAddress macAddress;
-        VlanId vlanId;
-
-        RoutingTableValue(PortNumber portNumber, MacAddress macAddress, VlanId vlanId) {
-            this.portNumber = portNumber;
-            this.macAddress = macAddress;
-            this.vlanId = vlanId;
-        }
-
-        @Override
-        public boolean equals(final Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (!(obj instanceof RoutingTableValue)) {
-                return false;
-            }
-            final RoutingTableValue other = (RoutingTableValue) obj;
-            return Objects.equals(this.portNumber, other.portNumber) &&
-                    Objects.equals(this.macAddress, other.macAddress) &&
-                    Objects.equals(this.vlanId, other.vlanId);
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(portNumber, macAddress, vlanId);
-        }
-    }
-
 }
