diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImpl.java b/src/main/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImpl.java
index 6628bcc..2eaf535 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImpl.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImpl.java
@@ -200,7 +200,23 @@
 	// TODO: Fix me
 	@Override
 	public List<Link> getLinks(Long dpid, short port) {
-    	List<Link> links = null;
+    	List<Link> links = new ArrayList<Link>();
+    	
+    	IPortObject srcPort = dbop.searchPort(HexString.toHexString(dpid), port);
+    	ISwitchObject srcSw = srcPort.getSwitch();
+    	
+    	if(srcSw != null) {
+        	for(IPortObject dstPort : srcPort.getLinkedPorts()) {
+        		ISwitchObject dstSw = dstPort.getSwitch();
+        		Link link = new Link(HexString.toLong(srcSw.getDPID()),
+        				srcPort.getNumber(),
+        				HexString.toLong(dstSw.getDPID()),
+        				dstPort.getNumber());
+    		
+        		links.add(link);
+        	}
+    	}
+    	
      	return links;
 	}
 	
@@ -222,14 +238,11 @@
 	// TODO: Fix me
 	@Override
 	public void deleteLinksOnPort(Long dpid, short port) {
-		// BEGIN: Trial code
-		// author: Naoki Shiota
 		List<Link> linksToDelete = getLinks(dpid,port);
 		
 		for(Link l : linksToDelete) {
 			deleteLink(l);
 		}
-		// END: Trial code
 	}
 
 	/**
@@ -242,6 +255,23 @@
 	public List<Link> getLinks(String dpid) {
 		List<Link> links = new ArrayList<Link>();
 
+		ISwitchObject srcSw = dbop.searchSwitch(dpid);
+		
+		if(srcSw != null) {
+			for(IPortObject srcPort : srcSw.getPorts()) {
+				for(IPortObject dstPort : srcPort.getLinkedPorts()) {
+					ISwitchObject dstSw = dstPort.getSwitch();
+					if(dstSw != null) {
+		        		Link link = new Link(HexString.toLong(srcSw.getDPID()),
+		        				srcPort.getNumber(),
+		        				HexString.toLong(dstSw.getDPID()),
+		        				dstPort.getNumber());
+		        		links.add(link);
+					}
+				}
+			}
+		}
+		
 		return links;
 	}
 
@@ -253,20 +283,22 @@
 		Iterable<ISwitchObject> switches = dbop.getActiveSwitches();
 
 		List<Link> links = new ArrayList<Link>(); 
-		for (ISwitchObject sw : switches) {
-			GremlinPipeline<Vertex, Link> pipe = new GremlinPipeline<Vertex, Link>();
-			ExtractLink extractor = new ExtractLink();
-
-			pipe.start(sw.asVertex());
-			pipe.enablePath(true);
-			pipe.out("on").out("link").in("on").path().step(extractor);
+		
+		for (ISwitchObject srcSw : switches) {
+			for(IPortObject srcPort : srcSw.getPorts()) {
+				for(IPortObject dstPort : srcPort.getLinkedPorts()) {
+					ISwitchObject dstSw = dstPort.getSwitch();
 					
-			while (pipe.hasNext() ) {
-				Link l = pipe.next();
-				links.add(l);
+					if(dstSw != null && dstSw.getState().equals("ACTIVE")) {
+						links.add(new Link(HexString.toLong(srcSw.getDPID()),
+								srcPort.getNumber(),
+								HexString.toLong(dstSw.getDPID()),
+								dstPort.getNumber()));
+					}
+				}
 			}
-						
 		}
+		
 		return links;
 	}
 	
diff --git a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java
new file mode 100644
index 0000000..0bf9ba0
--- /dev/null
+++ b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java
@@ -0,0 +1,440 @@
+/**
+*    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
new file mode 100644
index 0000000..09319bf
--- /dev/null
+++ b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImplTest.java
@@ -0,0 +1,536 @@
+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
new file mode 100644
index 0000000..e3ad879
--- /dev/null
+++ b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/TestableGraphDBOperation.java
@@ -0,0 +1,1500 @@
+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
new file mode 100644
index 0000000..5709f03
--- /dev/null
+++ b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/TestableLinkStorageImpl.java
@@ -0,0 +1,39 @@
+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/core/internal/LinkStorageImplTest.java b/src/test/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImplTest.java
index 29151c3..7bf2b1a 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImplTest.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImplTest.java
@@ -5,12 +5,14 @@
 import static org.junit.Assert.assertTrue;
 
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 
 import net.floodlightcontroller.routing.Link;
 import net.onrc.onos.ofcontroller.core.ILinkStorage;
 import net.onrc.onos.ofcontroller.core.INetMapStorage.DM_OPERATION;
+import net.onrc.onos.ofcontroller.core.internal.TestableGraphDBOperation.TestPortObject;
+import net.onrc.onos.util.GraphDBConnection;
+import net.onrc.onos.util.GraphDBOperation;
 import net.onrc.onos.ofcontroller.linkdiscovery.LinkInfo;
 
 import org.easymock.EasyMock;
@@ -24,23 +26,21 @@
 import org.powermock.api.easymock.PowerMock;
 import org.powermock.core.classloader.annotations.PrepareForTest;
 import org.powermock.modules.junit4.PowerMockRunner;
-
-import com.thinkaurelius.titan.core.TitanFactory;
-import com.thinkaurelius.titan.core.TitanGraph;
-import com.tinkerpop.blueprints.Direction;
-import com.tinkerpop.blueprints.Edge;
-import com.tinkerpop.blueprints.Vertex;
-import com.tinkerpop.gremlin.java.GremlinPipeline;
-import com.tinkerpop.pipes.PipeFunction;
-import com.tinkerpop.pipes.transform.PathPipe;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 @RunWith(PowerMockRunner.class)
-@PrepareForTest({TitanFactory.class})
+@PrepareForTest({LinkStorageImpl.class, GraphDBConnection.class, GraphDBOperation.class})
 public class LinkStorageImplTest {
+	protected static Logger log = LoggerFactory.getLogger(LinkStorageImplTest.class);
+
 	private static ILinkStorage linkStorage;
-	private static TitanGraph titanGraph;
 	
-	//private static IController
+	// 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.
@@ -49,20 +49,20 @@
 	 */
 	@Before
 	public void setUp() throws Exception{
-		TestDatabaseManager.deleteTestDatabase();
-
-		titanGraph = TestDatabaseManager.getTestDatabase();
-		TestDatabaseManager.populateTestData(titanGraph);
-
-		// replace return value of TitanFactory.open() to dummy DB created above
-		PowerMock.mockStatic(TitanFactory.class);
-		EasyMock.expect(TitanFactory.open((String)EasyMock.anyObject())).andReturn(titanGraph);
-		PowerMock.replay(TitanFactory.class);
+		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");
 		
-		// initialize with dummy string
-		linkStorage.init("/dummy/path/to/db");
+		initLinks();
 	}
 	
 	/**
@@ -74,9 +74,7 @@
 	public void tearDown() throws Exception {
 		// finish code
 		linkStorage.close();
-		
-		titanGraph.shutdown();
-		TestDatabaseManager.deleteTestDatabase();
+		ope.close();
 	}
 	
 	// TODO: remove @Ignore after UPDATE method is implemented
@@ -105,14 +103,7 @@
 		
 		//Use the link storage API to add the link
 		linkStorage.update(linkToCreate, ILinkStorage.DM_OPERATION.CREATE);
-		doTestLinkIsInGraph(linkToVerify);
-
-		// Add same link
-		Link linkToCreateTwice = createFeasibleLink();
-		linkStorage.update(linkToCreateTwice, ILinkStorage.DM_OPERATION.CREATE);
-		
-		// this occurs assertion failure if there are two links in titanGraph
-		doTestLinkIsInGraph(linkToVerify);
+		doTestLinkExist(linkToVerify);
 	}
 
 	/**
@@ -125,15 +116,7 @@
 		
 		//Use the link storage API to add the link
 		linkStorage.update(linkToInsert, ILinkStorage.DM_OPERATION.INSERT);
-
-		doTestLinkIsInGraph(linkToVerify);
-		
-		// Add same link
-		Link linkToInsertTwice = createFeasibleLink();
-		linkStorage.update(linkToInsertTwice, ILinkStorage.DM_OPERATION.INSERT);
-
-		// this occurs assertion failure if there are two links in titanGraph
-		doTestLinkIsInGraph(linkToVerify);
+		doTestLinkExist(linkToVerify);
 	}
 	
 	/**
@@ -146,14 +129,7 @@
 
 		// Test deletion of existing link
 		linkStorage.update(linkToDelete, DM_OPERATION.DELETE);
-		doTestLinkIsNotInGraph(linkToVerify);
-		
-		linkToDelete = createFeasibleLink();
-		linkToVerify = createFeasibleLink();
-
-		// Test deletion of not-existing link
-		linkStorage.update(linkToDelete, DM_OPERATION.DELETE);
-		doTestLinkIsNotInGraph(linkToVerify);
+		doTestLinkNotExist(linkToVerify);
 	}
 
 	/**
@@ -167,21 +143,15 @@
 		// Test creation of new links
 		linkStorage.update(linksToCreate, ILinkStorage.DM_OPERATION.CREATE);
 		for(Link l : linksToVerify) {
-			doTestLinkIsInGraph(l);
-		}
-		
-		// Test creation of existing links
-		linksToCreate = createFeasibleLinks();
-		linkStorage.update(linksToCreate, ILinkStorage.DM_OPERATION.CREATE);
-		for(Link l : linksToVerify) {
-			doTestLinkIsInGraph(l);
+			doTestLinkExist(l);
 		}
 	}
 	
 	/**
 	 * Test if update() can handle mixture of normal/abnormal input for creation of Links.
+	 * Deprecated: DBOperation is responsible.
 	 */
