diff --git a/src/test/java/net/floodlightcontroller/core/internal/TestDatabaseManager.java b/src/test/java/net/floodlightcontroller/core/internal/TestDatabaseManager.java
index 3d5e03b..8a09139 100644
--- a/src/test/java/net/floodlightcontroller/core/internal/TestDatabaseManager.java
+++ b/src/test/java/net/floodlightcontroller/core/internal/TestDatabaseManager.java
@@ -73,4 +73,4 @@
 		}
 	}
 	
-}
+}
\ No newline at end of file
diff --git a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java
deleted file mode 100644
index 0bf9ba0..0000000
--- a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java
+++ /dev/null
@@ -1,440 +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.linkdiscovery.internal;
-
-import static org.easymock.EasyMock.*;
-
-import java.util.Collections;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.core.IFloodlightProviderService.Role;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.test.MockThreadPoolService;
-import net.floodlightcontroller.linkdiscovery.ILinkDiscoveryListener;
-import net.floodlightcontroller.linkdiscovery.ILinkDiscoveryService;
-import net.floodlightcontroller.linkdiscovery.LinkInfo;
-import net.floodlightcontroller.linkdiscovery.internal.LinkDiscoveryManager;
-import net.floodlightcontroller.restserver.IRestApiService;
-import net.floodlightcontroller.restserver.RestApiServer;
-import net.floodlightcontroller.routing.IRoutingService;
-import net.floodlightcontroller.routing.Link;
-import net.floodlightcontroller.storage.IStorageSourceService;
-import net.floodlightcontroller.storage.memory.MemoryStorageSource;
-import net.floodlightcontroller.test.FloodlightTestCase;
-import net.floodlightcontroller.threadpool.IThreadPoolService;
-import net.floodlightcontroller.topology.ITopologyService;
-import net.floodlightcontroller.topology.NodePortTuple;
-import net.floodlightcontroller.topology.TopologyManager;
-import net.onrc.onos.registry.controller.IControllerRegistryService;
-import net.onrc.onos.registry.controller.StandaloneRegistry;
-
-/**
- *
- * @author David Erickson (daviderickson@cs.stanford.edu)
- */
-public class LinkDiscoveryManagerTest extends FloodlightTestCase {
-
-    private TestLinkDiscoveryManager ldm;
-    private StandaloneRegistry srs;
-    protected static Logger log = LoggerFactory.getLogger(LinkDiscoveryManagerTest.class);
-    
-    public class TestLinkDiscoveryManager extends LinkDiscoveryManager {
-        public boolean isSendLLDPsCalled = false;
-        public boolean isClearLinksCalled = false;
-
-        @Override
-        protected void discoverOnAllPorts() {
-            isSendLLDPsCalled = true;
-            super.discoverOnAllPorts();
-        }
-
-        public void reset() {
-            isSendLLDPsCalled = false;
-            isClearLinksCalled = false;
-        }
-
-        @Override
-        protected void clearAllLinks() {
-            isClearLinksCalled = true;
-            super.clearAllLinks();
-        }
-    }
-    
-    public LinkDiscoveryManager getTopology() {
-        return ldm;
-    }
-
-    public IOFSwitch createMockSwitch(Long id) {
-        IOFSwitch mockSwitch = createNiceMock(IOFSwitch.class);
-        expect(mockSwitch.getId()).andReturn(id).anyTimes();
-        return mockSwitch;
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-        FloodlightModuleContext cntx = new FloodlightModuleContext();
-        ldm = new TestLinkDiscoveryManager();
-        TopologyManager routingEngine = new TopologyManager();
-        ldm.linkDiscoveryAware = new ArrayList<ILinkDiscoveryListener>();
-        srs = new StandaloneRegistry();
-        MockThreadPoolService tp = new MockThreadPoolService();
-        RestApiServer restApi = new RestApiServer();
-        cntx.addService(IRestApiService.class, restApi);
-        cntx.addService(IThreadPoolService.class, tp);
-        cntx.addService(IRoutingService.class, routingEngine);
-        cntx.addService(ILinkDiscoveryService.class, ldm);
-        cntx.addService(ITopologyService.class, ldm);
-        cntx.addService(IStorageSourceService.class, new MemoryStorageSource());
-        cntx.addService(IFloodlightProviderService.class, getMockFloodlightProvider());
-        cntx.addService(IControllerRegistryService.class, srs);
-
-        restApi.init(cntx);
-        tp.init(cntx);
-        routingEngine.init(cntx);
-        srs.init(cntx);
-        ldm.init(cntx);
-        restApi.startUp(cntx);
-        tp.startUp(cntx);
-        routingEngine.startUp(cntx);
-        srs.startUp(cntx);
-        ldm.startUp(cntx);
-
-        IOFSwitch sw1 = createMockSwitch(1L);
-        IOFSwitch sw2 = createMockSwitch(2L);
-        Map<Long, IOFSwitch> switches = new HashMap<Long, IOFSwitch>();
-        switches.put(1L, sw1);
-        switches.put(2L, sw2);
-        getMockFloodlightProvider().setSwitches(switches);
-        replay(sw1, sw2);
-    }
-
-    @Test
-    public void testAddOrUpdateLink() throws Exception {
-        LinkDiscoveryManager topology = getTopology();
-
-        Link lt = new Link(1L, 2, 2L, 1);
-        LinkInfo info = new LinkInfo(System.currentTimeMillis(),
-                                     System.currentTimeMillis(), null,
-                                     0, 0);
-        topology.addOrUpdateLink(lt, info);
-
-
-        NodePortTuple srcNpt = new NodePortTuple(1L, 2);
-        NodePortTuple dstNpt = new NodePortTuple(2L, 1);
-
-        // check invariants hold
-        assertNotNull(topology.switchLinks.get(lt.getSrc()));
-        assertTrue(topology.switchLinks.get(lt.getSrc()).contains(lt));
-        assertNotNull(topology.portLinks.get(srcNpt));
-        assertTrue(topology.portLinks.get(srcNpt).contains(lt));
-        assertNotNull(topology.portLinks.get(dstNpt));
-        assertTrue(topology.portLinks.get(dstNpt).contains(lt));
-        assertTrue(topology.links.containsKey(lt));
-    }
-
-    @Test
-    public void testDeleteLink() throws Exception {
-        LinkDiscoveryManager topology = getTopology();
-
-        Link lt = new Link(1L, 2, 2L, 1);
-        LinkInfo info = new LinkInfo(System.currentTimeMillis(),
-                                     System.currentTimeMillis(), null,
-                                     0, 0);
-        topology.addOrUpdateLink(lt, info);
-        topology.deleteLinks(Collections.singletonList(lt), "Test");
-
-        // check invariants hold
-        assertNull(topology.switchLinks.get(lt.getSrc()));
-        assertNull(topology.switchLinks.get(lt.getDst()));
-        assertNull(topology.portLinks.get(lt.getSrc()));
-        assertNull(topology.portLinks.get(lt.getDst()));
-        assertTrue(topology.links.isEmpty());
-    }
-
-    @Test
-    public void testAddOrUpdateLinkToSelf() throws Exception {
-        LinkDiscoveryManager topology = getTopology();
-
-        Link lt = new Link(1L, 2, 2L, 3);
-        NodePortTuple srcNpt = new NodePortTuple(1L, 2);
-        NodePortTuple dstNpt = new NodePortTuple(2L, 3);
-
-        LinkInfo info = new LinkInfo(System.currentTimeMillis(),
-                                     System.currentTimeMillis(), null,
-                                     0, 0);
-        topology.addOrUpdateLink(lt, info);
-
-        // check invariants hold
-        assertNotNull(topology.switchLinks.get(lt.getSrc()));
-        assertTrue(topology.switchLinks.get(lt.getSrc()).contains(lt));
-        assertNotNull(topology.portLinks.get(srcNpt));
-        assertTrue(topology.portLinks.get(srcNpt).contains(lt));
-        assertNotNull(topology.portLinks.get(dstNpt));
-        assertTrue(topology.portLinks.get(dstNpt).contains(lt));
-        assertTrue(topology.links.containsKey(lt));
-    }
-
-    @Test
-    public void testDeleteLinkToSelf() throws Exception {
-        LinkDiscoveryManager topology = getTopology();
-
-        Link lt = new Link(1L, 2, 1L, 3);
-        NodePortTuple srcNpt = new NodePortTuple(1L, 2);
-        NodePortTuple dstNpt = new NodePortTuple(2L, 3);
-
-        LinkInfo info = new LinkInfo(System.currentTimeMillis(),
-                                     System.currentTimeMillis(), null,
-                                     0, 0);
-        topology.addOrUpdateLink(lt, info);
-        topology.deleteLinks(Collections.singletonList(lt), "Test to self");
-
-        // check invariants hold
-        assertNull(topology.switchLinks.get(lt.getSrc()));
-        assertNull(topology.switchLinks.get(lt.getDst()));
-        assertNull(topology.portLinks.get(srcNpt));
-        assertNull(topology.portLinks.get(dstNpt));
-        assertTrue(topology.links.isEmpty());
-    }
-
-    @Test
-    public void testRemovedSwitch() {
-        LinkDiscoveryManager topology = getTopology();
-
-        Link lt = new Link(1L, 2, 2L, 1);
-        NodePortTuple srcNpt = new NodePortTuple(1L, 2);
-        NodePortTuple dstNpt = new NodePortTuple(2L, 1);
-        LinkInfo info = new LinkInfo(System.currentTimeMillis(),
-                                     System.currentTimeMillis(), null,
-                                     0, 0);
-        topology.addOrUpdateLink(lt, info);
-
-        IOFSwitch sw1 = getMockFloodlightProvider().getSwitches().get(1L);
-        IOFSwitch sw2 = getMockFloodlightProvider().getSwitches().get(2L);
-        // Mock up our expected behavior
-        topology.removedSwitch(sw1);
-        verify(sw1, sw2);
-
-        // check invariants hold
-        assertNull(topology.switchLinks.get(lt.getSrc()));
-        assertNull(topology.switchLinks.get(lt.getDst()));
-        assertNull(topology.portLinks.get(srcNpt));
-        assertNull(topology.portLinks.get(dstNpt));
-        assertTrue(topology.links.isEmpty());
-    }
-
-    @Test
-    public void testRemovedSwitchSelf() {
-        LinkDiscoveryManager topology = getTopology();
-        IOFSwitch sw1 = createMockSwitch(1L);
-        replay(sw1);
-        Link lt = new Link(1L, 2, 1L, 3);
-        LinkInfo info = new LinkInfo(System.currentTimeMillis(),
-                                     System.currentTimeMillis(), null,
-                                     0, 0);
-        topology.addOrUpdateLink(lt, info);
-
-        // Mock up our expected behavior
-        topology.removedSwitch(sw1);
-
-        verify(sw1);
-        // check invariants hold
-        assertNull(topology.switchLinks.get(lt.getSrc()));
-        assertNull(topology.portLinks.get(lt.getSrc()));
-        assertNull(topology.portLinks.get(lt.getDst()));
-        assertTrue(topology.links.isEmpty());
-    }
-
-    @Test
-    public void testAddUpdateLinks() throws Exception {
-        LinkDiscoveryManager topology = getTopology();
-
-        Link lt = new Link(1L, 1, 2L, 1);
-        NodePortTuple srcNpt = new NodePortTuple(1L, 1);
-        NodePortTuple dstNpt = new NodePortTuple(2L, 1);
-        
-        LinkInfo info;
-
-        info = new LinkInfo(System.currentTimeMillis() - 40000,
-                            System.currentTimeMillis() - 40000, null,
-                                     0, 0);
-        topology.addOrUpdateLink(lt, info);
-
-        // check invariants hold
-        assertNotNull(topology.switchLinks.get(lt.getSrc()));
-        assertTrue(topology.switchLinks.get(lt.getSrc()).contains(lt));
-        assertNotNull(topology.portLinks.get(srcNpt));
-        assertTrue(topology.portLinks.get(srcNpt).contains(lt));
-        assertNotNull(topology.portLinks.get(dstNpt));
-        assertTrue(topology.portLinks.get(dstNpt).contains(lt));
-        assertTrue(topology.links.containsKey(lt));
-        assertTrue(topology.portBroadcastDomainLinks.get(srcNpt) == null ||
-                topology.portBroadcastDomainLinks.get(srcNpt).contains(lt) == false);
-        assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
-                topology.portBroadcastDomainLinks.get(dstNpt).contains(lt) == false);
-
-        topology.timeoutLinks();
-
-
-        info = new LinkInfo(System.currentTimeMillis(),/* firstseen */
-                            null,/* unicast */
-                            System.currentTimeMillis(), 0, 0);
-        topology.addOrUpdateLink(lt, info);
-        assertTrue(topology.links.get(lt).getUnicastValidTime() == null);
-        assertTrue(topology.links.get(lt).getMulticastValidTime() != null);
-        assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
-        assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
-
-
-        // Add a link info based on info that woudld be obtained from unicast LLDP
-        // Setting the unicast LLDP reception time to be 40 seconds old, so we can use
-        // this to test timeout after this test.  Although the info is initialized
-        // with LT_OPENFLOW_LINK, the link property should be changed to LT_NON_OPENFLOW
-        // by the addOrUpdateLink method.
-        info = new LinkInfo(System.currentTimeMillis() - 40000,
-                            System.currentTimeMillis() - 40000, null, 0, 0);
-        topology.addOrUpdateLink(lt, info);
-        assertTrue(topology.portBroadcastDomainLinks.get(srcNpt) == null ||
-                topology.portBroadcastDomainLinks.get(srcNpt).contains(lt) == false);
-        assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
-                topology.portBroadcastDomainLinks.get(dstNpt).contains(lt) == false);
-
-        // Expect to timeout the unicast Valid Time, but not the multicast Valid time
-        // So the link type should go back to non-openflow link.
-        topology.timeoutLinks();
-        assertTrue(topology.links.get(lt).getUnicastValidTime() == null);
-        assertTrue(topology.links.get(lt).getMulticastValidTime() != null);
-        assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
-        assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
-
-        // Set the multicastValidTime to be old and see if that also times out.
-        info = new LinkInfo(System.currentTimeMillis() - 40000,
-                            null, System.currentTimeMillis() - 40000, 0, 0);
-        topology.addOrUpdateLink(lt, info);
-        topology.timeoutLinks();
-        assertTrue(topology.links.get(lt) == null);
-        assertTrue(topology.portBroadcastDomainLinks.get(srcNpt) == null ||
-                topology.portBroadcastDomainLinks.get(srcNpt).contains(lt) == false);
-        assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
-                topology.portBroadcastDomainLinks.get(dstNpt).contains(lt) == false);
-
-
-        // Test again only with multicast LLDP
-        info = new LinkInfo(System.currentTimeMillis() - 40000,
-                            null, System.currentTimeMillis() - 40000, 0, 0);
-        topology.addOrUpdateLink(lt, info);
-        assertTrue(topology.links.get(lt).getUnicastValidTime() == null);
-        assertTrue(topology.links.get(lt).getMulticastValidTime() != null);
-        assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
-        assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
-
-        // Call timeout and check if link is no longer present.
-        topology.timeoutLinks();
-        assertTrue(topology.links.get(lt) == null);
-        assertTrue(topology.portBroadcastDomainLinks.get(srcNpt) == null ||
-                topology.portBroadcastDomainLinks.get(srcNpt).contains(lt) == false);
-        assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
-                topology.portBroadcastDomainLinks.get(dstNpt).contains(lt) == false);
-
-        // Start clean and see if loops are also added.
-        lt = new Link(1L, 1, 1L, 2);
-        srcNpt = new NodePortTuple(1L, 1);
-        dstNpt = new NodePortTuple(1L, 2);
-        info = new LinkInfo(System.currentTimeMillis() - 40000,
-                            null, System.currentTimeMillis() - 40000, 0, 0);
-        topology.addOrUpdateLink(lt, info);
-        assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
-        assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
-
-
-        // Start clean and see if loops are also added.
-        lt = new Link(1L, 1, 1L, 3);
-        srcNpt = new NodePortTuple(1L, 1);
-        dstNpt = new NodePortTuple(1L, 3);
-        info = new LinkInfo(System.currentTimeMillis() - 40000,
-                            null, System.currentTimeMillis() - 40000, 0, 0);
-        topology.addOrUpdateLink(lt, info);
-        assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
-        assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
-
-
-        // Start clean and see if loops are also added.
-        lt = new Link(1L, 4, 1L, 5);
-        srcNpt = new NodePortTuple(1L, 4);
-        dstNpt = new NodePortTuple(1L, 5);
-        info = new LinkInfo(System.currentTimeMillis() - 40000,
-                            null, System.currentTimeMillis() - 40000, 0, 0);
-        topology.addOrUpdateLink(lt, info);
-        assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
-        assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
-
-
-        // Start clean and see if loops are also added.
-        lt = new Link(1L, 3, 1L, 5);
-        srcNpt = new NodePortTuple(1L, 3);
-        dstNpt = new NodePortTuple(1L, 5);
-        info = new LinkInfo(System.currentTimeMillis() - 40000,
-                            null, System.currentTimeMillis() - 40000, 0, 0);
-        topology.addOrUpdateLink(lt, info);
-        assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
-        assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
-    }
-
-    @Test
-    public void testHARoleChange() throws Exception {
-        LinkDiscoveryManager topology = getTopology();
-        IOFSwitch sw1 = createMockSwitch(1L);
-        IOFSwitch sw2 = createMockSwitch(2L);
-        replay(sw1, sw2);
-        Link lt = new Link(1L, 2, 2L, 1);
-        NodePortTuple srcNpt = new NodePortTuple(1L, 2);
-        NodePortTuple dstNpt = new NodePortTuple(2L, 1);
-        LinkInfo info = new LinkInfo(System.currentTimeMillis(),
-                                     System.currentTimeMillis(), null,
-                                     0, 0);
-        topology.addOrUpdateLink(lt, info);
-
-        // check invariants hold
-        assertNotNull(topology.switchLinks.get(lt.getSrc()));
-        assertTrue(topology.switchLinks.get(lt.getSrc()).contains(lt));
-        assertNotNull(topology.portLinks.get(srcNpt));
-        assertTrue(topology.portLinks.get(srcNpt).contains(lt));
-        assertNotNull(topology.portLinks.get(dstNpt));
-        assertTrue(topology.portLinks.get(dstNpt).contains(lt));
-        assertTrue(topology.links.containsKey(lt));
-        
-        // check that it clears from memory
-        getMockFloodlightProvider().dispatchRoleChanged(null, Role.SLAVE);
-        assertTrue(topology.switchLinks.isEmpty());
-        getMockFloodlightProvider().dispatchRoleChanged(Role.SLAVE, Role.MASTER);
-        // check that lldps were sent
-        assertTrue(ldm.isSendLLDPsCalled);
-        assertTrue(ldm.isClearLinksCalled);
-        ldm.reset();
-    }
-}
diff --git a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImplTest.java b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImplTest.java
deleted file mode 100644
index 09319bf..0000000
--- a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImplTest.java
+++ /dev/null
@@ -1,536 +0,0 @@
-package net.floodlightcontroller.linkdiscovery.internal;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import net.floodlightcontroller.linkdiscovery.LinkInfo;
-import net.floodlightcontroller.linkdiscovery.internal.TestableGraphDBOperation.TestPortObject;
-import net.floodlightcontroller.routing.Link;
-import net.onrc.onos.ofcontroller.core.INetMapStorage.DM_OPERATION;
-import net.onrc.onos.ofcontroller.linkdiscovery.ILinkStorage;
-import net.onrc.onos.util.GraphDBConnection;
-import net.onrc.onos.util.GraphDBOperation;
-
-import org.easymock.EasyMock;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.openflow.protocol.OFPhysicalPort;
-import org.openflow.util.HexString;
-import org.powermock.api.easymock.PowerMock;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({LinkStorageImpl.class, GraphDBConnection.class, GraphDBOperation.class})
-public class LinkStorageImplTest {
-	protected static Logger log = LoggerFactory.getLogger(LinkStorageImplTest.class);
-
-	private static ILinkStorage linkStorage;
-	
-	// Mock GraphDBConnection (do nothing)
-	private static GraphDBConnection conn;
-	
-	// Mock GraphDBOperation (mocks port-related methods only)
-	private static TestableGraphDBOperation ope;
-
-	/**
-	 * Setup code called before each tests.
-	 * Read test graph data and replace DB access by test graph data.
-	 * @throws Exception
-	 */
-	@Before
-	public void setUp() throws Exception{
-		PowerMock.mockStatic(GraphDBConnection.class);
-		PowerMock.suppress(PowerMock.constructor(GraphDBConnection.class));
-		conn = PowerMock.createNiceMock(GraphDBConnection.class);
-		EasyMock.expect(GraphDBConnection.getInstance((String)EasyMock.anyObject())).andReturn(conn).anyTimes();
-		PowerMock.replay(GraphDBConnection.class);
-		
-		ope = new TestableGraphDBOperation();
-		PowerMock.expectNew(GraphDBOperation.class, (GraphDBConnection)EasyMock.anyObject()).andReturn(ope).anyTimes();
-		PowerMock.replay(GraphDBOperation.class);
-
-		linkStorage = new LinkStorageImpl();
-		linkStorage.init("/dummy/path/to/conf");
-		
-		initLinks();
-	}
-	
-	/**
-	 * Closing code called after each tests.
-	 * Discard test graph data.
-	 * @throws Exception
-	 */
-	@After
-	public void tearDown() throws Exception {
-		// finish code
-		linkStorage.close();
-		ope.close();
-	}
-	
-	// TODO: remove @Ignore after UPDATE method is implemented
-	/**
-	 * Test if update() can correctly updates LinkInfo for a Link.
-	 */
-	@Ignore @Test
-	public void testUpdate_UpdateSingleLink() {
-		Link linkToUpdate= createExistingLink();
-		long currentTime = System.currentTimeMillis();
-		LinkInfo infoToUpdate = createFeasibleLinkInfo(currentTime);
-		LinkInfo infoToVerify = createFeasibleLinkInfo(currentTime);
-
-		linkStorage.update(linkToUpdate, infoToUpdate, ILinkStorage.DM_OPERATION.UPDATE);
-		
-		doTestLinkHasStateOf(linkToUpdate, infoToVerify);
-	}
-	
-	/**
-	 * Test if update() can correctly creates a Link.
-	 */
-	@Test
-	public void testUpdate_CreateSingleLink() {
-		Link linkToCreate = createFeasibleLink();
-		Link linkToVerify = createFeasibleLink();
-		
-		//Use the link storage API to add the link
-		linkStorage.update(linkToCreate, ILinkStorage.DM_OPERATION.CREATE);
-		doTestLinkExist(linkToVerify);
-	}
-
-	/**
-	 * Test if update() can correctly inserts a Link.
-	 */
-	@Test
-	public void testUpdate_InsertSingleLink(){
-		Link linkToInsert = createFeasibleLink();
-		Link linkToVerify = createFeasibleLink();
-		
-		//Use the link storage API to add the link
-		linkStorage.update(linkToInsert, ILinkStorage.DM_OPERATION.INSERT);
-		doTestLinkExist(linkToVerify);
-	}
-	
-	/**
-	 * Test if update() can correctly deletes a Link.
-	 */
-	@Test
-	public void testUpdate_DeleteSingleLink(){
-		Link linkToDelete = createExistingLink();
-		Link linkToVerify = createExistingLink();
-
-		// Test deletion of existing link
-		linkStorage.update(linkToDelete, DM_OPERATION.DELETE);
-		doTestLinkNotExist(linkToVerify);
-	}
-
-	/**
-	 * Test if update() can correctly creates multiple Links.
-	 */
-	@Test
-	public void testUpdate_CreateLinks(){
-		List<Link> linksToCreate = createFeasibleLinks();
-		List<Link> linksToVerify = createFeasibleLinks();
-
-		// Test creation of new links
-		linkStorage.update(linksToCreate, ILinkStorage.DM_OPERATION.CREATE);
-		for(Link l : linksToVerify) {
-			doTestLinkExist(l);
-		}
-	}
-	
-	/**
-	 * Test if update() can handle mixture of normal/abnormal input for creation of Links.
-	 * Deprecated: DBOperation is responsible.
-	 */
-	@Ignore @Test
-	public void testUpdate_CreateLinks_Mixuture(){
-		List<Link> linksToCreate = new ArrayList<Link>();
-		linksToCreate.add(createFeasibleLink());
-		linksToCreate.add(createExistingLink());
-		
-		// Test creation of mixture of new/existing links
-		linkStorage.update(linksToCreate, ILinkStorage.DM_OPERATION.CREATE);
-		doTestLinkExist(createFeasibleLink());
-		doTestLinkExist(createExistingLink());
-	}
-
-	/**
-	 * Test if update() can correctly inserts multiple Links.
-	 */
-	@Test
-	public void testUpdate_InsertLinks(){
-		List<Link> linksToInsert = createFeasibleLinks();
-		List<Link> linksToVerify = createFeasibleLinks();
-		
-		// Test insertion of new links
-		linkStorage.update(linksToInsert, ILinkStorage.DM_OPERATION.INSERT);
-		for(Link l : linksToVerify) {
-			doTestLinkExist(l);
-		}
-	}
-	
-	/**
-	 * Test if update() can handle mixture of normal/abnormal input for creation of Links.
-	 */
-	@Ignore @Test
-	public void testUpdate_InsertLinks_Mixuture(){
-		List<Link> linksToInsert = new ArrayList<Link>();
-		linksToInsert.add(createFeasibleLink());
-		linksToInsert.add(createExistingLink());
-		
-		// Test insertion of mixture of new/existing links
-		linkStorage.update(linksToInsert, ILinkStorage.DM_OPERATION.INSERT);
-		doTestLinkExist(createFeasibleLink());
-		doTestLinkExist(createExistingLink());
-	}
-
-	/**
-	 * Test if update() can correctly deletes multiple Links.
-	 */
-	@Test
-	public void testUpdate_DeleteLinks(){
-		List<Link> linksToDelete = createExistingLinks();
-		List<Link> linksToVerify = createExistingLinks();
-		
-		// Test deletion of existing links
-		linkStorage.update(linksToDelete, ILinkStorage.DM_OPERATION.DELETE);
-		for(Link l : linksToVerify) {
-			doTestLinkNotExist(l);
-		}
-	}
-	
-	/**
-	 * Test if update() can handle mixture of normal/abnormal input for deletion of Links.
-	 */
-	@Ignore @Test
-	public void testUpdate_DeleteLinks_Mixuture(){
-		List<Link> linksToDelete = new ArrayList<Link>();
-		linksToDelete.add(createFeasibleLink());
-		linksToDelete.add(createExistingLink());
-		
-		// Test deletion of mixture of new/existing links
-		linkStorage.update(linksToDelete, ILinkStorage.DM_OPERATION.DELETE);
-		doTestLinkNotExist(createFeasibleLink());
-		doTestLinkNotExist(createExistingLink());
-	}
-	
-	// TODO: remove @Ignore after UPDATE method is implemented
-	/**
-	 * Test if updateLink() can correctly updates LinkInfo for a Link.
-	 */
-	@Ignore @Test
-	public void testUpdateLink_Update() {
-		Link linkToUpdate= createExistingLink();
-		long currentTime = System.currentTimeMillis();
-		LinkInfo infoToUpdate = createFeasibleLinkInfo(currentTime);
-		LinkInfo infoToVerify = createFeasibleLinkInfo(currentTime);
-
-		linkStorage.updateLink(linkToUpdate, infoToUpdate, ILinkStorage.DM_OPERATION.UPDATE);
-		
-		doTestLinkHasStateOf(linkToUpdate, infoToVerify);
-	}
-	
-	/**
-	 * Test if updateLink() can correctly creates a Link.
-	 */
-	@Test
-	public void testUpdateLink_Create() {
-		Link linkToCreate = createFeasibleLink();
-		Link linkToVerify = createFeasibleLink();
-		
-		//Use the link storage API to add the link
-		linkStorage.updateLink(linkToCreate, null, ILinkStorage.DM_OPERATION.CREATE);
-		doTestLinkExist(linkToVerify);
-	}
-	
-	/**
-	 * Test if updateLink() can correctly inserts a Link.
-	 */
-	@Test
-	public void testUpdateLink_Insert() {
-		Link linkToInsert = createFeasibleLink();
-		Link linkToVerify = createFeasibleLink();
-		
-		//Use the link storage API to add the link
-		linkStorage.updateLink(linkToInsert, null, ILinkStorage.DM_OPERATION.INSERT);
-
-		doTestLinkExist(linkToVerify);
-	}
-	
-	// TODO: Check if addOrUpdateLink() should accept DELETE operation. If not, remove this test.
-	/**
-	 * Test if updateLink() can correctly deletes a Link.
-	 */
-	@Ignore @Test
-	public void testUpdateLink_Delete() {
-		Link linkToDelete = createExistingLink();
-		Link linkToVerify = createExistingLink();
-
-		// Test deletion of existing link
-		linkStorage.updateLink(linkToDelete, null, DM_OPERATION.DELETE);
-		doTestLinkNotExist(linkToVerify);
-		
-		linkToDelete = createFeasibleLink();
-		linkToVerify = createFeasibleLink();
-
-		// Test deletion of not-existing link
-		linkStorage.updateLink(linkToDelete, null, DM_OPERATION.DELETE);
-		doTestLinkNotExist(linkToVerify);
-	}
-	
-	/**
-	 * Test if getLinks() can correctly return Links connected to specific DPID and port.
-	 */
-	@Test
-	public void testGetLinks_ByDpidPort(){
-		Link linkToVerify = createExistingLink();
-		Long dpid = linkToVerify.getSrc();
-		short port = (short)linkToVerify.getSrcPort();
-		
-		List<Link> list = linkStorage.getLinks(dpid, port);
-		
-		assertEquals(list.size(), 1);
-		
-		Link l = list.get(0);
-		assertEquals(l.getSrc(), linkToVerify.getSrc());
-		assertEquals(l.getSrcPort(), linkToVerify.getSrcPort());
-		assertEquals(l.getDst(), linkToVerify.getDst());
-		assertEquals(l.getDstPort(), linkToVerify.getDstPort());
-		
-		Link linkToVerifyNot = createFeasibleLink();
-		
-		List<Link> list2 = linkStorage.getLinks(linkToVerifyNot.getSrc(), (short)linkToVerifyNot.getSrcPort());
-		
-		assertEquals(list2.size(), 0);
-	}
-	
-	/**
-	 * Test if getLinks() can correctly return Links connected to specific MAC address.
-	 */
-	@Test
-	public void testGetLinks_ByString() {
-		Link linkToVeryfy = createExistingLink();
-		String dpid = HexString.toHexString(linkToVeryfy.getSrc());
-		
-		List<Link> links = linkStorage.getLinks(dpid);
-		assertTrue(links.contains(linkToVeryfy));
-
-		Link linkToVerifyNot = createFeasibleLink();
-		assertFalse(links.contains(linkToVerifyNot));
-	}
-	
-	/**
-	 * Test if deleteLink() can correctly delete a Link.
-	 */
-	@Test
-	public void testDeleteLink() {
-		// Deletion of existing link
-		Link linkToDelete = createExistingLink();
-		Link linkToVerify = createExistingLink();
-		
-		linkStorage.deleteLink(linkToDelete);
-		doTestLinkNotExist(linkToVerify);
-	}
-	
-	/**
-	 * Test if deleteLinks() can correctly delete Links.
-	 */
-	@Test
-	public void testDeleteLinks(){
-		List<Link> linksToDelete = createExistingLinks();
-		List<Link> linksToVerify = createExistingLinks();
-		
-		linkStorage.deleteLinks(linksToDelete);
-		for(Link l : linksToVerify) {
-			doTestLinkNotExist(l);
-		}
-	}
-	
-	/**
-	 * Test if deleteLinks() can handle mixture of normal/abnormal input.
-	 */
-	@Ignore @Test
-	public void testDeleteLinks_Mixture(){
-		List<Link> linksToDelete = new ArrayList<Link>();
-		linksToDelete.add(createFeasibleLink());
-		linksToDelete.add(createExistingLink());
-		
-		// Test deletion of mixture of new/existing links
-		linkStorage.deleteLinks(linksToDelete);
-		doTestLinkNotExist(createFeasibleLink());
-		doTestLinkNotExist(createExistingLink());
-	}
-
-	/**
-	 * Test if getActiveLinks() can correctly return active Links.
-	 */
-	@Test
-	public void testGetActiveLinks() {
-		Link existingLink = createExistingLink();
-		Link notExistingLink = createFeasibleLink();
-
-		List<Link> links = linkStorage.getActiveLinks();
-		
-		assertTrue(links.contains(existingLink));
-		assertFalse(links.contains(notExistingLink));
-	}
-	
-	/**
-	 * Test if deleteLinksOnPort() can delete Links.
-	 */
-	@Test
-	public void testDeleteLinksOnPort() {
-		Link linkToDelete = createExistingLink();
-		Link linkToVerify = createExistingLink();
-		
-		linkStorage.deleteLinksOnPort(linkToDelete.getSrc(), linkToDelete.getSrcPort());
-		
-		doTestLinkNotExist(linkToVerify);
-	}
-
-	/**
-	 * Test if specific link is existing
-	 * @param link 
-	 */
-	private void doTestLinkExist(Link link) {
-		assertTrue(ope.hasLinkBetween(HexString.toHexString(link.getSrc()),
-				link.getSrcPort(),
-				HexString.toHexString(link.getDst()),
-				link.getDstPort()));
-	}
-	
-	/**
-	 * Test if titanGraph doesn't have specific link
-	 * @param link
-	 */
-	private void doTestLinkNotExist(Link link) {
-		assertFalse(ope.hasLinkBetween(HexString.toHexString(link.getSrc()),
-				link.getSrcPort(),
-				HexString.toHexString(link.getDst()),
-				link.getDstPort()));
-	}
-	
-	/**
-	 * Test if titanGraph has specific Link with specific LinkInfo
-	 * @param link 
-	 */
-	private void doTestLinkHasStateOf(Link link, LinkInfo info) {
-	}
-	
-	//----------------- Creation of test data -----------------------
-	// Assume a network shown below.
-	//
-	// [dpid1]--+--[port:1]----[port:1]--+--[dpid2]
-	//          |                        |
-	//          +--[port:2]    [port:2]--+
-	//          |
-	//          +--[port:3]    [port:1]--+--[dpid3]
-	//          |                        |
-	//          +--[port:4]----[port:2]--+
-	//
-	// dpid1 : 00:00:00:00:0a:01
-	// dpid2 : 00:00:00:00:0a:02
-	// dpid3 : 00:00:00:00:0a:03
-	
-	private void initLinks() {
-		final String dpid1 = "00:00:00:00:0a:01";
-		final String dpid2 = "00:00:00:00:0a:02";
-		final String dpid3 = "00:00:00:00:0a:03";
-		
-		ope.createNewSwitchForTest(dpid1).setStateForTest("ACTIVE");
-		ope.createNewSwitchForTest(dpid2).setStateForTest("ACTIVE");
-		ope.createNewSwitchForTest(dpid3).setStateForTest("ACTIVE");
-
-		TestPortObject ports1 [] = {
-				ope.createNewPortForTest(dpid1, (short)1),
-				ope.createNewPortForTest(dpid1, (short)2),
-				ope.createNewPortForTest(dpid1, (short)3),
-				ope.createNewPortForTest(dpid1, (short)4),
-		};
-
-		TestPortObject ports2 [] = {
-				ope.createNewPortForTest(dpid2, (short)1),
-				ope.createNewPortForTest(dpid2, (short)2),
-		};
-
-		TestPortObject ports3 [] = {
-				ope.createNewPortForTest(dpid3, (short)1),
-				ope.createNewPortForTest(dpid3, (short)2),
-		};
-		
-		ope.setLinkBetweenPortsForTest(ports1[0], ports2[0]);
-		ope.setLinkBetweenPortsForTest(ports1[3], ports3[1]);
-	}
-	
-	/**
-	 * Returns new Link object of existing link
-	 * @return new Link object
-	 */
-	private Link createExistingLink() {
-		return new Link(Long.decode("0x0000000000000a01"), 1, Long.decode("0x0000000000000a02"), 1);
-	}
-	
-	/**
-	 * Returns new Link object of not-existing but feasible link
-	 * @return new Link object
-	 */
-	private Link createFeasibleLink() {
-		return new Link(Long.decode("0x0000000000000a01"), 3, Long.decode("0x0000000000000a03"), 1);
-	}
-	
-	// make NO sense while test-network data doesn't define physical network (i.e. any link is feasible)
-	@SuppressWarnings("unused")
-	private Link createInfeasibleLink() {
-		return new Link(Long.decode("0x0000000000000a01"), 1, Long.decode("0x0000000000000a03"), 3);
-	}
-
-	/**
-	 * Returns list of Link objects which all has information of existing link in titanGraph
-	 * @return ArrayList of new Link objects
-	 */
-	private List<Link> createExistingLinks() {
-		List<Link> links = new ArrayList<Link>();
-		links.add(new Link(Long.decode("0x0000000000000a01"), 1, Long.decode("0x0000000000000a02"), 1));
-		links.add(new Link(Long.decode("0x0000000000000a01"), 4, Long.decode("0x0000000000000a03"), 2));
-		return links;
-	}
-	
-	/**
-	 * Returns list of Link objects which all has information of not-existing but feasible link
-	 * @return ArrayList of new Link objects
-	 */
-	private List<Link> createFeasibleLinks() {
-		List<Link> links = new ArrayList<Link>();
-		links.add(new Link(Long.decode("0x0000000000000a01"), 2, Long.decode("0x0000000000000a02"), 2));
-		links.add(new Link(Long.decode("0x0000000000000a01"), 3, Long.decode("0x0000000000000a03"), 1));
-		return links;
-	}
-	
-	/**
-	 * Returns new LinkInfo object with convenient values.
-	 * @return LinkInfo object
-	 */
-	private LinkInfo createFeasibleLinkInfo(long time) {
-		long time_first = time;
-		long time_last_lldp = time + 50;
-		long time_last_bddp = time + 100;
-		int state_src = OFPhysicalPort.OFPortState.OFPPS_STP_FORWARD.getValue();
-		int state_dst = OFPhysicalPort.OFPortState.OFPPS_STP_LISTEN.getValue();
-
-		return new LinkInfo(time_first,
-				time_last_lldp,
-				time_last_bddp,
-				state_src,
-				state_dst);
-	}
-	//---------------------------------------------------------------
-}
diff --git a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/TestableGraphDBOperation.java b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/TestableGraphDBOperation.java
deleted file mode 100644
index e3ad879..0000000
--- a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/TestableGraphDBOperation.java
+++ /dev/null
@@ -1,1500 +0,0 @@
-package net.floodlightcontroller.linkdiscovery.internal;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.codehaus.jackson.annotate.JsonIgnore;
-import org.codehaus.jackson.annotate.JsonProperty;
-import org.codehaus.jackson.map.annotate.JsonSerialize;
-import org.easymock.EasyMock;
-import org.openflow.util.HexString;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.tinkerpop.blueprints.Direction;
-import com.tinkerpop.blueprints.Vertex;
-import com.tinkerpop.frames.Adjacency;
-import com.tinkerpop.frames.Incidence;
-import com.tinkerpop.frames.Property;
-import com.tinkerpop.frames.annotations.gremlin.GremlinGroovy;
-import com.tinkerpop.frames.annotations.gremlin.GremlinParam;
-
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
-import net.onrc.onos.ofcontroller.flowcache.web.DatapathSummarySerializer;
-import net.onrc.onos.ofcontroller.util.FlowEntryId;
-import net.onrc.onos.ofcontroller.util.FlowId;
-import net.onrc.onos.util.GraphDBConnection;
-import net.onrc.onos.util.GraphDBOperation;
-import net.onrc.onos.util.IDBConnection;
-
-/**
- * Mock class of GraphDBOperation which provides additional setter to construct a graph for test.
- * This object simply caches parameters set up by override interfaces and reflect them when commit().
- * *ForTest() methods are exempt from cache, parameters through those methods are reflected soon.
- * @author Naoki Shiota
- *
- */
-public class TestableGraphDBOperation extends GraphDBOperation {
-	protected static Logger log = LoggerFactory.getLogger(TestableGraphDBOperation.class);
-
-	protected List<TestSwitchObject> switches;
-	protected List<TestPortObject> ports;
-	protected List<TestDeviceObject> devices;
-	protected List<TestFlowPath> paths;
-	protected List<TestFlowEntry> entries;
-
-	protected List<TestSwitchObject> switchesToAdd;
-	protected List<TestPortObject> portsToAdd;
-	protected List<TestDeviceObject> devicesToAdd;
-	protected List<TestFlowPath> pathsToAdd;
-	protected List<TestFlowEntry> entriesToAdd;
-
-	protected List<TestSwitchObject> switchesToRemove;
-	protected List<TestPortObject> portsToRemove;
-	protected List<TestDeviceObject> devicesToRemove;
-	protected List<TestFlowPath> pathsToRemove;
-	protected List<TestFlowEntry> entriesToRemove;
-
-	// Testable implementations of INetMapTopologyObject interfaces
-
-	public static class TestSwitchObject implements ISwitchObject {
-		private String state,type,dpid;
-		private List<IPortObject> ports;
-		private List<IDeviceObject> devices;
-		private List<IFlowEntry> entries;
-
-		private String stateToUpdate, typeToUpdate, dpidToUpdate;
-		private List<IPortObject> portsToAdd;
-		private List<IPortObject> portsToRemove;
-
-		public TestSwitchObject() {
-			type = "switch";
-			
-			ports = new ArrayList<IPortObject>();
-			portsToAdd = new ArrayList<IPortObject>();
-			portsToRemove = new ArrayList<IPortObject>();
-			devices = new ArrayList<IDeviceObject>();
-			entries = new ArrayList<IFlowEntry>();
-			
-			clearUncommitedData();
-		}
-		
-		public void commit() {
-			for(IPortObject port : portsToAdd) {
-				ports.add(port);
-			}
-			for(IPortObject port : portsToRemove) {
-				ports.remove(port);
-			}
-			if(stateToUpdate != null) { state = stateToUpdate; }
-			if(typeToUpdate != null) { type = typeToUpdate; }
-			if(dpidToUpdate != null) { dpid = dpidToUpdate; }
-
-			clearUncommitedData();
-		}
-		
-		public void rollback() {
-			clearUncommitedData();
-		}
-		
-		public void clearUncommitedData() {
-			portsToAdd.clear();
-			portsToRemove.clear();
-			stateToUpdate = typeToUpdate = dpidToUpdate = null;
-		}
-		
-		public void setStateForTest(String state) { this.state = state; }
-		public void setTypeForTest(String type) { this.type = type; }
-		public void setDpidForTest(String dpid) { this.dpid = dpid; }
-		public void addPortForTest(TestPortObject port) { ports.add(port);  }
-		public void addDeviceForTest(TestDeviceObject dev) { devices.add(dev); }
-		public void addEntryForTest(TestFlowEntry entry) { entries.add(entry); }
-		
-		@Override
-		@JsonProperty("state")
-		@Property("state")
-		public String getState() { return state; }
-	
-		@Override
-		@Property("state")
-		public void setState(String state) { this.stateToUpdate = state; }
-	
-		@Override
-		@JsonIgnore
-		@Property("type")
-		public String getType() { return type ; }
-	
-		@Override
-		@Property("type")
-		public void setType(String type) { this.typeToUpdate = type; }
-	
-		// Not support for test
-		@Override
-		public Vertex asVertex() { return null; }
-	
-		@Override
-		@JsonProperty("dpid")
-		@Property("dpid")
-		public String getDPID() { return dpid; }
-	
-		@Override
-		@Property("dpid")
-		public void setDPID(String dpid) { this.dpidToUpdate = dpid; }
-	
-		@Override
-		@JsonProperty("ports")
-		@Adjacency(label = "on")
-		public Iterable<IPortObject> getPorts() { return ports; }
-	
-		@Override
-		@JsonIgnore
-		@GremlinGroovy("_().out('on').has('number',port_num)")
-		public IPortObject getPort(@GremlinParam("port_num") short port_num) {
-			for(IPortObject port : ports) {
-				if(port.getNumber() == port_num) {
-					return port;
-				}
-			}
-			return null;
-		}
-	
-		@Override
-		@Adjacency(label = "on")
-		public void addPort(IPortObject port) { portsToAdd.add(port); }
-	
-		@Override
-		@Adjacency(label = "on")
-		public void removePort(IPortObject port) { portsToRemove.add(port); }
-	
-		@Override
-		@JsonIgnore
-		@GremlinGroovy("_().out('on').out('host')")
-		public Iterable<IDeviceObject> getDevices() { return devices; }
-	
-		@Override
-		@JsonIgnore
-		@Incidence(label = "switch", direction = Direction.IN)
-		public Iterable<IFlowEntry> getFlowEntries() { return entries; }
-	}
-	
-	public static class TestPortObject implements IPortObject {
-		private String state,type,desc;
-		private Short number;
-		private Integer port_state;
-		private ISwitchObject sw;
-		
-		private List<IPortObject> linkedPorts;
-		private List<IDeviceObject> devices;
-		private List<IFlowEntry> inflows,outflows;
-		
-		private String stateToUpdate,typeToUpdate,descToUpdate;
-		private Short numberToUpdate;
-		private Integer port_stateToUpdate;
-		
-		private List<IPortObject> linkedPortsToAdd;
-		private List<IPortObject> linkedPortsToRemove;
-		private List<IDeviceObject> devicesToAdd;
-		private List<IDeviceObject> devicesToRemove;
-		
-
-		public TestPortObject() {
-			type = "port";
-
-			linkedPorts = new ArrayList<IPortObject>();
-			linkedPortsToAdd = new ArrayList<IPortObject>();
-			linkedPortsToRemove = new ArrayList<IPortObject>();
-			devices = new ArrayList<IDeviceObject>();
-			devicesToAdd = new ArrayList<IDeviceObject>();
-			devicesToRemove = new ArrayList<IDeviceObject>();
-			inflows = new ArrayList<IFlowEntry>();
-			outflows = new ArrayList<IFlowEntry>();
-			
-			clearUncommitedData();
-		}
-		
-		public void commit() {
-			for(IPortObject port : linkedPortsToAdd) { linkedPorts.add(port); }
-			for(IPortObject port : linkedPortsToRemove) { linkedPorts.remove(port); }
-			for(IDeviceObject dev : devicesToAdd) { devices.add(dev); }
-			for(IDeviceObject dev : devicesToRemove) { devices.remove(dev); }
-			
-			if(stateToUpdate != null) { state = stateToUpdate; }
-			if(typeToUpdate != null) { type = typeToUpdate; }
-			if(descToUpdate != null) { desc = descToUpdate; }
-			if(numberToUpdate != null) { number = numberToUpdate; }
-			if(port_stateToUpdate != null) { port_state = port_stateToUpdate; }
-			
-			clearUncommitedData();
-		}
-		
-		public void rollback() {
-			clearUncommitedData();
-		}
-		
-		public void clearUncommitedData() {
-			linkedPortsToAdd.clear();
-			linkedPortsToRemove.clear();
-			devicesToAdd.clear();
-			devicesToRemove.clear();
-			stateToUpdate = typeToUpdate = descToUpdate = null;
-			port_stateToUpdate = null;
-			numberToUpdate = null;
-		}
-		
-		// Setter methods for test
-		public void setStateForTest(String state) { this.state = state; }
-		public void setTypeForTest(String type) { this.type = type; }
-		public void setDescForTest(String desc) { this.desc = desc; }
-		public void setNumberForTest(Short number) { this.number = number; }
-		public void setPortStateForTest(Integer state) { this.port_state = state; }
-		public void setSwitchForTest(ISwitchObject sw) { this.sw = sw; }
-		public void addLinkedPortForTest(TestPortObject port) { this.linkedPorts.add(port); }
-		public void addInflowForTest(TestFlowEntry entry) { inflows.add(entry); }
-		public void addOutflowForTest(TestFlowEntry entry) { outflows.add(entry); }
-		
-		// Override methods for mock IPortObject
-		@Override
-		@JsonProperty("state")
-		@Property("state")
-		public String getState() { return state; }
-
-		@Override
-		@Property("state")
-		public void setState(String state) { this.stateToUpdate = state; }
-
-		@Override
-		@JsonIgnore
-		@Property("type")
-		public String getType() { return type; }
-
-		@Override
-		@Property("type")
-		public void setType(String type) { this.typeToUpdate = type; }
-
-		// not support for test
-		@Override
-		public Vertex asVertex() {
-			return null;
-		}
-
-		@Override
-		@JsonProperty("number")
-		@Property("number")
-		public Short getNumber() { return number; }
-
-		@Override
-		@Property("number")
-		public void setNumber(Short n) { this.numberToUpdate = n; }
-
-		@Override
-		@JsonProperty("desc")
-		@Property("desc")
-		public String getDesc() { return desc; }
-
-		@Override
-		@Property("desc")
-		public void setDesc(String s) { this.descToUpdate = s; }
-
-		@Override
-		@JsonIgnore
-		@Property("port_state")
-		public Integer getPortState() { return port_state; }
-
-		@Override
-		@Property("port_state")
-		public void setPortState(Integer s) { this.port_stateToUpdate = s; }
-
-		@Override
-		@JsonIgnore
-		@Incidence(label = "on", direction = Direction.IN)
-		public ISwitchObject getSwitch() { return sw; }
-
-		@Override
-		@JsonProperty("devices")
-		@Adjacency(label = "host")
-		public Iterable<IDeviceObject> getDevices() { return devices; }
-
-		@Override
-		@Adjacency(label = "host")
-		public void setDevice(IDeviceObject device) { devicesToAdd.add(device); }
-
-		@Override
-		@Adjacency(label = "host")
-		public void removeDevice(IDeviceObject device) { devicesToRemove.add(device); }
-
-		@Override
-		@JsonIgnore
-		@Incidence(label = "inport", direction = Direction.IN)
-		public Iterable<IFlowEntry> getInFlowEntries() { return inflows; }
-
-		@Override
-		@JsonIgnore
-		@Incidence(label = "outport", direction = Direction.IN)
-		public Iterable<IFlowEntry> getOutFlowEntries() { return outflows; }
-
-		@Override
-		@JsonIgnore
-		@Adjacency(label = "link")
-		public Iterable<IPortObject> getLinkedPorts() { return linkedPorts; }
-
-		@Override
-		@Adjacency(label = "link")
-		public void removeLink(IPortObject dest_port) { linkedPortsToRemove.add(dest_port); }
-
-		@Override
-		@Adjacency(label = "link")
-		public void setLinkPort(IPortObject dest_port) { linkedPortsToAdd.add(dest_port); }
-	}
-		
-	public static class TestDeviceObject implements IDeviceObject {
-		private String state,type,mac,ipaddr;
-		private List<IPortObject> ports;
-		private List<ISwitchObject> switches;
-		
-		private String stateToUpdate,typeToUpdate,macToUpdate,ipaddrToUpdate;
-		private List<IPortObject> portsToAdd;
-		private List<IPortObject> portsToRemove;
-	
-		public TestDeviceObject() {
-			type = "device";
-			
-			ports = new ArrayList<IPortObject>();
-			portsToAdd = new ArrayList<IPortObject>();
-			portsToRemove = new ArrayList<IPortObject>();
-			switches = new ArrayList<ISwitchObject>();
-			
-			clearUncommitedData();
-		}
-		
-		public void commit() {
-			for(IPortObject port : portsToAdd) {
-				ports.add(port);
-			}
-			for(IPortObject port : portsToRemove) {
-				ports.remove(port);
-			}
-			
-			if(stateToUpdate != null) { state = stateToUpdate; }
-			if(typeToUpdate != null) { type = typeToUpdate; }
-			if(macToUpdate != null) { mac = macToUpdate; }
-			if(ipaddrToUpdate != null) { ipaddr = ipaddrToUpdate; }
-			
-			clearUncommitedData();
-		}
-		
-		public void rollback() {
-			clearUncommitedData();
-		}
-		
-		public void clearUncommitedData() {
-			ports.clear();
-			portsToAdd.clear();
-			portsToRemove.clear();
-			
-			stateToUpdate = typeToUpdate = macToUpdate = ipaddrToUpdate = null;
-		}
-		
-		// Setter methods for test
-		public void setStateForTest(String state) { this.state = state; }
-		public void setTypeForTest(String type) { this.type = type; }
-		public void setMacForTest(String mac) { this.mac = mac; }
-		public void setIpaddrForTest(String ipaddr) { this.ipaddr = ipaddr; }
-		public void addSwitchForTest(ISwitchObject sw) { switches.add(sw); }
-		public void addPortForTest(IPortObject port) { ports.add(port); }
-		
-		
-		// Override methods
-		@Override
-		@JsonProperty("state")
-		@Property("state")
-		public String getState() { return state; }
-	
-		@Override
-		@Property("state")
-		public void setState(String state) { stateToUpdate = state; }
-	
-		@Override
-		@JsonIgnore
-		@Property("type")
-		public String getType() { return type; }
-	
-		@Override
-		@Property("type")
-		public void setType(String type) { typeToUpdate = type; }
-	
-		@Override
-		public Vertex asVertex() {
-			// TODO Auto-generated method stub
-			return null;
-		}
-	
-		@Override
-		@JsonProperty("mac")
-		@Property("dl_addr")
-		public String getMACAddress() { return mac; }
-	
-		@Override
-		@Property("dl_addr")
-		public void setMACAddress(String macaddr) { macToUpdate = macaddr; }
-	
-		@Override
-		@JsonProperty("ipv4")
-		@Property("nw_addr")
-		public String getIPAddress() { return ipaddr; }
-	
-		@Override
-		@Property("dl_addr")
-		public void setIPAddress(String ipaddr) { ipaddrToUpdate = ipaddr; }
-	
-		@Override
-		@JsonIgnore
-		@Incidence(label = "host", direction = Direction.IN)
-		public Iterable<IPortObject> getAttachedPorts() {
-			return ports; }
-	
-		@Override
-		@JsonIgnore
-		@Incidence(label = "host", direction = Direction.IN)
-		public void setHostPort(IPortObject port) { portsToAdd.add(port); }
-	
-		@Override
-		@JsonIgnore
-		@Incidence(label = "host", direction = Direction.IN)
-		public void removeHostPort(IPortObject port) { portsToRemove.add(port); }
-	
-		@Override
-		@JsonIgnore
-		@GremlinGroovy("_().in('host').in('on')")
-		public Iterable<ISwitchObject> getSwitch() { return switches; }
-	}
-	
-	public static class TestFlowPath implements IFlowPath {
-		private String state,type,flowId,installerId,srcSw,dstSw;
-		private String dataPathSummary,userState;
-		private String matchSrcMac,matchDstMac,matchSrcIpaddr,matchDstIpaddr;
-		private Short srcPort,dstPort,matchEthernetFrameType;
-		
-		private List<IFlowEntry> entries;
-		private List<ISwitchObject> switches;
-
-		private String stateToUpdate,typeToUpdate,flowIdToUpdate,installerIdToUpdate,srcSwToUpdate,dstSwToUpdate;
-		private String dataPathSummaryToUpdate,userStateToUpdate;
-		private String matchSrcMacToUpdate,matchDstMacToUpdate,matchSrcIpaddrToUpdate,matchDstIpaddrToUpdate;
-		private Short srcPortToUpdate,dstPortToUpdate,matchEthernetFrameTypeToUpdate;
-
-		private List<IFlowEntry> flowsToAdd;
-		private List<IFlowEntry> flowsToRemove;
-
-		public TestFlowPath() {
-			type = "flow";
-			
-			entries = new ArrayList<IFlowEntry>();
-			flowsToAdd = new ArrayList<IFlowEntry>();
-			flowsToRemove = new ArrayList<IFlowEntry>();
-			
-			switches = new ArrayList<ISwitchObject>();
-			
-			clear();
-		}
-		
-		public void commit() {
-			for(IFlowEntry flow : flowsToAdd) {
-				entries.add(flow);
-			}
-			for(IFlowEntry flow : flowsToRemove) {
-				entries.remove(flow);
-			}
-			if(stateToUpdate != null) { state = stateToUpdate; }
-			if(typeToUpdate != null) { type = typeToUpdate; }
-			if(flowIdToUpdate != null) { flowId = flowIdToUpdate; }
-			if(installerIdToUpdate != null) { installerId = installerIdToUpdate; }
-			if(srcSwToUpdate != null) { srcSw = srcSwToUpdate; }
-			if(dstSwToUpdate != null) { dstSw = dstSwToUpdate; }
-			if(dataPathSummaryToUpdate != null) { dataPathSummary = dataPathSummaryToUpdate; }
-			if(userStateToUpdate != null) { userState = userStateToUpdate; }
-			if(matchSrcMacToUpdate != null) { matchSrcMac = matchSrcMacToUpdate; }
-			if(matchDstMacToUpdate != null) { matchDstMac = matchDstMacToUpdate; }
-			if(matchSrcIpaddrToUpdate != null) { matchSrcIpaddr = matchSrcIpaddrToUpdate; }
-			if(matchDstIpaddrToUpdate != null) { matchDstIpaddr = matchDstIpaddrToUpdate; }
-			if(srcPortToUpdate != null) { srcPort = srcPortToUpdate; }
-			if(dstPortToUpdate != null) { dstPort = dstPortToUpdate; }
-			if(matchEthernetFrameTypeToUpdate != null) { matchEthernetFrameType = matchEthernetFrameTypeToUpdate; }
-		}
-		
-		public void rollback() {
-			clear();
-		}
-		
-		public void clear() {
-			flowsToAdd.clear();
-			flowsToRemove.clear();
-			
-			stateToUpdate = typeToUpdate = flowIdToUpdate = installerIdToUpdate = null;
-			srcSwToUpdate = dstSwToUpdate = dataPathSummaryToUpdate = userStateToUpdate = null;
-			matchSrcMacToUpdate = matchDstMacToUpdate = matchSrcIpaddrToUpdate = matchDstIpaddrToUpdate = null;
-			srcPortToUpdate = dstPortToUpdate = matchEthernetFrameTypeToUpdate = null;
-		}
-		
-		// Setter methods for test
-		public void setStateForTest(String state) { this.state = state; }
-		public void setTypeForTest(String type) { this.type = type; }
-		public void setFlowIdForTest(String flowId) { this.flowId = flowId; }
-		public void setInstallerIdForTest(String installerId) { this.installerId = installerId; }
-		public void setSrcSwForTest(String srcSw) { this.srcSw = srcSw; }
-		public void setDstSwForTest(String dstSw) { this.dstSw = dstSw; }
-		public void setDataPathSummaryForTest(String dataPathSummary) { this.dataPathSummary = dataPathSummary; }
-		public void setUserStateForTest(String userState) { this.userState = userState; }
-		public void setMatchSrcMacForTest(String matchSrcMac) { this.matchSrcMac = matchSrcMac; }
-		public void setMatchDstMacForTest(String matchDstMac) { this.matchDstMac = matchDstMac; }
-		public void setMatchSrcIpaddrForTest(String matchSrcIpaddr) { this.matchSrcIpaddr = matchSrcIpaddr; }
-		public void setMatchDstIpaddrForTest(String matchDstIpaddr) { this.matchDstIpaddr = matchDstIpaddr; }
-		public void setSrcPortForTest(Short srcPort) { this.srcPort = srcPort; }
-		public void setDstPortForTest(Short dstPort) { this.dstPort = dstPort; }
-		public void setMatchEthernetFrameTypeForTest(Short matchEthernetFrameType) { this.matchEthernetFrameType = matchEthernetFrameType; }
-		public void addFlowEntryForTest(IFlowEntry entry) { entries.add(entry); }
-		public void addSwitchForTest(ISwitchObject sw) { switches.add(sw); }
-
-		@Override
-		@JsonProperty("state")
-		@Property("state")
-		public String getState() { return state; }
-
-		@Override
-		@Property("state")
-		public void setState(String state) { stateToUpdate = state; }
-
-		@Override
-		@JsonIgnore
-		@Property("type")
-		public String getType() { return type; }
-
-		@Override
-		@Property("type")
-		public void setType(String type) { typeToUpdate = type; }
-
-		@Override
-		public Vertex asVertex() {
-			// TODO Auto-generated method stub
-			return null;
-		}
-
-		@Override
-		@JsonProperty("flowId")
-		@Property("flow_id")
-		public String getFlowId() { return flowId; }
-
-		@Override
-		@Property("flow_id")
-		public void setFlowId(String flowId) { flowIdToUpdate = flowId; }
-
-		@Override
-		@JsonProperty("installerId")
-		@Property("installer_id")
-		public String getInstallerId() { return installerId; }
-
-		@Override
-		@Property("installer_id")
-		public void setInstallerId(String installerId) { installerIdToUpdate = installerId; }
-
-		@Override
-		@JsonProperty("srcDpid")
-		@Property("src_switch")
-		public String getSrcSwitch() { return srcSw; }
-
-		@Override
-		@Property("src_switch")
-		public void setSrcSwitch(String srcSwitch) { srcSwToUpdate = srcSwitch; }
-
-		@Override
-		@JsonProperty("srcPort")
-		@Property("src_port")
-		public Short getSrcPort() { return srcPort; }
-
-		@Override
-		@Property("src_port")
-		public void setSrcPort(Short srcPort) { srcPortToUpdate = srcPort; }
-
-		@Override
-		@JsonProperty("dstDpid")
-		@Property("dst_switch")
-		public String getDstSwitch() { return dstSw; }
-
-		@Override
-		@Property("dst_switch")
-		public void setDstSwitch(String dstSwitch) { dstSwToUpdate = dstSwitch; }
-
-		@Override
-		@JsonProperty("dstPort")
-		@Property("dst_port")
-		public Short getDstPort() { return dstPort; }
-
-		@Override
-		@Property("dst_port")
-		public void setDstPort(Short dstPort) { dstPortToUpdate = dstPort; }
-
-		@Override
-		@JsonProperty("dataPath")
-		@JsonSerialize(using = DatapathSummarySerializer.class)
-		@Property("data_path_summary")
-		public String getDataPathSummary() { return dataPathSummary; }
-
-		@Override
-		@Property("data_path_summary")
-		public void setDataPathSummary(String dataPathSummary) { dataPathSummaryToUpdate = dataPathSummary; }
-
-		@Override
-		@JsonIgnore
-		@Adjacency(label = "flow", direction = Direction.IN)
-		public Iterable<IFlowEntry> getFlowEntries() { return entries; }
-
-		@Override
-		@Adjacency(label = "flow", direction = Direction.IN)
-		public void addFlowEntry(IFlowEntry flowEntry) {
-			if(! entries.contains(flowEntry)) {
-				flowsToAdd.add(flowEntry);
-			}
-		}
-
-		@Override
-		@Adjacency(label = "flow", direction = Direction.IN)
-		public void removeFlowEntry(IFlowEntry flowEntry) {
-			if(entries.contains(flowEntry)) {
-				flowsToAdd.add(flowEntry);
-			}
-		}
-
-		@Override
-		@JsonIgnore
-		@Property("matchEthernetFrameType")
-		public Short getMatchEthernetFrameType() { return matchEthernetFrameType; }
-
-		@Override
-		@Property("matchEthernetFrameType")
-		public void setMatchEthernetFrameType(Short matchEthernetFrameType) {
-			matchEthernetFrameTypeToUpdate = matchEthernetFrameType; }
-
-		@Override
-		@JsonIgnore
-		@Property("matchSrcMac")
-		public String getMatchSrcMac() { return matchSrcMac; }
-
-		@Override
-		@Property("matchSrcMac")
-		public void setMatchSrcMac(String matchSrcMac) { matchSrcMacToUpdate = matchSrcMac; }
-
-		@Override
-		@JsonIgnore
-		@Property("matchDstMac")
-		public String getMatchDstMac() { return matchDstMac; }
-
-		@Override
-		@Property("matchDstMac")
-		public void setMatchDstMac(String matchDstMac) { matchDstMacToUpdate = matchDstMac; }
-
-		@Override
-		@JsonIgnore
-		@Property("matchSrcIPv4Net")
-		public String getMatchSrcIPv4Net() { return matchSrcIpaddr; }
-
-		@Override
-		@Property("matchSrcIPv4Net")
-		public void setMatchSrcIPv4Net(String matchSrcIPv4Net) {
-			matchSrcIpaddrToUpdate = matchSrcIPv4Net; }
-
-		@Override
-		@JsonIgnore
-		@Property("matchDstIPv4Net")
-		public String getMatchDstIPv4Net() { return matchDstIpaddr; }
-
-		@Override
-		@Property("matchDstIPv4Net")
-		public void setMatchDstIPv4Net(String matchDstIPv4Net) {
-			matchDstIpaddrToUpdate = matchDstIPv4Net; }
-
-		@Override
-		@JsonIgnore
-		@GremlinGroovy("_().in('flow').out('switch')")
-		public Iterable<ISwitchObject> getSwitches() { return switches; }
-
-		@Override
-		@JsonIgnore
-		@Property("user_state")
-		public String getUserState() { return userState; }
-
-		@Override
-		@Property("user_state")
-		public void setUserState(String userState) { userStateToUpdate = userState; }
-	}
-
-	public static class TestFlowEntry implements IFlowEntry {
-		private String state,type,entryId,dpid,userState,switchState,errorStateType,errorStateCode;
-		private String matchSrcMac,matchDstMac,matchSrcIpaddr,matchDstIpaddr;
-		private Short matchInPort,matchEtherFrameType,actionOutput;
-		
-		private IFlowPath flowPath;
-		private ISwitchObject sw;
-		private IPortObject inport,outport;
-	
-		private String stateToUpdate,typeToUpdate,entryIdToUpdate,dpidToUpdate,
-			userStateToUpdate,switchStateToUpdate,errorStateTypeToUpdate,errorStateCodeToUpdate;
-		private String matchSrcMacToUpdate,matchDstMacToUpdate,matchSrcIpaddrToUpdate,matchDstIpaddrToUpdate;
-	
-		private Short matchInPortToUpdate,matchEtherFrameTypeToUpdate,actionOutputToUpdate;
-	
-		private IFlowPath flowPathToUpdate;
-		private ISwitchObject swToUpdate;
-		private IPortObject inportToUpdate,outportToUpdate;
-	
-		public TestFlowEntry() {
-			type = "flow_entry";
-			
-			clearUncommitedData();
-		}
-		
-		public void commit() {
-			if(stateToUpdate != null) { state = stateToUpdate; }
-			if(typeToUpdate != null) { type = typeToUpdate; }
-			if(entryIdToUpdate != null) { entryId = entryIdToUpdate; }
-			if(dpidToUpdate != null) { dpid = dpidToUpdate; }
-			if(userStateToUpdate != null) { userState = userStateToUpdate; }
-			if(switchStateToUpdate != null) { switchState = switchStateToUpdate; }
-			if(errorStateTypeToUpdate != null) { errorStateType = errorStateTypeToUpdate; }
-			if(errorStateCodeToUpdate != null) { errorStateCode = errorStateCodeToUpdate; }
-			if(matchSrcMacToUpdate != null) { matchSrcMac = matchSrcMacToUpdate; }
-			if(matchDstMacToUpdate != null) { matchDstMac = matchDstMacToUpdate; }
-			if(matchSrcIpaddrToUpdate != null) { matchSrcIpaddr = matchSrcIpaddrToUpdate; }
-			if(matchDstIpaddrToUpdate != null) { matchDstIpaddr = matchDstIpaddrToUpdate; }
-			if(matchInPortToUpdate != null) { matchInPort = matchInPortToUpdate; }
-			if(matchEtherFrameTypeToUpdate != null) { matchEtherFrameType = matchEtherFrameTypeToUpdate; }
-			if(actionOutputToUpdate != null) { actionOutput = actionOutputToUpdate; }
-			
-			if(flowPathToUpdate != null) { flowPath = flowPathToUpdate; }
-			if(swToUpdate != null) { sw = swToUpdate; }
-			if(inportToUpdate != null) { inport = inportToUpdate; }
-			if(outportToUpdate != null) { outport = outportToUpdate; }
-	
-			clearUncommitedData();
-		}
-		
-		public void rollback() {
-			clearUncommitedData();
-		}
-		
-		public void clearUncommitedData() {
-			stateToUpdate = typeToUpdate = entryIdToUpdate = dpidToUpdate = null;
-			userStateToUpdate = switchStateToUpdate = errorStateTypeToUpdate = errorStateCodeToUpdate = null;
-			matchSrcMacToUpdate = matchDstMacToUpdate = matchSrcIpaddrToUpdate = matchDstIpaddrToUpdate = null;
-			matchInPortToUpdate = matchEtherFrameTypeToUpdate = actionOutputToUpdate = null;
-			flowPathToUpdate = null;
-			swToUpdate = null;
-			inportToUpdate = outportToUpdate = null;
-		}
-		
-		// Setter methods for test
-		public void setStateForTest(String state) { this.state = state; }
-		public void setTypeForTest(String type) { this.type = type; }
-		public void setEntryIdForTest(String entryId) { this.entryId = entryId; }
-		public void setDpidForTest(String dpid) { this.dpid = dpid; }
-		public void setUserStateForTest(String userState) { this.userState = userState; }
-		public void setSwitchStateForTest(String switchState) { this.switchState = switchState; }
-		public void setErrorStateTypeForTest(String errorStateType) { this.errorStateType = errorStateType; }
-		public void setErrorStateCodeForTest(String errorStateCode) { this.errorStateCode = errorStateCode; }
-		public void setMatchSrcMacForTest(String matchSrcMac) { this.matchSrcMac = matchSrcMac; }
-		public void setMatchDstMacForTest(String matchDstMac) { this.matchDstMac = matchDstMac; }
-		public void setMatchSrcIpaddrForTest(String matchSrcIpaddr) { this.matchSrcIpaddr = matchSrcIpaddr; }
-		public void setMatchDstIpaddrForTest(String matchDstIpaddr) { this.matchDstIpaddr = matchDstIpaddr; }
-		public void setMatchInPortForTest(Short matchInPort) { this.matchInPort = matchInPort; }
-		public void setMatchEtherFrameTypeForTest(Short matchEtherFrameType) { this.matchEtherFrameType = matchEtherFrameType; }
-		public void setActionOutputForTest(Short actionOutput) { this.actionOutput = actionOutput; }
-		public void setFlowPathForTest(IFlowPath flowPath) { this.flowPath = flowPath; }
-		public void setSwitchForTest(ISwitchObject sw) { this.sw = sw; }
-		public void setInportForTest(IPortObject inport) { this.inport = inport; }
-		public void setOutportForTest(IPortObject outport) { this.outport = outport; }
-		
-		@Override
-		@JsonProperty("state")
-		@Property("state")
-		public String getState() { return state; }
-	
-		@Override
-		@Property("state")
-		public void setState(String state) { stateToUpdate = state; }
-	
-		@Override
-		@JsonIgnore
-		@Property("type")
-		public String getType() { return type; }
-	
-		@Override
-		@Property("type")
-		public void setType(String type) { typeToUpdate = type; }
-	
-		@Override
-		public Vertex asVertex() {
-			// TODO Auto-generated method stub
-			return null;
-		}
-	
-		@Override
-		@Property("flow_entry_id")
-		public String getFlowEntryId() { return entryId; }
-	
-		@Override
-		@Property("flow_entry_id")
-		public void setFlowEntryId(String flowEntryId) { entryIdToUpdate = flowEntryId; }
-	
-		@Override
-		@Property("switch_dpid")
-		public String getSwitchDpid() { return dpid; }
-	
-		@Override
-		@Property("switch_dpid")
-		public void setSwitchDpid(String switchDpid) { dpidToUpdate = switchDpid; }
-	
-		@Override
-		@Property("user_state")
-		public String getUserState() { return userState; }
-	
-		@Override
-		@Property("user_state")
-		public void setUserState(String userState) { userStateToUpdate = userState; }
-	
-		@Override
-		@Property("switch_state")
-		public String getSwitchState() { return switchState; }
-	
-		@Override
-		@Property("switch_state")
-		public void setSwitchState(String switchState) { switchStateToUpdate = switchState; }
-	
-		@Override
-		@Property("error_state_type")
-		public String getErrorStateType() { return errorStateType; }
-	
-		@Override
-		@Property("error_state_type")
-		public void setErrorStateType(String errorStateType) { errorStateTypeToUpdate = errorStateType; }
-	
-		@Override
-		@Property("error_state_code")
-		public String getErrorStateCode() { return errorStateCode; }
-	
-		@Override
-		@Property("error_state_code")
-		public void setErrorStateCode(String errorStateCode) { errorStateCodeToUpdate = errorStateCode; }
-	
-		@Override
-		@Property("matchInPort")
-		public Short getMatchInPort() { return matchInPort; }
-	
-		@Override
-		@Property("matchInPort")
-		public void setMatchInPort(Short matchInPort) { matchInPortToUpdate = matchInPort; }
-	
-		@Override
-		@Property("matchEthernetFrameType")
-		public Short getMatchEthernetFrameType() {return matchEtherFrameType; }
-	
-		@Override
-		@Property("matchEthernetFrameType")
-		public void setMatchEthernetFrameType(Short matchEthernetFrameType) { matchEtherFrameTypeToUpdate = matchEthernetFrameType; }
-		
-		@Override
-		@Property("matchSrcMac")
-		public String getMatchSrcMac() { return matchSrcMac; }
-	
-		@Override
-		@Property("matchSrcMac")
-		public void setMatchSrcMac(String matchSrcMac) { matchSrcMacToUpdate = matchSrcMac; }
-	
-		@Override
-		@Property("matchDstMac")
-		public String getMatchDstMac() { return matchDstMac; }
-	
-		@Override
-		@Property("matchDstMac")
-		public void setMatchDstMac(String matchDstMac) { matchDstMacToUpdate = matchDstMac; }
-	
-		@Override
-		@Property("matchSrcIPv4Net")
-		public String getMatchSrcIPv4Net() { return matchSrcIpaddr; }
-	
-		@Override
-		@Property("matchSrcIPv4Net")
-		public void setMatchSrcIPv4Net(String matchSrcIPv4Net) { matchSrcIpaddrToUpdate = matchSrcIPv4Net; }
-	
-		@Override
-		@Property("matchDstIPv4Net")
-		public String getMatchDstIPv4Net() { return matchDstIpaddr; }
-	
-		@Override
-		@Property("matchDstIPv4Net")
-		public void setMatchDstIPv4Net(String matchDstIPv4Net) { matchDstIpaddrToUpdate = matchDstIPv4Net; }
-	
-		@Override
-		@Property("actionOutput")
-		public Short getActionOutput() { return actionOutput; }
-	
-		@Override
-		@Property("actionOutput")
-		public void setActionOutput(Short actionOutput) { actionOutputToUpdate = actionOutput; }
-	
-		@Override
-		@Adjacency(label = "flow")
-		public IFlowPath getFlow() { return flowPath; }
-	
-		@Override
-		@Adjacency(label = "flow")
-		public void setFlow(IFlowPath flow) { flowPathToUpdate = flow; }
-	
-		@Override
-		@Adjacency(label = "switch")
-		public ISwitchObject getSwitch() { return sw; }
-	
-		@Override
-		@Adjacency(label = "switch")
-		public void setSwitch(ISwitchObject sw) { swToUpdate = sw; }
-	
-		@Override
-		@Adjacency(label = "inport")
-		public IPortObject getInPort() { return inport; }
-	
-		@Override
-		@Adjacency(label = "inport")
-		public void setInPort(IPortObject port) { inportToUpdate = port; }
-	
-		@Override
-		@Adjacency(label = "outport")
-		public IPortObject getOutPort() { return outport; }
-	
-		@Override
-		@Adjacency(label = "outport")
-		public void setOutPort(IPortObject port) { outportToUpdate = port; }
-	}
-
-
-	public TestableGraphDBOperation() {
-		super(EasyMock.createNiceMock(GraphDBConnection.class));
-		
-		switches = new ArrayList<TestSwitchObject>();
-		ports = new ArrayList<TestPortObject>();
-		devices = new ArrayList<TestDeviceObject>();
-		paths = new ArrayList<TestFlowPath>();
-		entries = new ArrayList<TestFlowEntry>();
-		
-		switchesToAdd = new ArrayList<TestSwitchObject>();
-		portsToAdd = new ArrayList<TestPortObject>();
-		devicesToAdd = new ArrayList<TestDeviceObject>();
-		pathsToAdd = new ArrayList<TestFlowPath>();
-		entriesToAdd = new ArrayList<TestFlowEntry>();
-
-		switchesToRemove = new ArrayList<TestSwitchObject>();
-		portsToRemove = new ArrayList<TestPortObject>();
-		devicesToRemove = new ArrayList<TestDeviceObject>();
-		pathsToRemove = new ArrayList<TestFlowPath>();
-		entriesToRemove = new ArrayList<TestFlowEntry>();
-		
-		clearUncommitedData();
-	}
-	
-	private void clearUncommitedData() {
-		for(TestFlowEntry flow : entries) {
-			flow.clearUncommitedData();
-		}
-		for(TestFlowEntry flow : entriesToAdd) {
-			flow.clearUncommitedData();
-		}
-		
-		for(TestDeviceObject dev : devices) {
-			dev.clearUncommitedData();
-		}
-		for(TestDeviceObject dev : devicesToAdd) {
-			dev.clearUncommitedData();
-		}
-		
-		for(TestSwitchObject sw : switches) {
-			sw.clearUncommitedData();
-		}
-		for(TestSwitchObject sw : switchesToAdd) {
-			sw.clearUncommitedData();
-		}
-		
-		for(TestPortObject port : ports) {
-			port.clearUncommitedData();
-		}
-		for(TestPortObject port : portsToAdd) {
-			port.clearUncommitedData();
-		}
-		
-		entriesToAdd.clear();
-		entriesToRemove.clear();
-		devicesToAdd.clear();
-		devicesToRemove.clear();
-		switchesToAdd.clear();
-		switchesToRemove.clear();
-		portsToAdd.clear();
-		portsToRemove.clear();
-	}
-	
-	
-	// this.*ForTest() methods below are supposed to be used for creation of test topology.
-	/**
-	 * Create new empty TestSwitchObject.
-	 * @return New TestSwitchObject
-	 */
-	public TestSwitchObject createNewSwitchForTest() {
-		TestSwitchObject sw = new TestSwitchObject();
-		switches.add(sw);
-		return sw;
-	}
-	
-	/**
-	 * Create new TestSwitchObject with specific DPID.
-	 * @param dpid DPID to be set
-	 * @return New TestSwitchObject
-	 */
-	public TestSwitchObject createNewSwitchForTest(String dpid) {
-		for(TestSwitchObject sw_loop : switches) {
-			if(sw_loop.getDPID().equals(dpid)) {
-				// Already created
-				log.error("switch already exists : " + dpid);
-				return sw_loop;
-			}
-		}
-
-		TestSwitchObject sw = new TestSwitchObject();
-		
-		sw.setDpidForTest(dpid);
-		switches.add(sw);
-		
-		return sw;
-	}
-	
-	/**
-	 * Create new empty TestPortObject.
-	 * @return New TestPortObject
-	 */
-	public TestPortObject createNewPortForTest() {
-		TestPortObject port = new TestPortObject();
-		ports.add(port);
-		return port;
-	}
-	
-	/**
-	 * Create new TestPortObject with specific DPID and port number.
-	 * @param dpid DPID to be set
-	 * @param number Port number to be set
-	 * @return New TestPortObject
-	 */
-	public TestPortObject createNewPortForTest(String dpid, Short number) {
-		TestSwitchObject sw = null;
-		
-		for(TestSwitchObject sw_loop : switches) {
-			if(sw_loop.getDPID().equals(dpid)) {
-				sw = sw_loop;
-			}
-		}
-		
-		if(sw != null) {
-			TestPortObject port = new TestPortObject();
-			port.setNumberForTest(number);
-			port.setSwitchForTest(sw);
-			sw.addPortForTest(port);
-			
-			ports.add(port);
-
-			return port;
-		} else {
-			return  null;
-		}
-	}
-	
-	/**
-	 * Link a TestPortObject to other TestPortObject.
-	 * @param src TestPortObjecgt of source port.
-	 * @param dst TestPortObjecgt of destination port.
-	 */
-	public void setLinkBetweenPortsForTest(TestPortObject src, TestPortObject dst) {
-		src.addLinkedPortForTest(dst);
-	}
-	
-	/**
-	 * Create new empty TestDeviceObject.
-	 * @return New TestDeviceObject
-	 */
-	public TestDeviceObject createNewDeviceForTest() {
-		TestDeviceObject dev = new TestDeviceObject();
-		
-		return dev;
-	}
-	
-	/**
-	 * Create new empty TestFlowPathObject.
-	 * @return New TestFlowPathObject
-	 */
-	public TestFlowPath createNewFlowPathForTest() {
-		TestFlowPath path = new TestFlowPath();
-		paths.add(path);
-		return path;
-	}
-
-	/**
-	 * Create new empty TestFlowEntryObject.
-	 * @return New TestFlowEntryObject
-	 */
-	public TestFlowEntry createNewFlowEntryForTest() {
-		TestFlowEntry entry = new TestFlowEntry();
-		entries.add(entry);
-		return entry;
-	}
-
-	
-	public boolean hasLinkBetween(String srcSw_str, Short srcNumber, String dstSw_str, Short dstNumber) {
-		IPortObject srcPort = null, dstPort = null;
-		long srcSw = HexString.toLong(srcSw_str);
-		long dstSw = HexString.toLong(dstSw_str);
-		
-		for(TestSwitchObject sw : switches) {
-			long swLong = HexString.toLong(sw.getDPID());
-			if(swLong == srcSw) {
-				for(IPortObject port : sw.getPorts()) {
-					if(port.getNumber().equals(srcNumber)) {
-						srcPort = port;
-					}
-				}
-			} else if(swLong == dstSw) {
-				for(IPortObject port : sw.getPorts()) {
-					if(port.getNumber().equals(dstNumber)) {
-						dstPort = port;
-					}
-				}
-			}
-		}
-		
-		if(srcPort != null && dstPort != null) {
-			for(IPortObject port : srcPort.getLinkedPorts()) {
-				if(port.equals(dstPort)) {
-					return true;
-				}
-			}
-		}
-		
-		return false;
-	}
-
-	// Overriding methods below are to mock GraphDBOperation class.
-	@Override
-	public ISwitchObject newSwitch(String dpid) {
-		TestSwitchObject sw = new TestSwitchObject();
-		sw.setDPID(dpid);
-		switchesToAdd.add(sw);
-		
-		return sw;
-	}
-
-	@Override
-	public ISwitchObject searchSwitch(String dpid_str) {
-		Long dpid = HexString.toLong(dpid_str);
-		
-		for(ISwitchObject sw : switches) {
-			if(HexString.toLong(sw.getDPID()) == dpid) {
-				return sw;
-			}
-		}
-		return null;
-	}
-
-	@Override
-	public ISwitchObject searchActiveSwitch(String dpid_str) {
-		Long dpid = HexString.toLong(dpid_str);
-
-		for(ISwitchObject sw : switches) {
-			if(HexString.toLong(sw.getDPID()) == dpid && sw.getState().equals("ACTIVE")) {
-				return sw;
-			}
-		}
-		return null;
-	}
-
-	@Override
-	public Iterable<ISwitchObject> getActiveSwitches() {
-		List<ISwitchObject> list = new ArrayList<ISwitchObject>();
-		
-		for(ISwitchObject sw : switches) {
-			if(sw.getState() != null && sw.getState().equals("ACTIVE")) {
-				list.add(sw);
-			}
-		}
-		return list.isEmpty() ? null : list;
-	}
-
-	@Override
-	public Iterable<ISwitchObject> getAllSwitches() {
-		List<ISwitchObject> list = new ArrayList<ISwitchObject>();
-		
-		for(ISwitchObject sw : switches) {
-			list.add(sw);
-		}
-		
-		return list.isEmpty() ? null : list;
-	}
-
-	@Override
-	public Iterable<ISwitchObject> getInactiveSwitches() {
-		List<ISwitchObject> list = new ArrayList<ISwitchObject>();
-		
-		for(ISwitchObject sw : switches) {
-			if(! sw.getState().equals("ACTIVE")) {
-				list.add(sw);
-			}
-		}
-		return list.isEmpty() ? null : list;
-	}
-
-	@Override
-	public Iterable<IFlowEntry> getAllSwitchNotUpdatedFlowEntries() {
-		List<IFlowEntry> list = new ArrayList<IFlowEntry>();
-		
-		for(TestFlowEntry entry : entries) {
-			if(entry.getSwitchState().equals("FE_SWITCH_NOT_UPDATED")) {
-				list.add(entry);
-			}
-		}
-		return list;
-	}
-
-	@Override
-	public void removeSwitch(ISwitchObject sw) {
-		if(switches.contains(sw)) {
-			switchesToRemove.add((TestSwitchObject)sw);
-		}
-	}
-
-	@Override
-	public IPortObject newPort(Short portNumber) {
-		TestPortObject port = new TestPortObject();
-		port.setNumber(portNumber);
-		
-		return port;
-	}
-
-	public IPortObject newPort(Long dpid, Short portNumber) {
-		TestPortObject port = null;
-		TestSwitchObject sw = (TestSwitchObject)searchSwitch(HexString.toHexString(dpid));
-		
-		if(sw != null) {
-			port = (TestPortObject)newPort(portNumber);
-			portsToAdd.add(port);
-			sw.addPort(port);
-		}
-		
-		return port;
-	}
-	
-	@Override
-	public IPortObject searchPort(String dpid_str, short number) {
-		long dpid = HexString.toLong(dpid_str);
-		
-		for(TestSwitchObject sw : switches) {
-			if(HexString.toLong(sw.getDPID()) == dpid) {
-				for(IPortObject port : sw.getPorts()) {
-					if(port.getNumber().equals(number)) {
-						return port;
-					}
-				}
-			}
-		}
-		return null;
-	}
-
-	@Override
-	public void removePort(IPortObject port) {
-		for(TestSwitchObject sw : switches) {
-			for(IPortObject pt : sw.getPorts()) {
-				if(pt.equals(port)) {
-					sw.removePort(port);
-				}
-			}
-		}
-		portsToRemove.add((TestPortObject)port);
-	}
-
-	@Override
-	public IDeviceObject newDevice() {
-		TestDeviceObject dev = new TestDeviceObject();
-		devicesToAdd.add(dev);
-		
-		return dev;
-	}
-
-	@Override
-	public IDeviceObject searchDevice(String macAddr) {
-		for(IDeviceObject dev : devices) {
-			if(dev.getMACAddress().equals(macAddr)) {
-				return dev;
-			}
-		}
-		return null;
-	}
-
-	@Override
-	public Iterable<IDeviceObject> getDevices() {
-		List<IDeviceObject> list = new ArrayList<IDeviceObject>();
-		
-		for(TestDeviceObject dev : devices) {
-			list.add(dev);
-		}
-		
-		return list;
-	}
-
-	@Override
-	public void removeDevice(IDeviceObject dev) {
-		if(devices.contains((TestDeviceObject)dev)) {
-			devicesToRemove.add((TestDeviceObject)dev);
-		}
-	}
-
-	@Override
-	public IFlowPath newFlowPath() {
-		TestFlowPath path = new TestFlowPath();
-		pathsToAdd.add(path);
-		
-		return path;
-	}
-
-	@Override
-	public IFlowPath searchFlowPath(FlowId flowId) {
-		for(IFlowPath path : paths) {
-			if(path.getFlowId().equals(flowId)) {
-				return path;
-			}
-		}
-		return null;
-	}
-
-	@Override
-	public IFlowPath getFlowPathByFlowEntry(IFlowEntry flowEntry) {
-		for(IFlowPath path : paths) {
-			for(IFlowEntry entry : path.getFlowEntries()) {
-				if(entry.equals(flowEntry)) {
-					return path;
-				}
-			}
-
-		}
-		return null;
-	}
-
-	@Override
-	public Iterable<IFlowPath> getAllFlowPaths() {
-		List<IFlowPath> list = new ArrayList<IFlowPath>();
-		
-		for(IFlowPath path : paths) {
-			list.add(path);
-		}
-		
-		return list;
-	}
-
-	@Override
-	public void removeFlowPath(IFlowPath flowPath) {
-		if(paths.contains((TestFlowPath)flowPath)) {
-			pathsToRemove.add((TestFlowPath)flowPath);
-		}
-	}
-
-	@Override
-	public IFlowEntry newFlowEntry() {
-		TestFlowEntry entry = new TestFlowEntry();
-		entriesToAdd.add(entry);
-		return entry;
-	}
-
-	@Override
-	public IFlowEntry searchFlowEntry(FlowEntryId flowEntryId) {
-		for(TestFlowEntry entry : entries) {
-			// TODO check if this matching works
-			if(entry.getFlowEntryId().equals(flowEntryId)) {
-				return entry;
-			}
-		}
-		return null;
-	}
-
-	@Override
-	public Iterable<IFlowEntry> getAllFlowEntries() {
-		List<IFlowEntry> list = new ArrayList<IFlowEntry>();
-		
-		for(TestFlowEntry entry : entries) {
-			list.add(entry);
-		}
-		
-		return list;
-	}
-
-	@Override
-	public void removeFlowEntry(IFlowEntry flowEntry) {
-		if(entries.contains((TestFlowEntry)flowEntry)) {
-			entriesToRemove.add((TestFlowEntry)flowEntry);
-		}
-	}
-
-	@Override
-	public IDBConnection getDBConnection() {
-		return super.getDBConnection();
-	}
-
-	@Override
-	public void commit() {
-		for(TestSwitchObject sw : switchesToAdd) {
-			switches.add(sw);
-		}
-		for(TestSwitchObject sw : switchesToRemove) {
-			sw.commit();
-			switches.remove(sw);
-		}
-		for(TestSwitchObject sw : switches) {
-			sw.commit();
-		}
-		
-		for(TestPortObject port : portsToAdd) {
-			ports.add(port);
-		}
-		for(TestPortObject port : portsToRemove) {
-			port.commit();
-			ports.remove(port);
-		}
-		for(TestPortObject port : ports) {
-			port.commit();
-		}
-		
-		for(TestDeviceObject dev : devicesToAdd) {
-			devices.add(dev);
-		}
-		for(TestDeviceObject dev : devicesToRemove) {
-			dev.commit();
-			devices.remove(dev);
-		}
-		for(TestDeviceObject dev : devices) {
-			dev.commit();
-		}
-		
-		clearUncommitedData();
-	}
-
-	@Override
-	public void rollback() {
-		clearUncommitedData();
-	}
-
-	@Override
-	public void close() {
-		// TODO Auto-generated method stub
-
-	}
-}
diff --git a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/TestableLinkStorageImpl.java b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/TestableLinkStorageImpl.java
deleted file mode 100644
index 5709f03..0000000
--- a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/TestableLinkStorageImpl.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package net.floodlightcontroller.linkdiscovery.internal;
-
-import java.util.Set;
-
-import com.thinkaurelius.titan.core.TitanGraph;
-import com.tinkerpop.blueprints.TransactionalGraph.Conclusion;
-import com.tinkerpop.blueprints.Vertex;
-
-/**
- * Seam that allows me to set up a testable instance of LinkStorageImpl that 
- * writes to a file database rather than a Cassandra cluster. 
- * It seems the init() API on LinkStorageImpl might change so I won't rely
- * on it yet.
- * 
- * @author jono
- *
- */
-
-public class TestableLinkStorageImpl extends LinkStorageImpl {
-	protected TitanGraph graph;
-
-	public TestableLinkStorageImpl(TitanGraph graph){
-		this.graph = graph;
-	}
-	
-	@Override
-	public void init(String conf){
-        Set<String> s = graph.getIndexedKeys(Vertex.class);
-        if (!s.contains("dpid")) {
-           graph.createKeyIndex("dpid", Vertex.class);
-           graph.stopTransaction(Conclusion.SUCCESS);
-        }
-        if (!s.contains("type")) {
-        	graph.createKeyIndex("type", Vertex.class);
-        	graph.stopTransaction(Conclusion.SUCCESS);
-        }
-		
-	}
-}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java b/src/test/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java
index b780c2b..87b48b2 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java
@@ -46,8 +46,6 @@
 import net.floodlightcontroller.topology.ITopologyService;
 import net.floodlightcontroller.topology.NodePortTuple;
 import net.floodlightcontroller.topology.TopologyManager;
