Merge branch 'master' into netgraphrefactor
diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImpl.java b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImpl.java
index ac76def..91a225d 100644
--- a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImpl.java
+++ b/src/main/java/net/floodlightcontroller/linkdiscovery/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;
 	}
 
diff --git a/src/test/java/net/floodlightcontroller/core/internal/TestDatabaseManager.java b/src/test/java/net/floodlightcontroller/core/internal/TestDatabaseManager.java
index 431db71..2b93298 100644
--- a/src/test/java/net/floodlightcontroller/core/internal/TestDatabaseManager.java
+++ b/src/test/java/net/floodlightcontroller/core/internal/TestDatabaseManager.java
@@ -11,15 +11,13 @@
 import java.util.Set;
 
 import junit.framework.Assert;
-
-import net.floodlightcontroller.core.INetMapTopologyObjects.ISwitchObject;
-import net.floodlightcontroller.core.ISwitchStorage.SwitchState;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
 
 import org.apache.commons.io.FileUtils;
 
 import com.thinkaurelius.titan.core.TitanFactory;
 import com.thinkaurelius.titan.core.TitanGraph;
-import com.tinkerpop.blueprints.Edge;
 import com.tinkerpop.blueprints.TransactionalGraph.Conclusion;
 import com.tinkerpop.blueprints.Vertex;
 import com.tinkerpop.blueprints.util.io.graphml.GraphMLReader;
diff --git a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImplTest.java b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImplTest.java
index 0968fef..2c459de 100644
--- a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImplTest.java
+++ b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImplTest.java
@@ -5,16 +5,17 @@
 import static org.junit.Assert.assertTrue;
 
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 
-import net.floodlightcontroller.core.internal.TestDatabaseManager;
 import net.floodlightcontroller.linkdiscovery.LinkInfo;