-	@Test
+	@Ignore @Test
 	public void testUpdate_CreateLinks_Mixuture(){
 		List<Link> linksToCreate = new ArrayList<Link>();
 		linksToCreate.add(createFeasibleLink());
@@ -189,8 +159,8 @@
 		
 		// Test creation of mixture of new/existing links
 		linkStorage.update(linksToCreate, ILinkStorage.DM_OPERATION.CREATE);
-		doTestLinkIsInGraph(createFeasibleLink());
-		doTestLinkIsInGraph(createExistingLink());
+		doTestLinkExist(createFeasibleLink());
+		doTestLinkExist(createExistingLink());
 	}
 
 	/**
@@ -204,21 +174,14 @@
 		// Test insertion of new links
 		linkStorage.update(linksToInsert, ILinkStorage.DM_OPERATION.INSERT);
 		for(Link l : linksToVerify) {
-			doTestLinkIsInGraph(l);
-		}
-		
-		// Test insertion of existing links
-		linksToInsert = createFeasibleLinks();
-		linkStorage.update(linksToInsert, ILinkStorage.DM_OPERATION.INSERT);
-		for(Link l : linksToVerify) {
-			doTestLinkIsInGraph(l);
+			doTestLinkExist(l);
 		}
 	}
 	
 	/**
 	 * Test if update() can handle mixture of normal/abnormal input for creation of Links.
 	 */