-import net.onrc.onos.registry.controller.IControllerRegistryService;
-import net.onrc.onos.registry.controller.StandaloneRegistry;
 import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryListener;
 import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryService;
 import net.onrc.onos.ofcontroller.linkdiscovery.LinkInfo;
@@ -60,7 +58,6 @@
 public class LinkDiscoveryManagerTest extends FloodlightTestCase {
 
     private TestLinkDiscoveryManager ldm;
-    private StandaloneRegistry srs;
     protected static Logger log = LoggerFactory.getLogger(LinkDiscoveryManagerTest.class);
     
     public class TestLinkDiscoveryManager extends LinkDiscoveryManager {
@@ -102,7 +99,6 @@
         ldm = new TestLinkDiscoveryManager();
         TopologyManager routingEngine = new TopologyManager();
         ldm.linkDiscoveryAware = new ArrayList<ILinkDiscoveryListener>();
-        srs = new StandaloneRegistry();
         MockThreadPoolService tp = new MockThreadPoolService();
         RestApiServer restApi = new RestApiServer();
         cntx.addService(IRestApiService.class, restApi);
@@ -112,17 +108,13 @@
         cntx.addService(ITopologyService.class, ldm);
         cntx.addService(IStorageSourceService.class, new MemoryStorageSource());
         cntx.addService(IFloodlightProviderService.class, getMockFloodlightProvider());
-        cntx.addService(IControllerRegistryService.class, srs);
-
         restApi.init(cntx);
         tp.init(cntx);
         routingEngine.init(cntx);
-        srs.init(cntx);
         ldm.init(cntx);
         restApi.startUp(cntx);
         tp.startUp(cntx);
         routingEngine.startUp(cntx);
-        srs.startUp(cntx);
         ldm.startUp(cntx);
 
         IOFSwitch sw1 = createMockSwitch(1L);
