diff --git a/src/test/java/net/floodlightcontroller/staticflowentry/StaticFlowTests.java b/src/test/java/net/floodlightcontroller/staticflowentry/StaticFlowTests.java
deleted file mode 100644
index 4f53342..0000000
--- a/src/test/java/net/floodlightcontroller/staticflowentry/StaticFlowTests.java
+++ /dev/null
@@ -1,302 +0,0 @@
-package net.floodlightcontroller.staticflowentry;
-
-
-/*
-public class StaticFlowTests extends FloodlightTestCase {    
-    
-    static String TestSwitch1DPID = "00:00:00:00:00:00:00:01";
-    static int TotalTestRules = 3;
-    
-    //
-    // Create TestRuleXXX and the corresponding FlowModXXX
-    // for X = 1..3
-    //
-    static Map<String,Object> TestRule1;
-    static OFFlowMod FlowMod1;
-    static {
-        FlowMod1 = new OFFlowMod();
-        TestRule1 = new HashMap<String,Object>();
-        TestRule1.put(COLUMN_NAME, "TestRule1");
-        TestRule1.put(COLUMN_SWITCH, TestSwitch1DPID);
-        // setup match
-        OFMatch match = new OFMatch();
-        TestRule1.put(COLUMN_DL_DST, "00:20:30:40:50:60");
-        match.fromString("dl_dst=00:20:30:40:50:60");
-        // setup actions
-        List<OFAction> actions = new LinkedList<OFAction>();
-        TestRule1.put(COLUMN_ACTIONS, "output=1");
-        actions.add(new OFActionOutput((short)1, (short) Short.MAX_VALUE));
-        // done
-        FlowMod1.setMatch(match);
-        FlowMod1.setActions(actions);
-        FlowMod1.setBufferId(-1);
-        FlowMod1.setOutPort(OFPort.OFPP_NONE.getValue());
-        FlowMod1.setPriority(Short.MAX_VALUE);
-        FlowMod1.setLengthU(OFFlowMod.MINIMUM_LENGTH + 8);  // 8 bytes of actions
-    }
-    
-    static Map<String,Object> TestRule2;
-    static OFFlowMod FlowMod2;
-
-    static {
-        FlowMod2 = new OFFlowMod();
-        TestRule2 = new HashMap<String,Object>();
-        TestRule2.put(COLUMN_NAME, "TestRule2");
-        TestRule2.put(COLUMN_SWITCH, TestSwitch1DPID);
-        // setup match
-        OFMatch match = new OFMatch();
-        TestRule2.put(COLUMN_NW_DST, "192.168.1.0/24");
-        match.fromString("nw_dst=192.168.1.0/24");
-        // setup actions
-        List<OFAction> actions = new LinkedList<OFAction>();
-        TestRule2.put(COLUMN_ACTIONS, "output=1");
-        actions.add(new OFActionOutput((short)1, (short) Short.MAX_VALUE));
-        // done
-        FlowMod2.setMatch(match);
-        FlowMod2.setActions(actions);
-        FlowMod2.setBufferId(-1);
-        FlowMod2.setOutPort(OFPort.OFPP_NONE.getValue());
-        FlowMod2.setPriority(Short.MAX_VALUE);
-        FlowMod2.setLengthU(OFFlowMod.MINIMUM_LENGTH + 8);  // 8 bytes of actions
-
-    }
-    
-   
-    static Map<String,Object> TestRule3;
-    static OFFlowMod FlowMod3;
-    static {
-        FlowMod3 = new OFFlowMod();
-        TestRule3 = new HashMap<String,Object>();
-        TestRule3.put(COLUMN_NAME, "TestRule3");
-        TestRule3.put(COLUMN_SWITCH, TestSwitch1DPID);
-        // setup match
-        OFMatch match = new OFMatch();
-        TestRule3.put(COLUMN_DL_DST, "00:20:30:40:50:60");
-        TestRule3.put(COLUMN_DL_VLAN, 4096);
-        match.fromString("dl_dst=00:20:30:40:50:60,dl_vlan=4096");
-        // setup actions
-        TestRule3.put(COLUMN_ACTIONS, "output=controller");
-        List<OFAction> actions = new LinkedList<OFAction>();
-        actions.add(new OFActionOutput(OFPort.OFPP_CONTROLLER.getValue(), (short) Short.MAX_VALUE));
-        // done
-        FlowMod3.setMatch(match);
-        FlowMod3.setActions(actions);
-        FlowMod3.setBufferId(-1);
-        FlowMod3.setOutPort(OFPort.OFPP_NONE.getValue());
-        FlowMod3.setPriority(Short.MAX_VALUE);
-        FlowMod3.setLengthU(OFFlowMod.MINIMUM_LENGTH + 8);  // 8 bytes of actions
-
-    }
-    
-    private void verifyFlowMod(OFFlowMod testFlowMod,
-            OFFlowMod goodFlowMod) {
-        verifyMatch(testFlowMod, goodFlowMod);
-        verifyActions(testFlowMod, goodFlowMod);
-        // dont' bother testing the cookie; just copy it over
-        goodFlowMod.setCookie(testFlowMod.getCookie());
-        // .. so we can continue to use .equals()
-        assertEquals(goodFlowMod, testFlowMod);
-    }
-    
-
-    private void verifyMatch(OFFlowMod testFlowMod, OFFlowMod goodFlowMod) {
-        assertEquals(goodFlowMod.getMatch(), testFlowMod.getMatch());
-    }
-
-
-    private void verifyActions(OFFlowMod testFlowMod, OFFlowMod goodFlowMod) {
-        List<OFAction> goodActions = goodFlowMod.getActions();
-        List<OFAction> testActions = testFlowMod.getActions();
-        assertNotNull(goodActions);
-        assertNotNull(testActions);
-        assertEquals(goodActions.size(), testActions.size());
-        // assumes actions are marshalled in same order; should be safe
-        for(int i = 0; i < goodActions.size(); i++) {
-            assertEquals(goodActions.get(i), testActions.get(i));
-        }
-
-    }
-
-
-    @Override 
-    public void setUp() throws Exception {
-        super.setUp();
-    }
-    
-    @Test
-    public void testStaticFlowPush() throws IOException {        
-        StaticFlowEntryPusher staticFlowEntryPusher = new StaticFlowEntryPusher();
-        IStorageSourceService storage = createStorageWithFlowEntries();
-        long dpid = HexString.toLong(TestSwitch1DPID);
-
-        // Create a Switch and attach a switch
-        IOFSwitch mockSwitch = createNiceMock(IOFSwitch.class);
-        Capture<OFMessage> writeCapture = new Capture<OFMessage>(CaptureType.ALL);
-        Capture<FloodlightContext> contextCapture = new Capture<FloodlightContext>(CaptureType.ALL);
-        Capture<List<OFMessage>> writeCaptureList = new Capture<List<OFMessage>>(CaptureType.ALL);
-
-        //OFMessageSafeOutStream mockOutStream = createNiceMock(OFMessageSafeOutStream.class);
-        mockSwitch.write(capture(writeCapture), capture(contextCapture));
-        expectLastCall().anyTimes();
-        mockSwitch.write(capture(writeCaptureList), capture(contextCapture));
-        expectLastCall().anyTimes();
-        mockSwitch.flush();
-        expectLastCall().anyTimes();
-        
-        staticFlowEntryPusher.setStorageSource(storage);
-        
-        FloodlightModuleContext fmc = new FloodlightModuleContext();
-        
-        MockFloodlightProvider mockFloodlightProvider = getMockFloodlightProvider();
-        Map<Long, IOFSwitch> switchMap = new HashMap<Long, IOFSwitch>();
-        switchMap.put(dpid, mockSwitch);
-        // NO ! expect(mockFloodlightProvider.getSwitches()).andReturn(switchMap).anyTimes();
-        mockFloodlightProvider.setSwitches(switchMap);
-        staticFlowEntryPusher.setFloodlightProvider(mockFloodlightProvider);
-        RestApiServer restApi = new RestApiServer();
-        try {
-            restApi.init(fmc);
-        } catch (FloodlightModuleException e) {
-            e.printStackTrace();
-        }
-        staticFlowEntryPusher.restApi = restApi;
-        staticFlowEntryPusher.startUp(null);    // again, to hack unittest
-
-        // verify that flowpusher read all three entries from storage
-        assertEquals(TotalTestRules, staticFlowEntryPusher.countEntries());
-        
-        // if someone calls mockSwitch.getOutputStream(), return mockOutStream instead
-        //expect(mockSwitch.getOutputStream()).andReturn(mockOutStream).anyTimes();    
-
-        // if someone calls getId(), return this dpid instead
-        expect(mockSwitch.getId()).andReturn(dpid).anyTimes();
-        expect(mockSwitch.getStringId()).andReturn(TestSwitch1DPID).anyTimes();
-        replay(mockSwitch);
-        
-        // hook the static pusher up to the fake switch
-        staticFlowEntryPusher.addedSwitch(mockSwitch);
-        
-        verify(mockSwitch);
-        
-        // Verify that the switch has gotten some flow_mods
-        assertEquals(true, writeCapture.hasCaptured());
-        assertEquals(TotalTestRules, writeCapture.getValues().size());
-        
-        // Order assumes how things are stored in hash bucket; 
-        // should be fixed because OFMessage.hashCode() is deterministic
-        OFFlowMod firstFlowMod = (OFFlowMod) writeCapture.getValues().get(2);
-        verifyFlowMod(firstFlowMod, FlowMod1);
-        OFFlowMod secondFlowMod = (OFFlowMod) writeCapture.getValues().get(1);
-        verifyFlowMod(secondFlowMod, FlowMod2);
-        OFFlowMod thirdFlowMod = (OFFlowMod) writeCapture.getValues().get(0);
-        verifyFlowMod(thirdFlowMod, FlowMod3);
-        
-        writeCapture.reset();
-        contextCapture.reset();
-        
-        
-        // delete two rules and verify they've been removed
-        // this should invoke staticFlowPusher.rowsDeleted()
-        storage.deleteRow(StaticFlowEntryPusher.TABLE_NAME, "TestRule1");
-        storage.deleteRow(StaticFlowEntryPusher.TABLE_NAME, "TestRule2");
-
-        assertEquals(1, staticFlowEntryPusher.countEntries());
-        assertEquals(2, writeCapture.getValues().size());
-        
-        OFFlowMod firstDelete = (OFFlowMod) writeCapture.getValues().get(0);
-        FlowMod1.setCommand(OFFlowMod.OFPFC_DELETE_STRICT);
-        verifyFlowMod(firstDelete, FlowMod1);
-
-        OFFlowMod secondDelete = (OFFlowMod) writeCapture.getValues().get(1);
-        FlowMod2.setCommand(OFFlowMod.OFPFC_DELETE_STRICT);
-        verifyFlowMod(secondDelete, FlowMod2);
-        
-        // add rules back to make sure that staticFlowPusher.rowsInserted() works
-        writeCapture.reset();
-        FlowMod2.setCommand(OFFlowMod.OFPFC_ADD);
-        storage.insertRow(StaticFlowEntryPusher.TABLE_NAME, TestRule2);
-        assertEquals(2, staticFlowEntryPusher.countEntries());
-        assertEquals(1, writeCaptureList.getValues().size());
-        List<OFMessage> outList = 
-            (List<OFMessage>) writeCaptureList.getValues().get(0);
-        assertEquals(1, outList.size());
-        OFFlowMod firstAdd = (OFFlowMod) outList.get(0);
-        verifyFlowMod(firstAdd, FlowMod2);
-        writeCapture.reset();
-        contextCapture.reset();
-        writeCaptureList.reset();
-        
-        // now try an update, calling staticFlowPusher.rowUpdated()
-        TestRule3.put(COLUMN_DL_VLAN, 333);
-        storage.updateRow(StaticFlowEntryPusher.TABLE_NAME, TestRule3);
-        assertEquals(2, staticFlowEntryPusher.countEntries());
-        assertEquals(1, writeCaptureList.getValues().size());
-
-        outList = (List<OFMessage>) writeCaptureList.getValues().get(0);
-        assertEquals(2, outList.size());
-        OFFlowMod removeFlowMod = (OFFlowMod) outList.get(0);
-        FlowMod3.setCommand(OFFlowMod.OFPFC_DELETE_STRICT);
-        verifyFlowMod(removeFlowMod, FlowMod3);
-        FlowMod3.setCommand(OFFlowMod.OFPFC_ADD);
-        FlowMod3.getMatch().fromString("dl_dst=00:20:30:40:50:60,dl_vlan=333");
-        OFFlowMod updateFlowMod = (OFFlowMod) outList.get(1);
-        verifyFlowMod(updateFlowMod, FlowMod3);
-
-    }
-
-
-    IStorageSourceService createStorageWithFlowEntries() {
-        return populateStorageWithFlowEntries(new MemoryStorageSource());
-    }
-    
-    IStorageSourceService populateStorageWithFlowEntries(IStorageSourceService storage) {
-        Set<String> indexedColumns = new HashSet<String>();
-        indexedColumns.add(COLUMN_NAME);
-        storage.createTable(StaticFlowEntryPusher.TABLE_NAME, indexedColumns);
-        storage.setTablePrimaryKeyName(StaticFlowEntryPusher.TABLE_NAME, COLUMN_NAME);
-
-        storage.insertRow(StaticFlowEntryPusher.TABLE_NAME, TestRule1);
-        storage.insertRow(StaticFlowEntryPusher.TABLE_NAME, TestRule2);
-        storage.insertRow(StaticFlowEntryPusher.TABLE_NAME, TestRule3);
-
-        return storage;
-    }
-    
-    @Test 
-    public void testHARoleChanged() throws IOException {
-        StaticFlowEntryPusher staticFlowEntryPusher = new StaticFlowEntryPusher();
-        IStorageSourceService storage = createStorageWithFlowEntries();
-        MockFloodlightProvider mfp = getMockFloodlightProvider();
-        staticFlowEntryPusher.setFloodlightProvider(mfp);
-        staticFlowEntryPusher.setStorageSource(storage);
-        RestApiServer restApi = new RestApiServer();
-        try {
-            FloodlightModuleContext fmc = new FloodlightModuleContext();
-            restApi.init(fmc);
-        } catch (FloodlightModuleException e) {
-            e.printStackTrace();
-        }
-        staticFlowEntryPusher.restApi = restApi;
-        staticFlowEntryPusher.startUp(null);    // again, to hack unittest
-        
-        assert(staticFlowEntryPusher.entry2dpid.containsValue(TestSwitch1DPID));
-        assert(staticFlowEntryPusher.entriesFromStorage.containsValue(FlowMod1));
-        assert(staticFlowEntryPusher.entriesFromStorage.containsValue(FlowMod2));
-        assert(staticFlowEntryPusher.entriesFromStorage.containsValue(FlowMod3));
-        
-        // Send a notification that we've changed to slave
-        mfp.dispatchRoleChanged(null, Role.SLAVE);
-        // Make sure we've removed all our entries
-        assert(staticFlowEntryPusher.entry2dpid.isEmpty());
-        assert(staticFlowEntryPusher.entriesFromStorage.isEmpty());
-        
-        // Send a notification that we've changed to master
-        mfp.dispatchRoleChanged(Role.SLAVE, Role.MASTER);  
-        // Make sure we've learned the entries
-        assert(staticFlowEntryPusher.entry2dpid.containsValue(TestSwitch1DPID));
-        assert(staticFlowEntryPusher.entriesFromStorage.containsValue(FlowMod1));
-        assert(staticFlowEntryPusher.entriesFromStorage.containsValue(FlowMod2));
-        assert(staticFlowEntryPusher.entriesFromStorage.containsValue(FlowMod3));
-    }
-}
-*/