-	@Test
+	@Ignore @Test
 	public void testUpdate_InsertLinks_Mixuture(){
 		List<Link> linksToInsert = new ArrayList<Link>();
 		linksToInsert.add(createFeasibleLink());
@@ -226,8 +189,8 @@
 		
 		// Test insertion of mixture of new/existing links
 		linkStorage.update(linksToInsert, ILinkStorage.DM_OPERATION.INSERT);
-		doTestLinkIsInGraph(createFeasibleLink());
-		doTestLinkIsInGraph(createExistingLink());
+		doTestLinkExist(createFeasibleLink());
+		doTestLinkExist(createExistingLink());
 	}
 
 	/**
@@ -241,21 +204,14 @@
 		// Test deletion of existing links
 		linkStorage.update(linksToDelete, ILinkStorage.DM_OPERATION.DELETE);
 		for(Link l : linksToVerify) {
-			doTestLinkIsNotInGraph(l);
-		}
-		
-		// Test deletion of not-existing links
-		linksToDelete = createExistingLinks();
-		linkStorage.update(linksToDelete, ILinkStorage.DM_OPERATION.DELETE);
-		for(Link l : linksToVerify) {
-			doTestLinkIsNotInGraph(l);
+			doTestLinkNotExist(l);
 		}
 	}
 	
 	/**
 	 * Test if update() can handle mixture of normal/abnormal input for deletion of Links.
 	 */
-	@Test
+	@Ignore @Test
 	public void testUpdate_DeleteLinks_Mixuture(){
 		List<Link> linksToDelete = new ArrayList<Link>();
 		linksToDelete.add(createFeasibleLink());
@@ -263,8 +219,8 @@
 		
 		// Test deletion of mixture of new/existing links
 		linkStorage.update(linksToDelete, ILinkStorage.DM_OPERATION.DELETE);
-		doTestLinkIsNotInGraph(createFeasibleLink());
-		doTestLinkIsNotInGraph(createExistingLink());
+		doTestLinkNotExist(createFeasibleLink());
+		doTestLinkNotExist(createExistingLink());
 	}
 	
 	// TODO: remove @Ignore after UPDATE method is implemented