+import net.floodlightcontroller.linkdiscovery.internal.TestGraphDBOperation.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.easymock.*;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Ignore;
@@ -25,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 TestGraphDBOperation ope;
 
 	/**
 	 * Setup code called before each tests.
@@ -50,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 TestGraphDBOperation();
+		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();
 	}
 	
 	/**
@@ -75,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
@@ -106,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);
 	}
 
 	/**
@@ -126,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);
 	}
 	
 	/**
@@ -147,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);
 	}
 
 	/**
@@ -168,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());
@@ -190,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());
 	}
 
 	/**
@@ -205,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());
@@ -227,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());
 	}
 
 	/**
@@ -242,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());
@@ -264,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
@@ -294,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);
 	}
 	
 	/**
@@ -315,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.
@@ -336,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);
 	}
 	
 	/**
@@ -397,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);
 	}
 	
 	/**
@@ -417,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());
@@ -432,8 +366,8 @@
 		
 		// Test deletion of mixture of new/existing links
 		linkStorage.deleteLinks(linksToDelete);
-		doTestLinkIsNotInGraph(createFeasibleLink());
-		doTestLinkIsNotInGraph(createExistingLink());
+		doTestLinkNotExist(createFeasibleLink());
+		doTestLinkNotExist(createExistingLink());
 	}
 
 	/**
@@ -460,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()));
 	}
 	
 	/**
@@ -518,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);
+		ope.createNewSwitchForTest(dpid2);
+		ope.createNewSwitchForTest(dpid3);
+
+		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);
 	}
 
 	/**
@@ -594,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;
 	}
 	
@@ -607,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/floodlightcontroller/linkdiscovery/internal/TestGraphDBOperation.java b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/TestGraphDBOperation.java
new file mode 100644
index 0000000..f4ed4c8
--- /dev/null
+++ b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/TestGraphDBOperation.java
@@ -0,0 +1,857 @@
+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.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.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;
+
+public class TestGraphDBOperation extends GraphDBOperation {
+	protected static Logger log = LoggerFactory.getLogger(TestGraphDBOperation.class);
+
+	protected List<TestSwitchObject> switches;
+	protected List<TestPortObject> ports;
+	protected List<TestDeviceObject> devices;
+//	protected List<TestFlowEntry> flows;
+
+	protected List<TestSwitchObject> switchesToAdd;
+	protected List<TestPortObject> portsToAdd;
+	protected List<TestDeviceObject> devicesToAdd;
+//	protected List<TestFlowEntry> flowsToAdd;
+
+	protected List<TestSwitchObject> switchesToRemove;
+	protected List<TestPortObject> portsToRemove;
+	protected List<TestDeviceObject> devicesToRemove;
+//	protected List<TestFlowEntry> flowsToRemove;
+
+
+	// Testable implementations of INetMapTopologyObject interfaces
+	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() {
+			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;
+		}
+		
+		public void addSwitchForTest(ISwitchObject sw) {
+			switches.add(sw);
+		}
+		
+		public void addPortForTest(IPortObject port) {
+			ports.add(port);
+		}
+		
+		@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 TestSwitchObject implements ISwitchObject {
+		private String state,type,dpid;
+		private List<IPortObject> ports;
+		private List<IDeviceObject> devices;
+		private List<IFlowEntry> flows;
+
+		private String stateToUpdate, typeToUpdate, dpidToUpdate;
+		private List<IPortObject> portsToAdd;
+		private List<IPortObject> portsToRemove;
+
+		public TestSwitchObject() {
+			type = "switch";
+			state = "ACTIVE";
+			
+			ports = new ArrayList<IPortObject>();
+			portsToAdd = new ArrayList<IPortObject>();
+			portsToRemove = new ArrayList<IPortObject>();
+			devices = new ArrayList<IDeviceObject>();
+			flows = 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 setDpidForTest(String dpid) { this.dpid = dpid; }
+		public void setStateForTest(String state) { this.state = state; }
+		public void setTypeForTest(String type) { this.type = type; }
+		public void addPortForTest(TestPortObject port) { ports.add(port);  }
+		
+		@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 flows; }
+	}
+	
+	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> flows;
+		
+		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";
+			state = "ACTIVE";
+
+			linkedPorts = new ArrayList<IPortObject>();
+			linkedPortsToAdd = new ArrayList<IPortObject>();
+			linkedPortsToRemove = new ArrayList<IPortObject>();
+			devices = new ArrayList<IDeviceObject>();
+			devicesToAdd = new ArrayList<IDeviceObject>();
+			devicesToRemove = new ArrayList<IDeviceObject>();
+			flows = 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;
+		}
+		
+		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); }
+		
+		@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() {
+			// TODO Auto-generated method stub
+			return null;
+		}
+
+		@Override
+		@JsonIgnore
+		@Incidence(label = "outport", direction = Direction.IN)
+		public Iterable<IFlowEntry> getOutFlowEntries() {
+			// TODO Auto-generated method stub
+			return null;
+		}
+
+		@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 TestGraphDBOperation() {
+		super(EasyMock.createNiceMock(GraphDBConnection.class));
+		
+		switches = new ArrayList<TestSwitchObject>();
+		ports = new ArrayList<TestPortObject>();
+		devices = new ArrayList<TestDeviceObject>();
+//		flows = new ArrayList<TestFlowEntry>();
+		
+		switchesToAdd = new ArrayList<TestSwitchObject>();
+		portsToAdd = new ArrayList<TestPortObject>();
+		devicesToAdd = new ArrayList<TestDeviceObject>();
+//		flowsToAdd = new ArrayList<TestFlowEntry>();
+
+		switchesToRemove = new ArrayList<TestSwitchObject>();
+		portsToRemove = new ArrayList<TestPortObject>();
+		devicesToRemove = new ArrayList<TestDeviceObject>();
+//		flowsToRemove = new ArrayList<TestFlowEntry>();
+		
+		clearUncommitedData();
+	}
+	
+	private void 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();
+		}
+		
+		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.
+	/**
+	 * 
+	 * @param dpid
+	 * @return
+	 */
+	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;
+	}
+	
+	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;
+		}
+	}
+	
+	public void setLinkBetweenPortsForTest(TestPortObject src, TestPortObject dst) {
+		src.addLinkedPortForTest(dst);
+		//dst.addLinkedPortForTest(src);
+	}
+	
+	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().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() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@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() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public IDeviceObject searchDevice(String macAddr) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Iterable<IDeviceObject> getDevices() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public void removeDevice(IDeviceObject dev) {
+		// TODO Auto-generated method stub
+
+	}
+
+	@Override
+	public IFlowPath newFlowPath() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public IFlowPath searchFlowPath(FlowId flowId) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public IFlowPath getFlowPathByFlowEntry(IFlowEntry flowEntry) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Iterable<IFlowPath> getAllFlowPaths() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public void removeFlowPath(IFlowPath flowPath) {
+		// TODO Auto-generated method stub
+
+	}
+
+	@Override
+	public IFlowEntry newFlowEntry() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public IFlowEntry searchFlowEntry(FlowEntryId flowEntryId) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Iterable<IFlowEntry> getAllFlowEntries() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public void removeFlowEntry(IFlowEntry flowEntry) {
+		// TODO Auto-generated method stub
+
+	}
+
+	@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
+
+	}
+}