diff --git a/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule b/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
index b4b4f27..f720188 100644
--- a/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
+++ b/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
@@ -10,19 +10,15 @@
 net.floodlightcontroller.perfmon.PktInProcessingTime
 net.floodlightcontroller.perfmon.NullPktInProcessingTime
 net.floodlightcontroller.restserver.RestApiServer
-net.floodlightcontroller.learningswitch.LearningSwitch
-net.floodlightcontroller.hub.Hub
 net.floodlightcontroller.jython.JythonDebugInterface
 net.floodlightcontroller.counter.CounterStore
 net.floodlightcontroller.counter.NullCounterStore
 net.floodlightcontroller.threadpool.ThreadPool
 net.floodlightcontroller.ui.web.StaticWebRoutable
-net.floodlightcontroller.virtualnetwork.VirtualNetworkFilter
 net.floodlightcontroller.devicemanager.internal.DefaultEntityClassifier
 net.floodlightcontroller.devicemanager.test.MockDeviceManager
 net.floodlightcontroller.core.test.MockFloodlightProvider
 net.floodlightcontroller.core.test.MockThreadPoolService
-net.floodlightcontroller.firewall.Firewall
 net.floodlightcontroller.onoslistener.OnosPublisher
 net.floodlightcontroller.flowcache.FlowManager
 net.floodlightcontroller.routing.TopoRouteService