@@ -293,14 +249,7 @@
 		
 		//Use the link storage API to add the link
 		linkStorage.updateLink(linkToCreate, null, ILinkStorage.DM_OPERATION.CREATE);
-		doTestLinkIsInGraph(linkToVerify);
-
-		// Add same link
-		Link linkToCreateTwice = createFeasibleLink();
-		linkStorage.updateLink(linkToCreateTwice, null, ILinkStorage.DM_OPERATION.CREATE);
-		
-		// this occurs assertion failure if there are two links in titanGraph
-		doTestLinkIsInGraph(linkToVerify);
+		doTestLinkExist(linkToVerify);
 	}
 	
 	/**
@@ -314,14 +263,7 @@
 		//Use the link storage API to add the link
 		linkStorage.updateLink(linkToInsert, null, ILinkStorage.DM_OPERATION.INSERT);
 
-		doTestLinkIsInGraph(linkToVerify);
-		
-		// Add same link
-		Link linkToInsertTwice = createFeasibleLink();
-		linkStorage.updateLink(linkToInsertTwice, null, ILinkStorage.DM_OPERATION.INSERT);
-
-		// this occurs assertion failure if there are two links in titanGraph
-		doTestLinkIsInGraph(linkToVerify);
+		doTestLinkExist(linkToVerify);
 	}
 	
 	// TODO: Check if addOrUpdateLink() should accept DELETE operation. If not, remove this test.
@@ -335,14 +277,14 @@
 
 		// Test deletion of existing link
 		linkStorage.updateLink(linkToDelete, null, DM_OPERATION.DELETE);
-		doTestLinkIsNotInGraph(linkToVerify);
+		doTestLinkNotExist(linkToVerify);
 		
 		linkToDelete = createFeasibleLink();
 		linkToVerify = createFeasibleLink();
 
 		// Test deletion of not-existing link
 		linkStorage.updateLink(linkToDelete, null, DM_OPERATION.DELETE);
-		doTestLinkIsNotInGraph(linkToVerify);
+		doTestLinkNotExist(linkToVerify);
 	}
 	
 	/**
@@ -396,14 +338,7 @@
 		Link linkToVerify = createExistingLink();
 		
 		linkStorage.deleteLink(linkToDelete);
-		doTestLinkIsNotInGraph(linkToVerify);
-		
-		// Deletion of not existing link
-		linkToDelete = createFeasibleLink();
-		linkToVerify = createFeasibleLink();
-		
-		linkStorage.deleteLink(linkToDelete);
-		doTestLinkIsNotInGraph(linkToVerify);
+		doTestLinkNotExist(linkToVerify);
 	}
 	
 	/**
@@ -416,14 +351,14 @@
 		
 		linkStorage.deleteLinks(linksToDelete);
 		for(Link l : linksToVerify) {
-			doTestLinkIsNotInGraph(l);
+			doTestLinkNotExist(l);
 		}
 	}
 	
 	/**
 	 * Test if deleteLinks() can handle mixture of normal/abnormal input.
 	 */
-	@Test
+	@Ignore @Test
 	public void testDeleteLinks_Mixture(){
 		List<Link> linksToDelete = new ArrayList<Link>();
 		linksToDelete.add(createFeasibleLink());
@@ -431,8 +366,8 @@
 		
 		// Test deletion of mixture of new/existing links
 		linkStorage.deleteLinks(linksToDelete);
-		doTestLinkIsNotInGraph(createFeasibleLink());
-		doTestLinkIsNotInGraph(createExistingLink());
+		doTestLinkNotExist(createFeasibleLink());
+		doTestLinkNotExist(createExistingLink());
 	}
 
 	/**
@@ -459,57 +394,29 @@
 		
 		linkStorage.deleteLinksOnPort(linkToDelete.getSrc(), linkToDelete.getSrcPort());
 		
-		doTestLinkIsNotInGraph(linkToVerify);
+		doTestLinkNotExist(linkToVerify);
 	}
 
 	/**
-	 * Test if titanGraph has specific link
+	 * Test if specific link is existing
 	 * @param link 
 	 */