diff --git a/src/test/java/net/floodlightcontroller/firewall/FirewallTest.java b/src/test/java/net/floodlightcontroller/firewall/FirewallTest.java
deleted file mode 100644
index 959bb49..0000000
--- a/src/test/java/net/floodlightcontroller/firewall/FirewallTest.java
+++ /dev/null
@@ -1,513 +0,0 @@
-package net.floodlightcontroller.firewall;
-
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.module.FloodlightModuleException;
-import net.floodlightcontroller.core.test.MockFloodlightProvider;
-import net.floodlightcontroller.packet.ARP;
-import net.floodlightcontroller.packet.Data;
-import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.packet.IPacket;
-import net.floodlightcontroller.packet.IPv4;
-import net.floodlightcontroller.packet.TCP;
-import net.floodlightcontroller.packet.UDP;
-import net.floodlightcontroller.restserver.IRestApiService;
-import net.floodlightcontroller.restserver.RestApiServer;
-import net.floodlightcontroller.routing.IRoutingDecision;
-import net.floodlightcontroller.storage.IStorageSourceService;
-import net.floodlightcontroller.storage.memory.MemoryStorageSource;
-import net.floodlightcontroller.test.FloodlightTestCase;
-import net.floodlightcontroller.util.MACAddress;
-
-import org.easymock.EasyMock;
-import org.junit.Before;
-import org.junit.Test;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFPacketIn.OFPacketInReason;
-import org.openflow.protocol.OFType;
-import org.openflow.util.HexString;
-
-/**
- * Unit test for stateless firewall implemented as a Google Summer of Code project.
- * 
- * @author Amer Tahir
- */
-public class FirewallTest extends FloodlightTestCase {
-    protected MockFloodlightProvider mockFloodlightProvider;
-    protected FloodlightContext cntx;
-    protected OFPacketIn packetIn;
-    protected IOFSwitch sw;
-    protected IPacket tcpPacket;
-    protected IPacket broadcastARPPacket;
-    protected IPacket ARPReplyPacket;
-    protected IPacket broadcastIPPacket;
-    protected IPacket tcpPacketReply;
-    protected IPacket broadcastMalformedPacket;
-    private Firewall firewall;
-    public static String TestSwitch1DPID = "00:00:00:00:00:00:00:01";
-
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-        cntx = new FloodlightContext();
-        mockFloodlightProvider = getMockFloodlightProvider();
-        firewall = new Firewall();
-        IStorageSourceService storageService = new MemoryStorageSource();
-        RestApiServer restApi = new RestApiServer();
-
-        // Mock switches
-        long dpid = HexString.toLong(TestSwitch1DPID);
-        sw = EasyMock.createNiceMock(IOFSwitch.class);
-        expect(sw.getId()).andReturn(dpid).anyTimes();
-        expect(sw.getStringId()).andReturn(TestSwitch1DPID).anyTimes();
-        replay(sw);
-        // Load the switch map
-        Map<Long, IOFSwitch> switches = new HashMap<Long, IOFSwitch>();
-        switches.put(dpid, sw);
-        mockFloodlightProvider.setSwitches(switches);
-
-        FloodlightModuleContext fmc = new FloodlightModuleContext();
-        fmc.addService(IFloodlightProviderService.class, 
-                mockFloodlightProvider);
-        fmc.addService(IFirewallService.class, firewall);
-        fmc.addService(IStorageSourceService.class, storageService);
-        fmc.addService(IRestApiService.class, restApi);
-
-        try {
-            restApi.init(fmc);
-        } catch (FloodlightModuleException e) {
-            e.printStackTrace();
-        }
-
-        firewall.init(fmc);
-        firewall.startUp(fmc);
-
-        // Build our test packet
-        this.tcpPacket = new Ethernet()
-        .setDestinationMACAddress("00:11:22:33:44:55")
-        .setSourceMACAddress("00:44:33:22:11:00")
-        .setVlanID((short) 42)
-        .setEtherType(Ethernet.TYPE_IPv4)
-        .setPayload(
-                new IPv4()
-                .setTtl((byte) 128)
-                .setSourceAddress("192.168.1.1")
-                .setDestinationAddress("192.168.1.2")
-                .setPayload(new TCP()
-                .setSourcePort((short) 81)
-                .setDestinationPort((short) 80)
-                .setPayload(new Data(new byte[] {0x01}))));
-        
-        // Build a broadcast ARP packet
-        this.broadcastARPPacket = new Ethernet()
-        .setDestinationMACAddress("FF:FF:FF:FF:FF:FF")
-        .setSourceMACAddress("00:44:33:22:11:00")
-        .setVlanID((short) 42)
-        .setEtherType(Ethernet.TYPE_ARP)
-        .setPayload(
-                new ARP()
-                .setHardwareType(ARP.HW_TYPE_ETHERNET)
-                .setProtocolType(ARP.PROTO_TYPE_IP)
-                .setOpCode(ARP.OP_REQUEST)
-                .setHardwareAddressLength((byte)6)
-                .setProtocolAddressLength((byte)4)
-                .setSenderHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:00"))
-                .setSenderProtocolAddress(IPv4.toIPv4Address("192.168.1.1"))
-                .setTargetHardwareAddress(Ethernet.toMACAddress("00:00:00:00:00:00"))
-                .setTargetProtocolAddress(IPv4.toIPv4Address("192.168.1.2"))
-                .setPayload(new Data(new byte[] {0x01})));
-        
-        // Build a ARP packet
-        this.ARPReplyPacket = new Ethernet()
-        .setDestinationMACAddress("00:44:33:22:11:00")
-        .setSourceMACAddress("00:11:22:33:44:55")
-        .setVlanID((short) 42)
-        .setEtherType(Ethernet.TYPE_ARP)
-        .setPayload(
-                new ARP()
-                .setHardwareType(ARP.HW_TYPE_ETHERNET)
-                .setProtocolType(ARP.PROTO_TYPE_IP)
-                .setOpCode(ARP.OP_REQUEST)
-                .setHardwareAddressLength((byte)6)
-                .setProtocolAddressLength((byte)4)
-                .setSenderHardwareAddress(Ethernet.toMACAddress("00:11:22:33:44:55"))
-                .setSenderProtocolAddress(IPv4.toIPv4Address("192.168.1.2"))
-                .setTargetHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:00"))
-                .setTargetProtocolAddress(IPv4.toIPv4Address("192.168.1.1"))
-                .setPayload(new Data(new byte[] {0x01})));
-        
-        // Build a broadcast IP packet
-        this.broadcastIPPacket = new Ethernet()
-        .setDestinationMACAddress("FF:FF:FF:FF:FF:FF")
-        .setSourceMACAddress("00:44:33:22:11:00")
-        .setVlanID((short) 42)
-        .setEtherType(Ethernet.TYPE_IPv4)
-        .setPayload(
-                new IPv4()
-                .setTtl((byte) 128)
-                .setSourceAddress("192.168.1.1")
-                .setDestinationAddress("192.168.1.255")
-                .setPayload(new UDP()
-                .setSourcePort((short) 5000)
-                .setDestinationPort((short) 5001)
-                .setPayload(new Data(new byte[] {0x01}))));
-
-        // Build a malformed broadcast packet
-        this.broadcastMalformedPacket = new Ethernet()
-        .setDestinationMACAddress("FF:FF:FF:FF:FF:FF")
-        .setSourceMACAddress("00:44:33:22:11:00")
-        .setVlanID((short) 42)
-        .setEtherType(Ethernet.TYPE_IPv4)
-        .setPayload(
-                new IPv4()
-                .setTtl((byte) 128)
-                .setSourceAddress("192.168.1.1")
-                .setDestinationAddress("192.168.1.2")
-                .setPayload(new UDP()
-                .setSourcePort((short) 5000)
-                .setDestinationPort((short) 5001)
-                .setPayload(new Data(new byte[] {0x01}))));
-
-        this.tcpPacketReply = new Ethernet()
-        .setDestinationMACAddress("00:44:33:22:11:00")
-        .setSourceMACAddress("00:11:22:33:44:55")
-        .setVlanID((short) 42)
-        .setEtherType(Ethernet.TYPE_IPv4)
-        .setPayload(
-                new IPv4()
-                .setTtl((byte) 128)
-                .setSourceAddress("192.168.1.2")
-                .setDestinationAddress("192.168.1.1")
-                .setPayload(new TCP()
-                .setSourcePort((short) 80)
-                .setDestinationPort((short) 81)
-                .setPayload(new Data(new byte[] {0x02}))));
-    }
-
-    protected void setPacketIn(IPacket packet) {
-        byte[] serializedPacket = packet.serialize();
-        // Build the PacketIn
-        this.packetIn = ((OFPacketIn) mockFloodlightProvider.getOFMessageFactory().getMessage(OFType.PACKET_IN))
-                .setBufferId(-1)
-                .setInPort((short) 1)
-                .setPacketData(serializedPacket)
-                .setReason(OFPacketInReason.NO_MATCH)
-                .setTotalLength((short) serializedPacket.length);
-
-        // Add the packet to the context store
-        IFloodlightProviderService.bcStore.
-        put(cntx, 
-                IFloodlightProviderService.CONTEXT_PI_PAYLOAD, 
-                (Ethernet)packet);
-    }
-
-    @Test
-    public void testNoRules() throws Exception {
-        // enable firewall first
-        firewall.enableFirewall(true);
-        // simulate a packet-in event
-        this.setPacketIn(tcpPacket);
-        firewall.receive(sw, this.packetIn, cntx);
-        verify(sw);
-
-        assertEquals(0, firewall.rules.size());
-
-        IRoutingDecision decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
-        // no rules to match, so firewall should deny
-        assertEquals(decision.getRoutingAction(), IRoutingDecision.RoutingAction.DROP);
-    }
-    
-    @Test
-    public void testReadRulesFromStorage() throws Exception {
-        // add 2 rules first
-        FirewallRule rule = new FirewallRule();
-        rule.in_port = 2;
-        rule.dl_src = MACAddress.valueOf("00:00:00:00:00:01").toLong();
-        rule.dl_dst = MACAddress.valueOf("00:00:00:00:00:02").toLong();
-        rule.priority = 1;
-        rule.action = FirewallRule.FirewallAction.DENY;
-        firewall.addRule(rule);
-        rule = new FirewallRule();
-        rule.in_port = 3;
-        rule.dl_src = MACAddress.valueOf("00:00:00:00:00:02").toLong();
-        rule.dl_dst = MACAddress.valueOf("00:00:00:00:00:01").toLong();
-        rule.nw_proto = IPv4.PROTOCOL_TCP;
-        rule.wildcard_nw_proto = false;
-        rule.tp_dst = 80;
-        rule.priority = 2;
-        rule.action = FirewallRule.FirewallAction.ALLOW;
-        firewall.addRule(rule);
-
-        List<FirewallRule> rules = firewall.readRulesFromStorage();
-        // verify rule 1
-        FirewallRule r = rules.get(0);
-        assertEquals(r.in_port, 2);
-        assertEquals(r.priority, 1);
-        assertEquals(r.dl_src, MACAddress.valueOf("00:00:00:00:00:01").toLong());
-        assertEquals(r.dl_dst, MACAddress.valueOf("00:00:00:00:00:02").toLong());
-        assertEquals(r.action, FirewallRule.FirewallAction.DENY);
-        // verify rule 2
-        r = rules.get(1);
-        assertEquals(r.in_port, 3);
-        assertEquals(r.priority, 2);
-        assertEquals(r.dl_src, MACAddress.valueOf("00:00:00:00:00:02").toLong());
-        assertEquals(r.dl_dst, MACAddress.valueOf("00:00:00:00:00:01").toLong());
-        assertEquals(r.nw_proto, IPv4.PROTOCOL_TCP);
-        assertEquals(r.tp_dst, 80);
-        assertEquals(r.wildcard_nw_proto, false);
-        assertEquals(r.action, FirewallRule.FirewallAction.ALLOW);
-    }
-
-    @Test
-    public void testRuleInsertionIntoStorage() throws Exception {
-        // add TCP rule
-        FirewallRule rule = new FirewallRule();
-        rule.nw_proto = IPv4.PROTOCOL_TCP;
-        rule.wildcard_nw_proto = false;
-        rule.priority = 1;
-        firewall.addRule(rule);
-
-        List<Map<String, Object>> rulesFromStorage = firewall.getStorageRules();
-        assertEquals(1, rulesFromStorage.size());
-        assertEquals(Integer.parseInt((String)rulesFromStorage.get(0).get("ruleid")), rule.ruleid);
-    }
-
-    @Test
-    public void testRuleDeletion() throws Exception {
-        // add TCP rule
-        FirewallRule rule = new FirewallRule();
-        rule.nw_proto = IPv4.PROTOCOL_TCP;
-        rule.wildcard_nw_proto = false;
-        rule.priority = 1;
-        firewall.addRule(rule);
-        int rid = rule.ruleid;
-
-        List<Map<String, Object>> rulesFromStorage = firewall.getStorageRules();
-        assertEquals(1, rulesFromStorage.size());
-        assertEquals(Integer.parseInt((String)rulesFromStorage.get(0).get("ruleid")), rid);
-
-        // delete rule
-        firewall.deleteRule(rid);
-        rulesFromStorage = firewall.getStorageRules();
-        assertEquals(0, rulesFromStorage.size());
-    }
-
-    @Test
-    public void testFirewallDisabled() throws Exception {
-        // firewall isn't enabled by default
-        // so, it shouldn't make any decision
-
-        // add TCP rule
-        FirewallRule rule = new FirewallRule();
-        rule.nw_proto = IPv4.PROTOCOL_TCP;
-        rule.wildcard_nw_proto = false;
-        rule.priority = 1;
-        firewall.addRule(rule);
-
-        this.setPacketIn(tcpPacket);
-        firewall.receive(sw, this.packetIn, cntx);
-        verify(sw);
-
-        assertEquals(1, firewall.rules.size());
-
-        IRoutingDecision decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
-        assertNull(decision);
-    }
-
-    @Test
-    public void testSimpleAllowRule() throws Exception {
-        // enable firewall first
-        firewall.enableFirewall(true);
-
-        // add TCP rule
-        FirewallRule rule = new FirewallRule();
-        rule.dl_type = Ethernet.TYPE_IPv4;
-        rule.wildcard_dl_type = false;
-        rule.nw_proto = IPv4.PROTOCOL_TCP;
-        rule.wildcard_nw_proto = false;
-        // source is IP 192.168.1.2
-        rule.nw_src_prefix = IPv4.toIPv4Address("192.168.1.2");
-        rule.wildcard_nw_src = false;
-        // dest is network 192.168.1.0/24
-        rule.nw_dst_prefix = IPv4.toIPv4Address("192.168.1.0");
-        rule.nw_dst_maskbits = 24;
-        rule.wildcard_nw_dst = false;
-        rule.priority = 1;
-        firewall.addRule(rule);
-
-        // simulate a packet-in events
-
-        this.setPacketIn(tcpPacketReply);
-        firewall.receive(sw, this.packetIn, cntx);
-        verify(sw);
-
-        IRoutingDecision decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
-        assertEquals(decision.getRoutingAction(), IRoutingDecision.RoutingAction.FORWARD_OR_FLOOD);
-
-        // clear decision
-        IRoutingDecision.rtStore.remove(cntx, IRoutingDecision.CONTEXT_DECISION);
-
-        this.setPacketIn(tcpPacket);
-        firewall.receive(sw, this.packetIn, cntx);
-        verify(sw);
-
-        decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
-        assertEquals(decision.getRoutingAction(), IRoutingDecision.RoutingAction.DROP);
-    }
-
-    @Test
-    public void testOverlappingRules() throws Exception {
-        firewall.enableFirewall(true);
-
-        // add TCP port 80 (destination only) allow rule
-        FirewallRule rule = new FirewallRule();
-        rule.dl_type = Ethernet.TYPE_IPv4;
-        rule.wildcard_dl_type = false;
-        rule.nw_proto = IPv4.PROTOCOL_TCP;
-        rule.wildcard_nw_proto = false;
-        rule.tp_dst = 80;
-        rule.priority = 1;
-        firewall.addRule(rule);
-
-        // add block all rule
-        rule = new FirewallRule();
-        rule.action = FirewallRule.FirewallAction.DENY;
-        rule.priority = 2;
-        firewall.addRule(rule);
-
-        assertEquals(2, firewall.rules.size());
-
-        // packet destined to TCP port 80 - should be allowed
-
-        this.setPacketIn(tcpPacket);
-        firewall.receive(sw, this.packetIn, cntx);
-        verify(sw);
-
-        IRoutingDecision decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
-        assertEquals(decision.getRoutingAction(), IRoutingDecision.RoutingAction.FORWARD_OR_FLOOD);
-
-        // clear decision
-        IRoutingDecision.rtStore.remove(cntx, IRoutingDecision.CONTEXT_DECISION);
-
-        // packet destined for port 81 - should be denied
-
-        this.setPacketIn(tcpPacketReply);
-        firewall.receive(sw, this.packetIn, cntx);
-        verify(sw);
-
-        decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
-        assertEquals(decision.getRoutingAction(), IRoutingDecision.RoutingAction.DROP);
-    }
-
-    @Test
-    public void testARP() throws Exception {
-        // enable firewall first
-        firewall.enableFirewall(true);
-
-        // no rules inserted so all traffic other than broadcast and ARP-request-broadcast should be blocked
-
-        // simulate an ARP broadcast packet-in event
-
-        this.setPacketIn(broadcastARPPacket);
-        firewall.receive(sw, this.packetIn, cntx);
-        verify(sw);
-
-        // broadcast-ARP traffic should be allowed
-        IRoutingDecision decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
-        assertEquals(IRoutingDecision.RoutingAction.MULTICAST, decision.getRoutingAction());
-        
-        // clear decision
-        IRoutingDecision.rtStore.remove(cntx, IRoutingDecision.CONTEXT_DECISION);
-        
-        // simulate an ARP reply packet-in event
-
-        this.setPacketIn(ARPReplyPacket);
-        firewall.receive(sw, this.packetIn, cntx);
-        verify(sw);
-
-        // ARP reply traffic should be denied
-        decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
-        assertEquals(decision.getRoutingAction(), IRoutingDecision.RoutingAction.DROP);
-    }
-    
-    @Test
-    public void testIPBroadcast() throws Exception {
-        // enable firewall first
-        firewall.enableFirewall(true);
-        
-        // set subnet mask for IP broadcast
-        firewall.setSubnetMask("255.255.255.0");
-
-        // no rules inserted so all traffic other than broadcast and ARP-request-broadcast should be blocked
-
-        // simulate a packet-in event
-
-        this.setPacketIn(broadcastIPPacket);
-        firewall.receive(sw, this.packetIn, cntx);
-        verify(sw);
-
-        // broadcast traffic should be allowed
-        IRoutingDecision decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
-        assertEquals(IRoutingDecision.RoutingAction.MULTICAST, decision.getRoutingAction());
-    }
-
-    @Test
-    public void testMalformedIPBroadcast() throws Exception {
-        // enable firewall first
-        firewall.enableFirewall(true);
-
-        // no rules inserted so all traffic other than broadcast and ARP-request-broadcast should be blocked
-
-        // simulate a packet-in event
-
-        this.setPacketIn(broadcastMalformedPacket);
-        firewall.receive(sw, this.packetIn, cntx);
-        verify(sw);
-
-        // malformed broadcast traffic should NOT be allowed
-        IRoutingDecision decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
-        assertEquals(decision.getRoutingAction(), IRoutingDecision.RoutingAction.DROP);
-    }
-
-    @Test
-    public void testLayer2Rule() throws Exception {
-        // enable firewall first
-        firewall.enableFirewall(true);
-
-        // add L2 rule
-        FirewallRule rule = new FirewallRule();
-        rule.dl_src = MACAddress.valueOf("00:44:33:22:11:00").toLong();
-        rule.wildcard_dl_src = false;
-        rule.dl_dst = MACAddress.valueOf("00:11:22:33:44:55").toLong();
-        rule.wildcard_dl_dst = false;
-        rule.priority = 1;
-        firewall.addRule(rule);
-
-        // add TCP deny all rule
-        rule = new FirewallRule();
-        rule.nw_proto = IPv4.PROTOCOL_TCP;
-        rule.wildcard_nw_proto = false;
-        rule.priority = 2;
-        rule.action = FirewallRule.FirewallAction.DENY;
-        firewall.addRule(rule);
-
-        // simulate a packet-in event
-
-        this.setPacketIn(tcpPacket);
-        firewall.receive(sw, this.packetIn, cntx);
-        verify(sw);
-
-        IRoutingDecision decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
-        assertEquals(decision.getRoutingAction(), IRoutingDecision.RoutingAction.FORWARD_OR_FLOOD);
-    }
-}
diff --git a/src/test/java/net/floodlightcontroller/hub/HubTest.java b/src/test/java/net/floodlightcontroller/hub/HubTest.java
deleted file mode 100644
index b4a215c..0000000
--- a/src/test/java/net/floodlightcontroller/hub/HubTest.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/**
-*    Copyright 2011, Big Switch Networks, Inc. 
-*    Originally created by David Erickson, Stanford University
-* 
-*    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 net.floodlightcontroller.hub;
-
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
-import static org.easymock.EasyMock.capture;
-
-import java.util.Arrays;
-
-import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IOFMessageListener;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.test.MockFloodlightProvider;
-import net.floodlightcontroller.packet.Data;
-import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.packet.IPacket;
-import net.floodlightcontroller.packet.IPv4;
-import net.floodlightcontroller.packet.UDP;
-import net.floodlightcontroller.test.FloodlightTestCase;
-
-import org.easymock.Capture;
-import org.easymock.CaptureType;
-import org.junit.Before;
-import org.junit.Test;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFPacketIn.OFPacketInReason;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketOut;
-import org.openflow.protocol.OFPort;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.action.OFAction;
-import org.openflow.protocol.action.OFActionOutput;
-
-/**
- *
- * @author David Erickson (daviderickson@cs.stanford.edu)
- */
-public class HubTest extends FloodlightTestCase {
-    protected OFPacketIn packetIn;
-    protected IPacket testPacket;
-    protected byte[] testPacketSerialized;
-    private   MockFloodlightProvider mockFloodlightProvider;
-    private Hub hub;
-    
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-
-        mockFloodlightProvider = getMockFloodlightProvider();
-        hub = new Hub();
-        mockFloodlightProvider.addOFMessageListener(OFType.PACKET_IN, hub);
-        hub.setFloodlightProvider(mockFloodlightProvider);
-        
-        // Build our test packet
-        this.testPacket = new Ethernet()
-            .setDestinationMACAddress("00:11:22:33:44:55")
-            .setSourceMACAddress("00:44:33:22:11:00")
-            .setEtherType(Ethernet.TYPE_IPv4)
-            .setPayload(
-                new IPv4()
-                .setTtl((byte) 128)
-                .setSourceAddress("192.168.1.1")
-                .setDestinationAddress("192.168.1.2")
-                .setPayload(new UDP()
-                            .setSourcePort((short) 5000)
-                            .setDestinationPort((short) 5001)
-                            .setPayload(new Data(new byte[] {0x01}))));
-        this.testPacketSerialized = testPacket.serialize();
-
-        // Build the PacketIn
-        this.packetIn = ((OFPacketIn) mockFloodlightProvider.getOFMessageFactory().getMessage(OFType.PACKET_IN))
-            .setBufferId(-1)
-            .setInPort((short) 1)
-            .setPacketData(this.testPacketSerialized)
-            .setReason(OFPacketInReason.NO_MATCH)
-            .setTotalLength((short) this.testPacketSerialized.length);
-    }
-
-    @Test
-    public void testFloodNoBufferId() throws Exception {
-        // build our expected flooded packetOut
-        OFPacketOut po = ((OFPacketOut) mockFloodlightProvider.getOFMessageFactory().getMessage(OFType.PACKET_OUT))
-            .setActions(Arrays.asList(new OFAction[] {new OFActionOutput().setPort(OFPort.OFPP_FLOOD.getValue())}))
-            .setActionsLength((short) OFActionOutput.MINIMUM_LENGTH)
-            .setBufferId(-1)
-            .setInPort((short) 1)
-            .setPacketData(this.testPacketSerialized);
-        po.setLengthU(OFPacketOut.MINIMUM_LENGTH + po.getActionsLengthU()
-                + this.testPacketSerialized.length);
-
-        // Mock up our expected behavior
-        IOFSwitch mockSwitch = createMock(IOFSwitch.class);
-        
-        Capture<OFMessage> wc1 = new Capture<OFMessage>(CaptureType.ALL);
-        Capture<FloodlightContext> bc1 = new Capture<FloodlightContext>(CaptureType.ALL);
-        
-        mockSwitch.write(capture(wc1), capture(bc1));
-
-        // Start recording the replay on the mocks
-        replay(mockSwitch);
-        // Get the listener and trigger the packet in
-        IOFMessageListener listener = mockFloodlightProvider.getListeners().get(
-                OFType.PACKET_IN).get(0);
-        listener.receive(mockSwitch, this.packetIn,
-                         parseAndAnnotate(this.packetIn));
-
-        // Verify the replay matched our expectations
-        verify(mockSwitch);
-        
-        assertTrue(wc1.hasCaptured());
-        OFMessage m = wc1.getValue();
-        assert(m.equals(po));
-    }
-
-    @Test
-    public void testFloodBufferId() throws Exception {
-        MockFloodlightProvider mockFloodlightProvider = getMockFloodlightProvider();
-        this.packetIn.setBufferId(10);
-
-        // build our expected flooded packetOut
-        OFPacketOut po = ((OFPacketOut) mockFloodlightProvider.getOFMessageFactory().getMessage(OFType.PACKET_OUT))
-            .setActions(Arrays.asList(new OFAction[] {new OFActionOutput().setPort(OFPort.OFPP_FLOOD.getValue())}))
-            .setActionsLength((short) OFActionOutput.MINIMUM_LENGTH)
-            .setBufferId(10)
-            .setInPort((short) 1);
-        po.setLengthU(OFPacketOut.MINIMUM_LENGTH + po.getActionsLengthU());
-
-        // Mock up our expected behavior
-        IOFSwitch mockSwitch = createMock(IOFSwitch.class);
-        Capture<OFMessage> wc1 = new Capture<OFMessage>(CaptureType.ALL);
-        Capture<FloodlightContext> bc1 = new Capture<FloodlightContext>(CaptureType.ALL);
-        
-        mockSwitch.write(capture(wc1), capture(bc1));
-
-        // Start recording the replay on the mocks
-        replay(mockSwitch);
-        // Get the listener and trigger the packet in
-        IOFMessageListener listener = mockFloodlightProvider.getListeners().get(
-                OFType.PACKET_IN).get(0);
-        listener.receive(mockSwitch, this.packetIn,
-                         parseAndAnnotate(this.packetIn));
-
-        // Verify the replay matched our expectations
-        verify(mockSwitch);
-        
-        assertTrue(wc1.hasCaptured());
-        OFMessage m = wc1.getValue();
-        assert(m.equals(po));
-    }
-}
diff --git a/src/test/java/net/floodlightcontroller/learningswitch/LearningSwitchTest.java b/src/test/java/net/floodlightcontroller/learningswitch/LearningSwitchTest.java
deleted file mode 100644
index a68a1b8..0000000
--- a/src/test/java/net/floodlightcontroller/learningswitch/LearningSwitchTest.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/**
-*    Copyright 2011, Big Switch Networks, Inc. 
-*    Originally created by David Erickson, Stanford University
-* 
-*    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 net.floodlightcontroller.learningswitch;
-
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-
-import net.floodlightcontroller.core.IOFMessageListener;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.module.FloodlightTestModuleLoader;
-import net.floodlightcontroller.core.module.IFloodlightModule;
-import net.floodlightcontroller.core.test.MockFloodlightProvider;
-import net.floodlightcontroller.packet.Data;
-import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.packet.IPacket;
-import net.floodlightcontroller.packet.IPv4;
-import net.floodlightcontroller.packet.UDP;
-import net.floodlightcontroller.test.FloodlightTestCase;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.openflow.protocol.OFFlowMod;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFPacketIn.OFPacketInReason;
-import org.openflow.protocol.OFPacketOut;
-import org.openflow.protocol.OFPort;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.action.OFAction;
-import org.openflow.protocol.action.OFActionOutput;
-
-/**
- *
- * @author David Erickson (daviderickson@cs.stanford.edu)
- */
-public class LearningSwitchTest extends FloodlightTestCase {
-    protected OFPacketIn packetIn;
-    protected IPacket testPacket;
-    protected byte[] testPacketSerialized;
-    protected IPacket broadcastPacket;
-    protected byte[] broadcastPacketSerialized;
-    protected IPacket testPacketReply;
-    protected byte[] testPacketReplySerialized;
-    private LearningSwitch learningSwitch;
-    
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-        FloodlightTestModuleLoader fml = new FloodlightTestModuleLoader();
-        Collection<Class<? extends IFloodlightModule>> mods 
-        	= new ArrayList<Class<? extends IFloodlightModule>>();
-        mods.add(LearningSwitch.class);
-        fml.setupModules(mods, null);
-        learningSwitch = (LearningSwitch) fml.getModuleByName(LearningSwitch.class);
-        mockFloodlightProvider = 
-        		(MockFloodlightProvider) fml.getModuleByName(MockFloodlightProvider.class);
-       
-        // Build our test packet
-        this.testPacket = new Ethernet()
-            .setDestinationMACAddress("00:11:22:33:44:55")
-            .setSourceMACAddress("00:44:33:22:11:00")
-            .setVlanID((short) 42)
-            .setEtherType(Ethernet.TYPE_IPv4)
-            .setPayload(
-                new IPv4()
-                .setTtl((byte) 128)
-                .setSourceAddress("192.168.1.1")
-                .setDestinationAddress("192.168.1.2")
-                .setPayload(new UDP()
-                            .setSourcePort((short) 5000)
-                            .setDestinationPort((short) 5001)
-                            .setPayload(new Data(new byte[] {0x01}))));
-        this.testPacketSerialized = testPacket.serialize();
-        // Build a broadcast packet
-        this.broadcastPacket = new Ethernet()
-            .setDestinationMACAddress("FF:FF:FF:FF:FF:FF")
-            .setSourceMACAddress("00:44:33:22:11:00")
-            .setVlanID((short) 42)
-            .setEtherType(Ethernet.TYPE_IPv4)
-            .setPayload(
-                new IPv4()
-                .setTtl((byte) 128)
-                .setSourceAddress("192.168.1.1")
-                .setDestinationAddress("192.168.255.255")
-                .setPayload(new UDP()
-                        .setSourcePort((short) 5000)
-                        .setDestinationPort((short) 5001)
-                        .setPayload(new Data(new byte[] {0x01}))));
-
-        this.broadcastPacketSerialized = broadcastPacket.serialize();
-        this.testPacketReply = new Ethernet()
-            .setDestinationMACAddress("00:44:33:22:11:00")
-            .setSourceMACAddress("00:11:22:33:44:55")
-            .setVlanID((short) 42)
-            .setEtherType(Ethernet.TYPE_IPv4)
-            .setPayload(
-                    new IPv4()
-                    .setTtl((byte) 128)
-                    .setSourceAddress("192.168.1.2")
-                    .setDestinationAddress("192.168.1.1")
-                    .setPayload(new UDP()
-                    .setSourcePort((short) 5001)
-                    .setDestinationPort((short) 5000)
-                    .setPayload(new Data(new byte[] {0x02}))));
-        this.testPacketReplySerialized = testPacketReply.serialize();
-
-        // Build the PacketIn
-        this.packetIn = ((OFPacketIn) mockFloodlightProvider.getOFMessageFactory().getMessage(OFType.PACKET_IN))
-            .setBufferId(-1)
-            .setInPort((short) 1)
-            .setPacketData(this.testPacketSerialized)
-            .setReason(OFPacketInReason.NO_MATCH)
-            .setTotalLength((short) this.testPacketSerialized.length);
-    }
-
-    @Test
-    public void testFlood() throws Exception {
-        // build our expected flooded packetOut
-        OFPacketOut po = new OFPacketOut()
-            .setActions(Arrays.asList(new OFAction[] {new OFActionOutput().setPort(OFPort.OFPP_FLOOD.getValue())}))
-            .setActionsLength((short) OFActionOutput.MINIMUM_LENGTH)
-            .setBufferId(-1)
-            .setInPort((short)1)
-            .setPacketData(this.testPacketSerialized);
-        po.setLengthU(OFPacketOut.MINIMUM_LENGTH + po.getActionsLengthU()
-                + this.testPacketSerialized.length);
-
-        // Mock up our expected behavior
-        IOFSwitch mockSwitch = createMock(IOFSwitch.class);
-        expect(mockSwitch.getStringId()).andReturn("00:11:22:33:44:55:66:77").anyTimes();
-        mockSwitch.write(po, null);
-
-        // Start recording the replay on the mocks
-        replay(mockSwitch);
-        // Get the listener and trigger the packet in
-        IOFMessageListener listener = mockFloodlightProvider.getListeners().get(
-                OFType.PACKET_IN).get(0);
-        // Make sure it's the right listener
-        listener.receive(mockSwitch, this.packetIn, parseAndAnnotate(this.packetIn));
-
-        // Verify the replay matched our expectations      
-        short result = learningSwitch.getFromPortMap(mockSwitch, Ethernet.toLong(Ethernet.toMACAddress("00:44:33:22:11:00")), (short) 42).shortValue();
-        verify(mockSwitch);
-
-        // Verify the MAC table inside the switch
-        assertEquals(1, result);
-    }
-    
-    @Test
-    public void testFlowMod() throws Exception {
-        // tweak the test packet in since we need a bufferId
-        this.packetIn.setBufferId(50);
-
-        // build expected flow mods
-        OFMessage fm1 = ((OFFlowMod) mockFloodlightProvider.getOFMessageFactory().getMessage(OFType.FLOW_MOD))
-            .setActions(Arrays.asList(new OFAction[] {
-                    new OFActionOutput().setPort((short) 2).setMaxLength((short) -1)}))
-            .setBufferId(50)
-            .setCommand(OFFlowMod.OFPFC_ADD)
-            .setIdleTimeout((short) 5)
-            .setMatch(new OFMatch()
-                .loadFromPacket(testPacketSerialized, (short) 1)
-                .setWildcards(OFMatch.OFPFW_NW_PROTO | OFMatch.OFPFW_TP_SRC | OFMatch.OFPFW_TP_DST
-                        | OFMatch.OFPFW_NW_TOS))
-            .setOutPort(OFPort.OFPP_NONE.getValue())
-            .setCookie(1L << 52)
-            .setPriority((short) 100)
-            .setFlags((short)(1 << 0))
-            .setLengthU(OFFlowMod.MINIMUM_LENGTH+OFActionOutput.MINIMUM_LENGTH);
-        OFMessage fm2 = ((OFFlowMod) mockFloodlightProvider.getOFMessageFactory().getMessage(OFType.FLOW_MOD))
-            .setActions(Arrays.asList(new OFAction[] {
-                    new OFActionOutput().setPort((short) 1).setMaxLength((short) -1)}))
-            .setBufferId(-1)
-            .setCommand(OFFlowMod.OFPFC_ADD)
-            .setIdleTimeout((short) 5)
-            .setMatch(new OFMatch()
-                .loadFromPacket(testPacketReplySerialized, (short) 2)
-                .setWildcards(OFMatch.OFPFW_NW_PROTO | OFMatch.OFPFW_TP_SRC | OFMatch.OFPFW_TP_DST
-                        | OFMatch.OFPFW_NW_TOS))
-            .setOutPort(OFPort.OFPP_NONE.getValue())
-            .setCookie(1L << 52)
-            .setPriority((short) 100)
-            .setFlags((short)(1 << 0))
-            .setLengthU(OFFlowMod.MINIMUM_LENGTH+OFActionOutput.MINIMUM_LENGTH);
-
-        // Mock up our expected behavior
-        IOFSwitch mockSwitch = createMock(IOFSwitch.class);
-        expect(mockSwitch.getId()).andReturn(1L).anyTimes();
-        expect(mockSwitch.getAttribute(IOFSwitch.PROP_FASTWILDCARDS)).andReturn((Integer) (OFMatch.OFPFW_IN_PORT | OFMatch.OFPFW_NW_PROTO
-                | OFMatch.OFPFW_TP_SRC | OFMatch.OFPFW_TP_DST | OFMatch.OFPFW_NW_SRC_ALL
-                | OFMatch.OFPFW_NW_DST_ALL | OFMatch.OFPFW_NW_TOS));
-        mockSwitch.write(fm1, null);
-        mockSwitch.write(fm2, null);
-
-        // Start recording the replay on the mocks
-        replay(mockSwitch);
-
-        // Populate the MAC table
-        learningSwitch.addToPortMap(mockSwitch,
-                Ethernet.toLong(Ethernet.toMACAddress("00:11:22:33:44:55")), (short) 42, (short) 2);
-        
-        // Get the listener and trigger the packet in
-        IOFMessageListener listener = mockFloodlightProvider.getListeners().get(
-                OFType.PACKET_IN).get(0);
-        listener.receive(mockSwitch, this.packetIn, parseAndAnnotate(this.packetIn));
-        
-        // Verify the replay matched our expectations
-        short result = learningSwitch.getFromPortMap(mockSwitch, Ethernet.toLong(Ethernet.toMACAddress("00:44:33:22:11:00")), (short) 42).shortValue();
-        verify(mockSwitch);
-
-        // Verify the MAC table inside the switch
-        assertEquals(1, result);
-    }
-}
diff --git a/src/test/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkFilterTest.java b/src/test/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkFilterTest.java
deleted file mode 100644
index 32afe4e..0000000
--- a/src/test/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkFilterTest.java
+++ /dev/null
@@ -1,375 +0,0 @@
-package net.floodlightcontroller.virtualnetwork;
-
-import static org.easymock.EasyMock.*;
-
-import java.util.List;
-
-import org.easymock.EasyMock;
-import org.junit.Before;
-import org.junit.Test;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.OFPacketIn.OFPacketInReason;
-
-import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.core.IOFMessageListener;
-import net.floodlightcontroller.core.IListener.Command;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.test.MockThreadPoolService;
-import net.floodlightcontroller.core.test.PacketFactory;
-import net.floodlightcontroller.devicemanager.IDeviceService;
-import net.floodlightcontroller.devicemanager.IEntityClassifierService;
-import net.floodlightcontroller.devicemanager.internal.DefaultEntityClassifier;
-import net.floodlightcontroller.devicemanager.test.MockDeviceManager;
-import net.floodlightcontroller.flowcache.FlowReconcileManager;
-import net.floodlightcontroller.flowcache.IFlowReconcileService;
-import net.floodlightcontroller.packet.Data;
-import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.packet.IPacket;
-import net.floodlightcontroller.packet.IPv4;
-import net.floodlightcontroller.packet.UDP;
-import net.floodlightcontroller.restserver.IRestApiService;
-import net.floodlightcontroller.restserver.RestApiServer;
-import net.floodlightcontroller.test.FloodlightTestCase;
-import net.floodlightcontroller.threadpool.IThreadPoolService;
-import net.floodlightcontroller.topology.ITopologyService;
-import net.floodlightcontroller.util.MACAddress;
-import net.floodlightcontroller.virtualnetwork.VirtualNetworkFilter;
-
-public class VirtualNetworkFilterTest extends FloodlightTestCase {
-    protected VirtualNetworkFilter vns;
-    protected MockDeviceManager deviceService;
-    
-    protected static String guid1 = "guid1";
-    protected static String net1 = "net1";
-    protected static String gw1 = "1.1.1.1";
-    protected static String guid2 = "guid2";
-    protected static String net2 = "net2";
-    protected static String guid3 = "guid3";
-    protected static String net3 = "net3";
-    protected static String gw2 = "2.2.2.2";
-    
-    protected static MACAddress mac1 = 
-            new MACAddress(Ethernet.toMACAddress("00:11:22:33:44:55"));
-    protected static MACAddress mac2 = 
-            new MACAddress(Ethernet.toMACAddress("00:11:22:33:44:66"));
-    protected static MACAddress mac3 = 
-            new MACAddress(Ethernet.toMACAddress("00:11:22:33:44:77"));
-    protected static MACAddress mac4 = 
-            new MACAddress(Ethernet.toMACAddress("00:11:22:33:44:88"));
-    protected static String hostPort1 = "port1";
-    protected static String hostPort2 = "port2";
-    protected static String hostPort3 = "port3";
-    protected static String hostPort4 = "port4";
-    
-    // For testing forwarding behavior
-    protected IOFSwitch sw1;
-    protected FloodlightContext cntx;
-    protected OFPacketIn mac1ToMac2PacketIn;
-    protected IPacket mac1ToMac2PacketIntestPacket;
-    protected byte[] mac1ToMac2PacketIntestPacketSerialized;
-    protected OFPacketIn mac1ToMac4PacketIn;
-    protected IPacket mac1ToMac4PacketIntestPacket;
-    protected byte[] mac1ToMac4PacketIntestPacketSerialized;
-    protected OFPacketIn mac1ToGwPacketIn;
-    protected IPacket mac1ToGwPacketIntestPacket;
-    protected byte[] mac1ToGwPacketIntestPacketSerialized;
-    protected OFPacketIn packetInDHCPDiscoveryRequest;
-    
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-
-        // Module loading stuff
-        FloodlightModuleContext fmc = new FloodlightModuleContext();
-        RestApiServer restApi = new RestApiServer();
-        deviceService = new MockDeviceManager();
-        FlowReconcileManager frm = new FlowReconcileManager();
-        MockThreadPoolService tps = new MockThreadPoolService();
-        ITopologyService topology = createMock(ITopologyService.class);
-        vns = new VirtualNetworkFilter();
-        DefaultEntityClassifier entityClassifier = new DefaultEntityClassifier();
-        fmc.addService(IRestApiService.class, restApi);
-        fmc.addService(IFloodlightProviderService.class, getMockFloodlightProvider());
-        fmc.addService(IDeviceService.class, deviceService);
-        fmc.addService(IFlowReconcileService.class, frm);
-        fmc.addService(IThreadPoolService.class, tps);
-        fmc.addService(IEntityClassifierService.class, entityClassifier);
-        fmc.addService(ITopologyService.class, topology);
-        tps.init(fmc);
-        frm.init(fmc);
-        deviceService.init(fmc);
-        restApi.init(fmc);
-        getMockFloodlightProvider().init(fmc);
-        entityClassifier.init(fmc);
-        tps.startUp(fmc);
-        vns.init(fmc);
-        frm.startUp(fmc);
-        deviceService.startUp(fmc);
-        restApi.startUp(fmc);
-        getMockFloodlightProvider().startUp(fmc);
-        vns.startUp(fmc);
-        entityClassifier.startUp(fmc);
-
-        topology.addListener(deviceService);
-        expectLastCall().times(1);
-        replay(topology);
-        // Mock switches
-        //fastWilcards mocked as this constant
-        int fastWildcards = 
-                OFMatch.OFPFW_IN_PORT | 
-                OFMatch.OFPFW_NW_PROTO | 
-                OFMatch.OFPFW_TP_SRC | 
-                OFMatch.OFPFW_TP_DST | 
-                OFMatch.OFPFW_NW_SRC_ALL | 
-                OFMatch.OFPFW_NW_DST_ALL |
-                OFMatch.OFPFW_NW_TOS;
-        sw1 = EasyMock.createNiceMock(IOFSwitch.class);
-        expect(sw1.getId()).andReturn(1L).anyTimes();
-        expect(sw1.getAttribute(IOFSwitch.PROP_FASTWILDCARDS)).andReturn((Integer)fastWildcards).anyTimes();
-        expect(sw1.hasAttribute(IOFSwitch.PROP_SUPPORTS_OFPP_TABLE)).andReturn(true).anyTimes();
-        replay(sw1);
-        
-        // Mock packets
-        // Mock from MAC1 -> MAC2
-        mac1ToMac2PacketIntestPacket = new Ethernet()
-            .setDestinationMACAddress(mac2.toBytes())
-            .setSourceMACAddress(mac1.toBytes())
-            .setEtherType(Ethernet.TYPE_IPv4)
-            .setPayload(
-                new IPv4()
-                .setTtl((byte) 128)
-                .setSourceAddress("192.168.1.1")
-                .setDestinationAddress("192.168.1.2")
-                .setPayload(new UDP()
-                            .setSourcePort((short) 5000)
-                            .setDestinationPort((short) 5001)
-                            .setPayload(new Data(new byte[] {0x01}))));
-        mac1ToMac2PacketIntestPacketSerialized = mac1ToMac2PacketIntestPacket.serialize();
-        mac1ToMac2PacketIn = 
-                ((OFPacketIn) mockFloodlightProvider.getOFMessageFactory().
-                        getMessage(OFType.PACKET_IN))
-                        .setBufferId(-1)
-                        .setInPort((short) 1)
-                        .setPacketData(mac1ToMac2PacketIntestPacketSerialized)
-                        .setReason(OFPacketInReason.NO_MATCH)
-                        .setTotalLength((short) mac1ToMac2PacketIntestPacketSerialized.length);
-        
-        // Mock from MAC1 -> MAC4
-        mac1ToMac4PacketIntestPacket = new Ethernet()
-        .setDestinationMACAddress(mac4.toBytes())
-        .setSourceMACAddress(mac1.toBytes())
-        .setEtherType(Ethernet.TYPE_IPv4)
-        .setPayload(
-            new IPv4()
-            .setTtl((byte) 128)
-            .setSourceAddress("192.168.1.1")
-            .setDestinationAddress("192.168.1.2")
-            .setPayload(new UDP()
-                        .setSourcePort((short) 5000)
-                        .setDestinationPort((short) 5001)
-                        .setPayload(new Data(new byte[] {0x01}))));
-        mac1ToMac4PacketIntestPacketSerialized = mac1ToMac4PacketIntestPacket.serialize();
-        mac1ToMac4PacketIn = 
-            ((OFPacketIn) mockFloodlightProvider.getOFMessageFactory().
-                    getMessage(OFType.PACKET_IN))
-                    .setBufferId(-1)
-                    .setInPort((short) 1)
-                    .setPacketData(mac1ToMac4PacketIntestPacketSerialized)
-                    .setReason(OFPacketInReason.NO_MATCH)
-                    .setTotalLength((short) mac1ToMac4PacketIntestPacketSerialized.length);
-        
-        // Mock from MAC1 to gateway1
-        mac1ToGwPacketIntestPacket = new Ethernet()
-        .setDestinationMACAddress("00:11:33:33:44:55") // mac shouldn't matter, can't be other host
-        .setSourceMACAddress(mac1.toBytes())
-        .setEtherType(Ethernet.TYPE_IPv4)
-        .setPayload(
-            new IPv4()
-            .setTtl((byte) 128)
-            .setSourceAddress("192.168.1.1")
-            .setDestinationAddress(gw1)
-            .setPayload(new UDP()
-                        .setSourcePort((short) 5000)
-                        .setDestinationPort((short) 5001)
-                        .setPayload(new Data(new byte[] {0x01}))));
-        mac1ToGwPacketIntestPacketSerialized = mac1ToGwPacketIntestPacket.serialize();
-        mac1ToGwPacketIn = 
-            ((OFPacketIn) mockFloodlightProvider.getOFMessageFactory().
-                    getMessage(OFType.PACKET_IN))
-                    .setBufferId(-1)
-                    .setInPort((short) 1)
-                    .setPacketData(mac1ToGwPacketIntestPacketSerialized)
-                    .setReason(OFPacketInReason.NO_MATCH)
-                    .setTotalLength((short) mac1ToGwPacketIntestPacketSerialized.length);
-    }
-    
-    @Test
-    public void testCreateNetwork() {
-        // Test creating a network with all parameters
-        vns.createNetwork(guid1, net1, IPv4.toIPv4Address(gw1));
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid1));
-        assertTrue(vns.nameToGuid.get(net1).equals(guid1));
-        assertTrue(vns.guidToGateway.get(guid1).equals(IPv4.toIPv4Address(gw1)));
-        assertTrue(vns.vNetsByGuid.get(guid1).name.equals(net1));
-        assertTrue(vns.vNetsByGuid.get(guid1).guid.equals(guid1));
-        assertTrue(vns.vNetsByGuid.get(guid1).gateway.equals(gw1));
-        assertTrue(vns.vNetsByGuid.get(guid1).hosts.size()==0);
-
-        // Test creating network without a gateway
-        vns.createNetwork(guid2, net2, null);
-        assertTrue(vns.nameToGuid.get(net2).equals(guid2));
-        assertTrue(vns.guidToGateway.get(guid2) == null);
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).size() == 1);
-        assertTrue(vns.vNetsByGuid.get(guid2).name.equals(net2));
-        assertTrue(vns.vNetsByGuid.get(guid2).guid.equals(guid2));
-        assertTrue(vns.vNetsByGuid.get(guid2).gateway == null);
-        assertTrue(vns.vNetsByGuid.get(guid2).hosts.size()==0);
-        
-        // Test creating a network that shares the gateway with net1
-        vns.createNetwork(guid3, net3, IPv4.toIPv4Address(gw1));
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid1));
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid3));
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).size() == 2);
-        assertTrue(vns.nameToGuid.get(net3).equals(guid3));
-        assertTrue(vns.guidToGateway.get(guid3).equals(IPv4.toIPv4Address(gw1)));
-        assertTrue(vns.vNetsByGuid.get(guid3).name.equals(net3));
-        assertTrue(vns.vNetsByGuid.get(guid3).guid.equals(guid3));
-        assertTrue(vns.vNetsByGuid.get(guid3).gateway.equals(gw1));
-        assertTrue(vns.vNetsByGuid.get(guid3).hosts.size()==0);
-
-    }
-    
-    @Test
-    public void testModifyNetwork() {
-        // Create some networks
-        
-        testCreateNetwork();
-        // Modify net2 to add a gateway
-        vns.createNetwork(guid2, net2, IPv4.toIPv4Address(gw1));
-        assertTrue(vns.nameToGuid.get(net2).equals(guid2));
-        assertTrue(vns.guidToGateway.get(guid2).equals(IPv4.toIPv4Address(gw1)));
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid1));
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid2));
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid3));
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).size() == 3);
-        // Modify net2 to change it's name
-        vns.createNetwork(guid2, "newnet2", null);
-        // Make sure the gateway is still there
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid2));
-        assertTrue(vns.vNetsByGuid.get(guid2).gateway.equals(gw1));
-        // make sure the new name mapping was learned
-        assertTrue(vns.nameToGuid.get("newnet2").equals(guid2));
-        assertTrue(vns.vNetsByGuid.get(guid2).name.equals("newnet2"));
-        // and the old one was deleted
-        assertFalse(vns.nameToGuid.containsKey(net2));
-    }
-    
-    @Test
-    public void testDeleteNetwork() {
-        testModifyNetwork();
-        // Delete newnet2
-        vns.deleteNetwork(guid2);
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid1));
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid3));
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).size() == 2);
-        assertFalse(vns.nameToGuid.containsKey(net2));
-        assertFalse(vns.guidToGateway.containsKey(net2));
-        assertTrue(vns.vNetsByGuid.get(guid2)==null);
-    }
-    
-    @Test
-    public void testAddHost() {
-        testModifyNetwork();
-        vns.addHost(mac1, guid1, hostPort1);
-        assertTrue(vns.macToGuid.get(mac1).equals(guid1));
-        assertTrue(vns.portToMac.get(hostPort1).equals(mac1));
-        assertTrue(vns.vNetsByGuid.get(guid1).hosts.contains(mac1));
-        vns.addHost(mac2, guid1, hostPort2);
-        assertTrue(vns.macToGuid.get(mac2).equals(guid1));
-        assertTrue(vns.portToMac.get(hostPort2).equals(mac2));
-        assertTrue(vns.vNetsByGuid.get(guid1).hosts.contains(mac2));
-        vns.addHost(mac3, guid3, hostPort3);
-        vns.addHost(mac4, guid3, hostPort4);
-        assertTrue(vns.vNetsByGuid.get(guid3).hosts.contains(mac4));
-    }
-    
-    @Test
-    public void testDeleteHost() {
-        testAddHost();
-
-        String host1Guid = vns.macToGuid.get(mac1);
-        vns.deleteHost(mac1, null);
-        assertFalse(vns.macToGuid.containsKey(mac1));
-        assertFalse(vns.portToMac.containsKey(hostPort1));
-        assertFalse(vns.vNetsByGuid.get(host1Guid).hosts.contains(mac1));
-        
-        String host2Guid = vns.macToGuid.get(vns.portToMac.get(hostPort2));
-        vns.deleteHost(null, hostPort2);
-        assertFalse(vns.macToGuid.containsKey(mac2));
-        assertFalse(vns.portToMac.containsKey(hostPort2));
-        assertFalse(vns.vNetsByGuid.get(host2Guid).hosts.contains(mac2));
-
-        String host3Guid = vns.macToGuid.get(mac3);        
-        vns.deleteHost(mac3, hostPort3);
-        assertFalse(vns.macToGuid.containsKey(mac3));
-        assertFalse(vns.portToMac.containsKey(hostPort3));
-        assertFalse(vns.vNetsByGuid.get(host3Guid).hosts.contains(mac3));
-        
-    }
-    
-    @Test
-    public void testForwarding() {
-        testAddHost();
-        // make sure mac1 can communicate with mac2
-        IOFMessageListener listener = getVirtualNetworkListener();
-        cntx = new FloodlightContext();
-        IFloodlightProviderService.bcStore.put(cntx, 
-                           IFloodlightProviderService.CONTEXT_PI_PAYLOAD, 
-                               (Ethernet)mac1ToMac2PacketIntestPacket);
-        Command ret = listener.receive(sw1, mac1ToMac2PacketIn, cntx);
-        assertTrue(ret == Command.CONTINUE);
-        // make sure mac1 can't communicate with mac4
-        cntx = new FloodlightContext();
-        IFloodlightProviderService.bcStore.put(cntx,
-                           IFloodlightProviderService.CONTEXT_PI_PAYLOAD, 
-                               (Ethernet)mac1ToMac4PacketIntestPacket);
-        ret = listener.receive(sw1, mac1ToMac4PacketIn, cntx);
-        assertTrue(ret == Command.STOP);
-    }
-
-    @Test
-    public void testDefaultGateway() {
-        testAddHost();
-        IOFMessageListener listener = getVirtualNetworkListener();
-        cntx = new FloodlightContext();
-        IFloodlightProviderService.bcStore.put(cntx, 
-                           IFloodlightProviderService.CONTEXT_PI_PAYLOAD, 
-                               (Ethernet)mac1ToGwPacketIntestPacket);
-        deviceService.learnEntity(((Ethernet)mac1ToGwPacketIntestPacket).getDestinationMAC().toLong(), 
-        		null, IPv4.toIPv4Address(gw1), null, null);
-        Command ret = listener.receive(sw1, mac1ToGwPacketIn, cntx);
-        assertTrue(ret == Command.CONTINUE);
-    }
-    
-    @Test
-    public void testDhcp() {
-        IOFMessageListener listener = getVirtualNetworkListener();
-        Ethernet dhcpPacket = PacketFactory.DhcpDiscoveryRequestEthernet(mac1);
-        OFPacketIn dhcpPacketOf = PacketFactory.DhcpDiscoveryRequestOFPacketIn(mac1);
-        cntx = new FloodlightContext();
-        IFloodlightProviderService.bcStore.put(cntx, 
-                           IFloodlightProviderService.CONTEXT_PI_PAYLOAD, 
-                           dhcpPacket);
-        Command ret = listener.receive(sw1, dhcpPacketOf, cntx);
-        assertTrue(ret == Command.CONTINUE);
-    }
-    
-    protected IOFMessageListener getVirtualNetworkListener() {
-    	List<IOFMessageListener> listeners = mockFloodlightProvider.getListeners().get(OFType.PACKET_IN);
-    	return listeners.get(listeners.indexOf(vns));
-    }
-}