-	private void doTestLinkIsInGraph(Link link) {
-		String src_dpid = HexString.toHexString(link.getSrc());
-		String dst_dpid = HexString.toHexString(link.getDst());
-		short src_port = link.getSrcPort();
-		short dst_port = link.getDstPort();
-		
-		Iterator<Vertex> it = titanGraph.getVertices("dpid", src_dpid).iterator();
-		
-		// Test if just one switch is found in the graph
-		assertTrue(it.hasNext());
-		Vertex sw = it.next();
-		assertFalse(it.hasNext());
-		
-		GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
-		pipe.start(sw).out("on").has("number", src_port).out("link").has("number", dst_port).in("on").has("dpid", dst_dpid);
-		
-		// Test if just one link is found in the graph
-		assertTrue(pipe.hasNext());
-		pipe.next();
-		assertFalse(pipe.hasNext());
+	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 doTestLinkIsNotInGraph(Link link) {
-		String src_dpid = HexString.toHexString(link.getSrc());
-		String dst_dpid = HexString.toHexString(link.getDst());
-		short src_port = link.getSrcPort();
-		short dst_port = link.getDstPort();
-		
-		Iterator<Vertex> it = titanGraph.getVertices("dpid", src_dpid).iterator();
-		
-		// Test if just one switch is found in the graph
-		assertTrue(it.hasNext());
-		Vertex sw = it.next();
-		assertFalse(it.hasNext());
-		
-		GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
-		pipe.start(sw).out("on").has("number", src_port).out("link").has("number", dst_port).in("on").has("dpid", dst_dpid);
-		
-		// Test if no link is found in the graph
-		assertFalse(pipe.hasNext());
+	private void doTestLinkNotExist(Link link) {
+		assertFalse(ope.hasLinkBetween(HexString.toHexString(link.getSrc()),
+				link.getSrcPort(),
+				HexString.toHexString(link.getDst()),
+				link.getDstPort()));
 	}
 	
 	/**
@@ -517,74 +424,73 @@
 	 * @param link 
 	 */
 	private void doTestLinkHasStateOf(Link link, LinkInfo info) {
-		String src_dpid = HexString.toHexString(link.getSrc());
-		String dst_dpid = HexString.toHexString(link.getDst());
-		short src_port = link.getSrcPort();
-		short dst_port = link.getDstPort();
-		
-		Iterator<Vertex> it = titanGraph.getVertices("dpid", src_dpid).iterator();
-		
-		// Test if just one switch is found in the graph
-		assertTrue(it.hasNext());
-		Vertex sw = it.next();
-		assertFalse(it.hasNext());
-		
-		GremlinPipeline<Vertex, Edge> pipe = new GremlinPipeline<Vertex, Edge>();
-		pipe.start(sw);
-		pipe.enablePath();
-		pipe.out("on").has("number", src_port).out("link").has("number", dst_port).in("on").has("dpid", dst_dpid)
-			.path().step(new PipeFunction<PathPipe<Vertex>, Edge>() {
-			@Override
-			public Edge compute(PathPipe<Vertex> pipepath) {
-				List<Vertex> V = pipepath.next();
-
-				Vertex port_src = V.get(1);
-				Vertex port_dst = V.get(2);
-				
-				for(Edge e : port_src.getEdges(Direction.OUT)) {
-					if(e.getVertex(Direction.IN).equals(port_dst)) {
-						return e;
-					}
-				}
-				
-				return null;
-			}
-		});
-		
-		// Test if just one link is found in the graph
-		assertTrue(pipe.hasNext());
-		Edge edge = pipe.next();
-		assertTrue(edge != null);
-		assertFalse(pipe.hasNext());
-
-		// TODO: implement test code to check if update is correctly done.
-		assertTrue(false);
 	}
-
-
+	
 	//----------------- Creation of test data -----------------------
-	/**
-	 * Returns new Link object which has information of existing link in titanGraph
-	 * @return new Link object
-	 */
-	private Link createExistingLink() {
-		// Link from SEA switch port 2 to CHI switch port 1
-		return new Link(Long.decode("0x0000000000000a01"), 2, Long.decode("0x0000000000000a03"), 1);
+	// 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 which has information of not-existing but feasible link in titanGraph
+	 * 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() {
-		// Link from SEA switch port 1 to LAX switch port 1
-		return new Link(Long.decode("0x0000000000000a01"), 4, Long.decode("0x0000000000000a02"), 1);
+		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("0x0000000000000a02"), 1);
+		return new Link(Long.decode("0x0000000000000a01"), 1, Long.decode("0x0000000000000a03"), 3);
 	}
 
 	/**
@@ -593,10 +499,8 @@
 	 */
 	private List<Link> createExistingLinks() {
 		List<Link> links = new ArrayList<Link>();
-		// Link from SEA switch port 2 to CHI switch port 1
-		links.add(new Link(Long.decode("0x0000000000000a01"), 2, Long.decode("0x0000000000000a03"), 1));
-		// Link from LAX switch port 1 to SEA switch port 3
-		links.add(new Link(Long.decode("0x0000000000000a02"), 1, Long.decode("0x0000000000000a01"), 3));
+		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;
 	}
 	
@@ -606,10 +510,8 @@
 	 */
 	private List<Link> createFeasibleLinks() {
 		List<Link> links = new ArrayList<Link>();
-		// Link from CHI switch port 4 to NYC switch port 3
-		links.add(new Link(Long.decode("0x0000000000000a03"), 4, Long.decode("0x0000000000000a05"), 3));
-		// Link from SEA switch port 4 to LAX switch port 1
-		links.add(new Link(Long.decode("0x0000000000000a01"), 4, Long.decode("0x0000000000000a02"), 1));
+		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;
 	}
 	
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableGraphDBOperation.java b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableGraphDBOperation.java
new file mode 100644
index 0000000..31a4bb0
--- /dev/null
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableGraphDBOperation.java
@@ -0,0 +1,1331 @@
+package net.onrc.onos.ofcontroller.core.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.easymock.EasyMock;
+import org.openflow.util.HexString;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.tinkerpop.blueprints.Vertex;
+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.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
+		public String getState() { return state; }
+	
+		@Override
+		public void setState(String state) { this.stateToUpdate = state; }
+	
+		@Override
+		public String getType() { return type ; }
+	
+		@Override
+		public void setType(String type) { this.typeToUpdate = type; }
+	
+		// Not support for test
+		@Override
+		public Vertex asVertex() { return null; }
+	
+		@Override
+		public String getDPID() { return dpid; }
+	
+		@Override
+		public void setDPID(String dpid) { this.dpidToUpdate = dpid; }
+	
+		@Override
+		public Iterable<IPortObject> getPorts() { return ports; }
+	
+		@Override
+		public IPortObject getPort(@GremlinParam("port_num") short port_num) {
+			for(IPortObject port : ports) {
+				if(port.getNumber() == port_num) {
+					return port;
+				}
+			}
+			return null;
+		}
+	
+		@Override
+		public void addPort(IPortObject port) { portsToAdd.add(port); }
+	
+		@Override
+		public void removePort(IPortObject port) { portsToRemove.add(port); }
+	
+		@Override
+		public Iterable<IDeviceObject> getDevices() { return devices; }
+	
+		@Override
+		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
+		public String getState() { return state; }
+
+		@Override
+		public void setState(String state) { this.stateToUpdate = state; }
+
+		@Override
+		public String getType() { return type; }
+
+		@Override
+		public void setType(String type) { this.typeToUpdate = type; }
+
+		// not support for test
+		@Override
+		public Vertex asVertex() {
+			return null;
+		}
+
+		@Override
+		public Short getNumber() { return number; }
+
+		@Override
+		public void setNumber(Short n) { this.numberToUpdate = n; }
+
+		@Override
+		public String getDesc() { return desc; }
+
+		@Override
+		public void setDesc(String s) { this.descToUpdate = s; }
+
+		@Override
+		public Integer getPortState() { return port_state; }
+
+		@Override
+		public void setPortState(Integer s) { this.port_stateToUpdate = s; }
+
+		@Override
+		public ISwitchObject getSwitch() { return sw; }
+
+		@Override
+		public Iterable<IDeviceObject> getDevices() { return devices; }
+
+		@Override
+		public void setDevice(IDeviceObject device) { devicesToAdd.add(device); }
+
+		@Override
+		public void removeDevice(IDeviceObject device) { devicesToRemove.add(device); }
+
+		@Override
+		public Iterable<IFlowEntry> getInFlowEntries() { return inflows; }
+
+		@Override
+		public Iterable<IFlowEntry> getOutFlowEntries() { return outflows; }
+
+		@Override
+		public Iterable<IPortObject> getLinkedPorts() { return linkedPorts; }
+
+		@Override
+		public void removeLink(IPortObject dest_port) { linkedPortsToRemove.add(dest_port); }
+
+		@Override
+		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
+		public String getState() { return state; }
+	
+		@Override
+		public void setState(String state) { stateToUpdate = state; }
+	
+		@Override
+		public String getType() { return type; }
+	
+		@Override
+		public void setType(String type) { typeToUpdate = type; }
+	
+		@Override
+		public Vertex asVertex() {
+			// TODO Auto-generated method stub
+			return null;
+		}
+	
+		@Override
+		public String getMACAddress() { return mac; }
+	
+		@Override
+		public void setMACAddress(String macaddr) { macToUpdate = macaddr; }
+	
+		@Override
+		public String getIPAddress() { return ipaddr; }
+	
+		@Override
+		public void setIPAddress(String ipaddr) { ipaddrToUpdate = ipaddr; }
+	
+		@Override
+		public Iterable<IPortObject> getAttachedPorts() {
+			return ports; }
+	
+		@Override
+		public void setHostPort(IPortObject port) { portsToAdd.add(port); }
+	
+		@Override
+		public void removeHostPort(IPortObject port) { portsToRemove.add(port); }
+	
+		@Override
+		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
+		public String getState() { return state; }
+
+		@Override
+		public void setState(String state) { stateToUpdate = state; }
+
+		@Override
+		public String getType() { return type; }
+
+		@Override
+		public void setType(String type) { typeToUpdate = type; }
+
+		@Override
+		public Vertex asVertex() {
+			// TODO Auto-generated method stub
+			return null;
+		}
+
+		@Override
+		public String getFlowId() { return flowId; }
+
+		@Override
+		public void setFlowId(String flowId) { flowIdToUpdate = flowId; }
+
+		@Override
+		public String getInstallerId() { return installerId; }
+
+		@Override
+		public void setInstallerId(String installerId) { installerIdToUpdate = installerId; }
+
+		@Override
+		public String getSrcSwitch() { return srcSw; }
+
+		@Override
+		public void setSrcSwitch(String srcSwitch) { srcSwToUpdate = srcSwitch; }
+
+		@Override
+		public Short getSrcPort() { return srcPort; }
+
+		@Override
+		public void setSrcPort(Short srcPort) { srcPortToUpdate = srcPort; }
+
+		@Override
+		public String getDstSwitch() { return dstSw; }
+
+		@Override
+		public void setDstSwitch(String dstSwitch) { dstSwToUpdate = dstSwitch; }
+
+		@Override
+		public Short getDstPort() { return dstPort; }
+
+		@Override
+		public void setDstPort(Short dstPort) { dstPortToUpdate = dstPort; }
+
+		@Override
+		public String getDataPathSummary() { return dataPathSummary; }
+
+		@Override
+		public void setDataPathSummary(String dataPathSummary) { dataPathSummaryToUpdate = dataPathSummary; }
+
+		@Override
+		public Iterable<IFlowEntry> getFlowEntries() { return entries; }
+
+		@Override
+		public void addFlowEntry(IFlowEntry flowEntry) {
+			if(! entries.contains(flowEntry)) {
+				flowsToAdd.add(flowEntry);
+			}
+		}
+
+		@Override
+		public void removeFlowEntry(IFlowEntry flowEntry) {
+			if(entries.contains(flowEntry)) {
+				flowsToAdd.add(flowEntry);
+			}
+		}
+
+		@Override
+		public Short getMatchEthernetFrameType() { return matchEthernetFrameType; }
+
+		@Override
+		public void setMatchEthernetFrameType(Short matchEthernetFrameType) {
+			matchEthernetFrameTypeToUpdate = matchEthernetFrameType; }
+
+		@Override
+		public String getMatchSrcMac() { return matchSrcMac; }
+
+		@Override
+		public void setMatchSrcMac(String matchSrcMac) { matchSrcMacToUpdate = matchSrcMac; }
+
+		@Override
+		public String getMatchDstMac() { return matchDstMac; }
+
+		@Override
+		public void setMatchDstMac(String matchDstMac) { matchDstMacToUpdate = matchDstMac; }
+
+		@Override
+		public String getMatchSrcIPv4Net() { return matchSrcIpaddr; }
+
+		@Override
+		public void setMatchSrcIPv4Net(String matchSrcIPv4Net) {
+			matchSrcIpaddrToUpdate = matchSrcIPv4Net; }
+
+		@Override
+		public String getMatchDstIPv4Net() { return matchDstIpaddr; }
+
+		@Override
+		public void setMatchDstIPv4Net(String matchDstIPv4Net) {
+			matchDstIpaddrToUpdate = matchDstIPv4Net; }
+
+		@Override
+		public Iterable<ISwitchObject> getSwitches() { return switches; }
+
+		@Override
+		public String getUserState() { return userState; }
+
+		@Override
+		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
+		public String getState() { return state; }
+	
+		@Override
+		public void setState(String state) { stateToUpdate = state; }
+	
+		@Override
+		public String getType() { return type; }
+	
+		@Override
+		public void setType(String type) { typeToUpdate = type; }
+	
+		@Override
+		public Vertex asVertex() {
+			// TODO Auto-generated method stub
+			return null;
+		}
+	
+		@Override
+		public String getFlowEntryId() { return entryId; }
+	
+		@Override
+		public void setFlowEntryId(String flowEntryId) { entryIdToUpdate = flowEntryId; }
+	
+		@Override
+		public String getSwitchDpid() { return dpid; }
+	
+		@Override
+		public void setSwitchDpid(String switchDpid) { dpidToUpdate = switchDpid; }
+	
+		@Override
+		public String getUserState() { return userState; }
+	
+		@Override
+		public void setUserState(String userState) { userStateToUpdate = userState; }
+	
+		@Override
+		public String getSwitchState() { return switchState; }
+	
+		@Override
+		public void setSwitchState(String switchState) { switchStateToUpdate = switchState; }
+	
+		@Override
+		public String getErrorStateType() { return errorStateType; }
+	
+		@Override
+		public void setErrorStateType(String errorStateType) { errorStateTypeToUpdate = errorStateType; }
+	
+		@Override
+		public String getErrorStateCode() { return errorStateCode; }
+	
+		@Override
+		public void setErrorStateCode(String errorStateCode) { errorStateCodeToUpdate = errorStateCode; }
+	
+		@Override
+		public Short getMatchInPort() { return matchInPort; }
+	
+		@Override
+		public void setMatchInPort(Short matchInPort) { matchInPortToUpdate = matchInPort; }
+	
+		@Override
+		public Short getMatchEthernetFrameType() {return matchEtherFrameType; }
+	
+		@Override
+		public void setMatchEthernetFrameType(Short matchEthernetFrameType) { matchEtherFrameTypeToUpdate = matchEthernetFrameType; }
+		
+		@Override
+		public String getMatchSrcMac() { return matchSrcMac; }
+	
+		@Override
+		public void setMatchSrcMac(String matchSrcMac) { matchSrcMacToUpdate = matchSrcMac; }
+	
+		@Override
+		public String getMatchDstMac() { return matchDstMac; }
+	
+		@Override
+		public void setMatchDstMac(String matchDstMac) { matchDstMacToUpdate = matchDstMac; }
+	
+		@Override
+		public String getMatchSrcIPv4Net() { return matchSrcIpaddr; }
+	
+		@Override
+		public void setMatchSrcIPv4Net(String matchSrcIPv4Net) { matchSrcIpaddrToUpdate = matchSrcIPv4Net; }
+	
+		@Override
+		public String getMatchDstIPv4Net() { return matchDstIpaddr; }
+	
+		@Override
+		public void setMatchDstIPv4Net(String matchDstIPv4Net) { matchDstIpaddrToUpdate = matchDstIPv4Net; }
+	
+		@Override
+		public Short getActionOutput() { return actionOutput; }
+	
+		@Override
+		public void setActionOutput(Short actionOutput) { actionOutputToUpdate = actionOutput; }
+	
+		@Override
+		public IFlowPath getFlow() { return flowPath; }
+	
+		@Override
+		public void setFlow(IFlowPath flow) { flowPathToUpdate = flow; }
+	
+		@Override
+		public ISwitchObject getSwitch() { return sw; }
+	
+		@Override
+		public void setSwitch(ISwitchObject sw) { swToUpdate = sw; }
+	
+		@Override
+		public IPortObject getInPort() { return inport; }
+	
+		@Override
+		public void setInPort(IPortObject port) { inportToUpdate = port; }
+	
+		@Override
+		public IPortObject getOutPort() { return outport; }
+	
+		@Override
+		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
+
+	}
+}
