diff --git a/src/main/java/net/onrc/onos/graph/LocalTopologyEventListener.java b/src/main/java/net/onrc/onos/graph/LocalTopologyEventListener.java
index 6a11eb2..72227d5 100644
--- a/src/main/java/net/onrc/onos/graph/LocalTopologyEventListener.java
+++ b/src/main/java/net/onrc/onos/graph/LocalTopologyEventListener.java
@@ -13,12 +13,12 @@
 import com.tinkerpop.blueprints.Vertex;
 
 public class LocalTopologyEventListener implements LocalGraphChangedListener {
-	
+
 	protected final static Logger log = LoggerFactory.getLogger(LocalTopologyEventListener.class);
 	protected static DBConnection conn;
-	
+
 	public LocalTopologyEventListener(DBConnection conn) {
-		LocalTopologyEventListener.conn = conn;		
+		LocalTopologyEventListener.conn = conn;
 	}
 
 	@Override
@@ -76,12 +76,12 @@
 	@Override
 	public void vertexRemoved(Vertex vertex, Map<String, Object> arg1) {
 		// TODO Auto-generated method stub
-		// Generate NetMapEvents 
+		// Generate NetMapEvents
 		String type = (String) vertex.getProperty("type");
 		log.debug("TopologyEvents: Received vertex removed event: {}",vertex);
 		if (type.equals("port")) {
 			// port is removed...lets fire reconcile here directly for now
-			
+
 			IPortObject src_port = (IPortObject) conn.getFramedGraph().frame(vertex, IPortObject.class);
 			log.debug("TopologyEvents: Port removed: {}:{}",src_port.getSwitch().getDPID(),src_port.getNumber());
 
@@ -97,15 +97,13 @@
 	public void edgePropertyChanged(Edge arg0, String arg1, Object arg2,
 			Object arg3) {
 		// TODO Auto-generated method stub
-		
+
 	}
 
 	@Override
 	public void vertexPropertyChanged(Vertex arg0, String arg1, Object arg2,
 			Object arg3) {
 		// TODO Auto-generated method stub
-		
-	}
 
 	}
 
diff --git a/src/test/java/net/onrc/onos/graph/GraphDBConnectionTest.java b/src/test/java/net/onrc/onos/graph/GraphDBConnectionTest.java
deleted file mode 100644
index b50f889..0000000
--- a/src/test/java/net/onrc/onos/graph/GraphDBConnectionTest.java
+++ /dev/null
@@ -1,231 +0,0 @@
-/**
- * 
- */
-package net.onrc.onos.graph;
-
-import static org.junit.Assert.*;
-import static org.easymock.EasyMock.expect;
-import static org.powermock.api.easymock.PowerMock.*;
-
-import java.util.*;
-
-import net.onrc.onos.graph.GraphDBOperation;
-
-import org.easymock.IAnswer;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-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.Vertex;
-import com.tinkerpop.blueprints.util.wrappers.event.EventTransactionalGraph;
-import com.tinkerpop.frames.FramedGraph;
-
-/**
- * @author Toshio Koide
- *
- */
-
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({
-	GraphDBConnection.class,
-	GraphDBOperation.class,
-	TitanFactory.class,
-	EventTransactionalGraph.class})
-public class GraphDBConnectionTest {
-	private static TitanGraph graph = null;
-	private static EventTransactionalGraph<TitanGraph> eg = null;
-	private static Boolean isGraphOpen = false;
-	/**
-	 * @throws java.lang.Exception
-	 */
-	@Before
-	public void setUp() throws Exception {
-	}
-
-	/**
-	 * @throws java.lang.Exception
-	 */
-	@After
-	public void tearDown() throws Exception {
-	}
-
-	
-	@SuppressWarnings("unchecked")
-	private void expectDBConnectionAvailable() throws Exception {
-		isGraphOpen = false;
-		
-		// create mock objects
-		mockStatic(TitanFactory.class);
-		mockStatic(EventTransactionalGraph.class);
-		graph = createMock(TitanGraph.class);
-		eg = (EventTransactionalGraph<TitanGraph>)createMock(EventTransactionalGraph.class);
-		
-		// setup expectations
-		expect(graph.isOpen()).andAnswer(new IAnswer<Boolean>() {
-			@Override
-			public Boolean answer() throws Throwable {
-				return isGraphOpen;
-			}
-		}).anyTimes();
-		expect(TitanFactory.open("/path/to/dummy")).andAnswer(new IAnswer<TitanGraph>() {
-			@Override
-			public TitanGraph answer() throws Throwable {
-				isGraphOpen = true;
-				return graph;
-			}
-		}).anyTimes();
-		expect(graph.getIndexedKeys(Vertex.class)).andReturn(new TreeSet<String>());
-		graph.createKeyIndex("dpid", Vertex.class);
-		graph.createKeyIndex("port_id", Vertex.class);
-		graph.createKeyIndex("type", Vertex.class);
-		graph.createKeyIndex("dl_addr", Vertex.class);
-		graph.createKeyIndex("flow_id", Vertex.class);
-		graph.createKeyIndex("flow_entry_id", Vertex.class);
-		graph.createKeyIndex("switch_state", Vertex.class);
-		graph.createKeyIndex("ipv4_address", Vertex.class);
-		graph.commit();
-		expectNew(EventTransactionalGraph.class, graph).andReturn(eg);
-	}
-	
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBConnection#getInstance(java.lang.String)}.
-	 * @throws Exception
-	 */
-	@Test
-	public final void testGetInstance() throws Exception {
-		// setup expectations
-		expectDBConnectionAvailable();
-		
-		// start the test
-		replayAll();
-		GraphDBConnection conn = GraphDBConnection.getInstance("/path/to/dummy");
-
-		// verify the test
-		verifyAll();
-		assertNotNull(conn);
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBConnection#getFramedGraph()}.
-	 * @throws Exception
-	 */
-	@Test
-	public final void testGetFramedGraph() throws Exception {
-		// setup expectations
-		expectDBConnectionAvailable();
-		
-		// start the test
-		replayAll();
-		GraphDBConnection conn = GraphDBConnection.getInstance("/path/to/dummy");
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		
-		// verify the test
-		verifyAll();
-		assertNotNull(fg);
-		assertEquals(graph, fg.getBaseGraph());
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBConnection#addEventListener(net.onrc.onos.graph.LocalGraphChangedListener)}.
-	 * @throws Exception 
-	 */
-	@Test
-	public final void testAddEventListener() throws Exception {
-		// instantiate required objects
-		LocalGraphChangedListener listener = new LocalTopologyEventListener(null);
-
-		// setup expectations
-		expectDBConnectionAvailable();
-		eg.addListener(listener);
-		
-		// start the test
-		replayAll();
-		GraphDBConnection conn = GraphDBConnection.getInstance("/path/to/dummy");
-		conn.addEventListener(listener);
-		
-		// verify the test
-		verifyAll();
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBConnection#isValid()}.
-	 * @throws Exception 
-	 */
-	@Test
-	public final void testIsValid() throws Exception {
-		// setup expectations
-		expectDBConnectionAvailable();
-
-		// start the test
-		replayAll();
-		GraphDBConnection conn = GraphDBConnection.getInstance("/path/to/dummy");
-		Boolean result = conn.isValid();
-		
-		// verify the test
-		verifyAll();
-		assertTrue(result);
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBConnection#commit()}.
-	 * @throws Exception 
-	 */
-	@Test
-	public final void testCommit() throws Exception {
-		// setup expectations
-		expectDBConnectionAvailable();
-		graph.commit();
-		
-		// start the test
-		replayAll();
-		GraphDBConnection conn = GraphDBConnection.getInstance("/path/to/dummy");
-		conn.commit();
-
-		// verify the test
-		verifyAll();
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBConnection#rollback()}.
-	 * @throws Exception 
-	 */
-	@Test
-	public final void testRollback() throws Exception {
-		// setup expectations
-		expectDBConnectionAvailable();
-		graph.rollback();
-		
-		// start the test
-		replayAll();
-		GraphDBConnection conn = GraphDBConnection.getInstance("/path/to/dummy");
-		conn.rollback();
-
-		// verify the test
-		verifyAll();
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBConnection#close()}.
-	 * @throws Exception 
-	 */
-	@Test
-	public final void testClose() throws Exception {
-		// setup expectations
-		expectDBConnectionAvailable();
-		graph.commit();
-		
-		// start the test
-		replayAll();
-		GraphDBConnection conn = GraphDBConnection.getInstance("/path/to/dummy");
-		conn.close();
-
-		// verify the test
-		verifyAll();
-	}
-
-}
diff --git a/src/test/java/net/onrc/onos/graph/GraphDBOperationTest.java b/src/test/java/net/onrc/onos/graph/GraphDBOperationTest.java
deleted file mode 100644
index b40d2af..0000000
--- a/src/test/java/net/onrc/onos/graph/GraphDBOperationTest.java
+++ /dev/null
@@ -1,648 +0,0 @@
-/**
- * 
- */
-package net.onrc.onos.graph;
-
-import static org.junit.Assert.assertArrayEquals;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-import junit.framework.TestCase;
-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.IIpv4Address;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
-import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
-import net.onrc.onos.ofcontroller.core.internal.TestDatabaseManager;
-import net.onrc.onos.ofcontroller.util.FlowEntryId;
-import net.onrc.onos.ofcontroller.util.FlowId;
-
-import org.easymock.EasyMock;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.powermock.api.easymock.PowerMock;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-import com.google.common.net.InetAddresses;
-import com.thinkaurelius.titan.core.TitanFactory;
-import com.thinkaurelius.titan.core.TitanGraph;
-import com.tinkerpop.blueprints.Vertex;
-
-/**
- * @author Toshio Koide
- *
- */
-
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({TitanFactory.class})
-public class GraphDBOperationTest extends TestCase {
-	private static TitanGraph testdb;
-	private static GraphDBOperation op;
-
-	/**
-	 * @throws java.lang.Exception
-	 */
-	@BeforeClass
-	public static void setUpBeforeClass() throws Exception {
-	}
-
-	/**
-	 * @throws java.lang.Exception
-	 */
-	@AfterClass
-	public static void tearDownAfterClass() throws Exception {
-	}
-
-	/**
-	 * @throws java.lang.Exception
-	 */
-	@Before
-	public void setUp() throws Exception {
-		TestDatabaseManager.deleteTestDatabase();
-		testdb = TestDatabaseManager.getTestDatabase();
-//		TestDatabaseManager.populateTestData(titanGraph);
-
-		String dummyPath = "/dummy/to/conf";
-		// replace return value of TitanFactory.open() to dummy DB created above
-		PowerMock.mockStatic(TitanFactory.class);
-		EasyMock.expect(TitanFactory.open(dummyPath)).andReturn(testdb);
-		PowerMock.replay(TitanFactory.class);
-		
-		op = new GraphDBOperation(dummyPath);
-	}
-
-	/**
-	 * @throws java.lang.Exception
-	 */
-	@After
-	public void tearDown() throws Exception {
-		op.close();
-		testdb.shutdown();
-		PowerMock.verifyAll();
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#newSwitch(net.onrc.onos.graph.GraphDBConnection)}.
-	 */
-	@Test
-	public final void testNewSwitch() {
-		assertNull(op.searchSwitch("123"));
-
-		ISwitchObject sw = op.newSwitch("123");
-		assertEquals(sw.getDPID(), "123");
-		op.commit();
-
-		sw = op.searchSwitch("123");
-		assertNotNull(sw);
-		assertEquals("123", sw.getDPID());
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#searchSwitch(net.onrc.onos.graph.GraphDBConnection, java.lang.String)}.
-	 */
-	@Test
-	public final void testSearchSwitch() {
-		op.newSwitch("123");
-		op.newSwitch("456");
-		op.commit();
-
-		ISwitchObject sw = op.searchSwitch("123");
-		assertNotNull(sw);
-		assertEquals("123", sw.getDPID());
-
-		sw = op.searchSwitch("789");
-		assertNull(sw);
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#searchActiveSwitch(net.onrc.onos.graph.GraphDBConnection, java.lang.String)}.
-	 */
-	@Test
-	public final void testSearchActiveSwitch() {
-		op.newSwitch("111").setState(SwitchState.ACTIVE.toString());
-		op.newSwitch("222").setState(SwitchState.INACTIVE.toString());
-		op.commit();
-		
-		ISwitchObject sw = op.searchActiveSwitch("111");
-		assertNotNull(sw);
-		assertEquals("111", sw.getDPID());
-		
-		sw = op.searchActiveSwitch("222");
-		assertNull(sw);	
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#getActiveSwitches(net.onrc.onos.graph.GraphDBConnection)}.
-	 */
-	@Test
-	public final void testGetActiveSwitches() {
-		op.newSwitch("111").setState(SwitchState.ACTIVE.toString());
-		op.newSwitch("222").setState(SwitchState.INACTIVE.toString());
-		op.commit();
-		
-		Iterator<ISwitchObject> i = op.getActiveSwitches().iterator();
-		
-		assertTrue(i.hasNext());
-		assertEquals("111", i.next().getDPID());
-		assertFalse(i.hasNext());
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#getAllSwitches(net.onrc.onos.graph.GraphDBConnection)}.
-	 */
-	@Test
-	public final void testGetAllSwitches() {
-		List<String> dpids = Arrays.asList("111", "222", "333");
-		Collections.sort(dpids);
-		
-		for (String dpid: dpids) op.newSwitch(dpid);
-		op.commit();
-
-		List<String> actual_ids = new ArrayList<String>();
-		for (ISwitchObject switchObj: op.getAllSwitches()) actual_ids.add(switchObj.getDPID());
-		Collections.sort(actual_ids);
-
-		assertArrayEquals(dpids.toArray(), actual_ids.toArray());
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#getInactiveSwitches(net.onrc.onos.graph.GraphDBConnection)}.
-	 */
-	@Test
-	public final void testGetInactiveSwitches() {
-		op.newSwitch("111").setState(SwitchState.ACTIVE.toString());
-		op.newSwitch("222").setState(SwitchState.INACTIVE.toString());
-		op.commit();
-		
-		Iterator<ISwitchObject> i = op.getInactiveSwitches().iterator();
-		
-		assertTrue(i.hasNext());
-		assertEquals("222", i.next().getDPID());
-		assertFalse(i.hasNext());
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#getAllSwitchNotUpdatedFlowEntries(net.onrc.onos.graph.GraphDBConnection)}.
-	 */
-	@Test
-	public final void testGetAllSwitchNotUpdatedFlowEntries() {
-		FlowEntryId flowEntryId10 = new FlowEntryId(10);
-		FlowEntryId flowEntryId20 = new FlowEntryId(20);
-		IFlowEntry flowEntry10 = op.newFlowEntry();
-		IFlowEntry flowEntry20 = op.newFlowEntry();
-		flowEntry10.setFlowEntryId(flowEntryId10.toString());
-		flowEntry20.setFlowEntryId(flowEntryId20.toString());
-		flowEntry10.setSwitchState("FE_SWITCH_NOT_UPDATED");
-		flowEntry20.setSwitchState("FE_SWITCH_UPDATED");
- 		op.commit();
-		
-		Iterator<IFlowEntry> flowEntries = op.getAllSwitchNotUpdatedFlowEntries().iterator();
-		assertNotNull(flowEntries);
-		assertTrue(flowEntries.hasNext());
-		assertEquals(flowEntryId10.toString(), flowEntries.next().getFlowEntryId());
-		assertFalse(flowEntries.hasNext());
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#removeSwitch(net.onrc.onos.graph.GraphDBConnection, net.floodlightcontroller.core.INetMapTopologyObjects.ISwitchObject)}.
-	 */
-	@Test
-	public final void testRemoveSwitch() {
-		ISwitchObject sw = op.newSwitch("123");
-		op.commit();	
-		sw = op.searchSwitch("123");
-		assertNotNull(sw);
-
-		op.removeSwitch(sw);
-		op.commit();
-		
-		assertNull(op.searchSwitch("123"));
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#newPort(net.onrc.onos.graph.GraphDBConnection)}.
-	 */
-	@Test
-	public final void testNewPort() {
-		assertFalse(testdb.getVertices("type", "port").iterator().hasNext());
-		
-		IPortObject port = op.newPort("1", (short) 10);
-		assertTrue(port.getNumber() == 10);
-		op.commit();
-		
-		Iterator<Vertex> vertices = testdb.getVertices("type", "port").iterator();
-		assertTrue(vertices.hasNext());
-		assertEquals(vertices.next().getProperty("number").toString(), "10");		
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#searchPort(net.onrc.onos.graph.GraphDBConnection, java.lang.String, short)}.
-	 */
-	@Test
-	public final void testSearchPort() {
-		ISwitchObject sw;
-		IPortObject port;
-		
-		sw = op.newSwitch("1");
-		sw.addPort(op.newPort("1", (short) 1));
-		sw.addPort(op.newPort("1", (short) 2));
-		
-		sw = op.newSwitch("2");
-		sw.addPort(op.newPort("2", (short) 1));
-		sw.addPort(op.newPort("2", (short) 2));
-
-		op.commit();
-
-		assertNull(op.searchPort("3", (short) 1));
-		assertNull(op.searchPort("1", (short) 3));
-
-		port = op.searchPort("1", (short) 1);
-		assertNotNull(port);
-		assertTrue(port.getNumber() == 1);
-		sw = port.getSwitch();
-		assertNotNull(sw);
-		assertEquals("1", sw.getDPID());
-
-		port = op.searchPort("1", (short) 2);
-		assertNotNull(port);
-		assertTrue(port.getNumber() == 2);
-		sw = port.getSwitch();
-		assertNotNull(sw);
-		assertEquals("1", sw.getDPID());
-
-		port = op.searchPort("2", (short) 1);
-		assertNotNull(port);
-		assertTrue(port.getNumber() == 1);
-		sw = port.getSwitch();
-		assertNotNull(sw);
-		assertEquals("2", sw.getDPID());
-
-		port = op.searchPort("2", (short) 2);
-		assertNotNull(port);
-		assertTrue(port.getNumber() == 2);
-		sw = port.getSwitch();
-		assertNotNull(sw);
-		assertEquals("2", sw.getDPID());
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#removePort(net.onrc.onos.graph.GraphDBConnection, net.floodlightcontroller.core.INetMapTopologyObjects.IPortObject)}.
-	 */
-	@Test
-	public final void testRemovePort() {
-		ISwitchObject sw;
-		IPortObject port;
-		
-		sw = op.newSwitch("1");
-		sw.addPort(op.newPort("1", (short) 1));
-		sw.addPort(op.newPort("1", (short) 2));
-		
-		op.commit();
-
-		port = op.searchPort("1", (short) 1);
-		assertNotNull(port);
-		assertNotNull(op.searchPort("1", (short) 2));
-		assertNull(op.searchPort("1", (short) 3));
-
-		op.removePort(port);
-		op.commit();
-		
-		assertNull(op.searchPort("1", (short) 1));
-		port = op.searchPort("1", (short) 2);
-		assertNotNull(port);
-		
-		op.removePort(port);
-		op.commit();
-
-		assertNull(op.searchPort("1", (short) 1));
-		assertNull(op.searchPort("1", (short) 2));
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#newDevice(net.onrc.onos.graph.GraphDBConnection)}.
-	 */
-	@Test
-	public final void testNewDevice() {
-		assertFalse(testdb.getVertices("type", "device").iterator().hasNext());
-		
-		IDeviceObject device = op.newDevice();
-		device.setMACAddress("11:22:33:44:55:66");
-		//device.setIPAddress("192.168.1.1");
-		op.commit();
-		
-		Iterator<Vertex> vertices = testdb.getVertices("type", "device").iterator();
-		assertTrue(vertices.hasNext());
-		Vertex v = vertices.next();
-		assertEquals("11:22:33:44:55:66", v.getProperty("dl_addr").toString());
-		//assertEquals("192.168.1.1", v.getProperty("nw_addr").toString());
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#searchDevice(net.onrc.onos.graph.GraphDBConnection, java.lang.String)}.
-	 */
-	@Test
-	public final void testSearchDevice() {
-		assertNull(op.searchDevice("11:22:33:44:55:66"));
-		assertNull(op.searchDevice("66:55:44:33:22:11"));
-
-		op.newDevice().setMACAddress("11:22:33:44:55:66");
-		op.commit();
-		
-		IDeviceObject device = op.searchDevice("11:22:33:44:55:66");
-		assertNotNull(device);
-		assertEquals("11:22:33:44:55:66", device.getMACAddress());
-		
-		assertNull(op.searchDevice("66:55:44:33:22:11"));
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#getDevices(net.onrc.onos.graph.GraphDBConnection)}.
-	 */
-	@Test
-	public final void testGetDevices() {
-		List<String> original_macs = Arrays.asList(
-				"11:11:11:11:11:11",
-				"22:22:22:22:22:22",
-				"33:33:33:33:33:33"
-				);
-		
-		for (String mac: original_macs) op.newDevice().setMACAddress(mac);
-		op.commit();
-		
-		Iterable<IDeviceObject> devices = op.getDevices();
-		List<String> macs = new ArrayList<String>();
-		for (IDeviceObject device: devices) macs.add(device.getMACAddress());
-		Collections.sort(macs);
-		assertArrayEquals(original_macs.toArray(), macs.toArray());
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#removeDevice(net.onrc.onos.graph.GraphDBConnection, net.floodlightcontroller.core.INetMapTopologyObjects.IDeviceObject)}.
-	 */
-	@Test
-	public final void testRemoveDevice() {
-		op.newDevice().setMACAddress("11:22:33:44:55:66");
-		op.commit();
-		
-		op.removeDevice(op.searchDevice("11:22:33:44:55:66"));
-		op.commit();
-		assertNull(op.searchDevice("11:22:33:44:55:66"));
-	}
-	
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#newIpv4Address(net.onrc.onos.graph.GraphDBConnection, net.floodlightcontroller.core.INetMapTopologyObjects.IIpv4Address)}.
-	 */
-	@Test
-	public final void testNewIpv4Address() {
-		int intIpv4Address = InetAddresses.coerceToInteger(InetAddresses.forString("192.168.10.1"));
-		
-		assertFalse(testdb.getVertices("type", "ipv4Address").iterator().hasNext());
-		
-		IIpv4Address ipv4Address = op.newIpv4Address();
-		ipv4Address.setIpv4Address(intIpv4Address);
-		//device.setIPAddress("192.168.1.1");
-		op.commit();
-		
-		Iterator<Vertex> vertices = testdb.getVertices("type", "ipv4Address").iterator();
-		assertTrue(vertices.hasNext());
-		Vertex v = vertices.next();
-		assertEquals(intIpv4Address, ((Integer) v.getProperty("ipv4_address")).intValue());
-	}
-	
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#searchIpv4Address(net.onrc.onos.graph.GraphDBConnection, net.floodlightcontroller.core.INetMapTopologyObjects.IIpv4Address)}.
-	 */
-	@Test
-	public final void testSearchIpv4Address() {
-		int addr1 = InetAddresses.coerceToInteger(InetAddresses.forString("192.168.20.1"));
-		int addr2 = InetAddresses.coerceToInteger(InetAddresses.forString("59.203.2.15"));
-		
-		assertNull(op.searchIpv4Address(addr1));
-		assertNull(op.searchIpv4Address(addr2));
-
-		op.newIpv4Address().setIpv4Address(addr1);
-		op.commit();
-		
-		IIpv4Address ipv4Address = op.searchIpv4Address(addr1);
-		assertNotNull(ipv4Address);
-		assertEquals(addr1, ipv4Address.getIpv4Address());
-		
-		assertNull(op.searchIpv4Address(addr2));
-	}
-	
-	@Ignore
-	@Test
-	public final void testEnsureIpv4Address() {
-		// TODO not yet implemented
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#newFlowPath(net.onrc.onos.graph.GraphDBConnection)}.
-	 */
-	@Test
-	public final void testNewFlowPath() {
-		FlowId flowId = new FlowId(10);
-		IFlowPath flowPath = op.newFlowPath();
-		flowPath.setFlowId(flowId.toString());
-		op.commit();
-
-		Iterator<IFlowPath> flows = op.getAllFlowPaths().iterator();
-		assertTrue(flows.hasNext());
-		assertEquals(flowId.toString(), flows.next().getFlowId());
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#searchFlowPath(net.onrc.onos.graph.GraphDBConnection, net.floodlightcontroller.util.FlowId)}.
-	 */
-	@Test
-	public final void testSearchFlowPath() {
-		FlowId flowId = new FlowId(20);
-		assertNull(op.searchFlowPath(flowId));
-
-		op.newFlowPath().setFlowId(flowId.toString());
-		op.commit();
-		
-		IFlowPath flowPath = op.searchFlowPath(flowId);
-		assertNotNull(flowPath);
-		assertEquals(flowId.toString(), flowPath.getFlowId());
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#getFlowPathByFlowEntry(net.onrc.onos.graph.GraphDBConnection, net.floodlightcontroller.core.INetMapTopologyObjects.IFlowEntry)}.
-	 */
-	@Test
-	public final void testGetFlowPathByFlowEntry() {
-		FlowId flowId10 = new FlowId(10);
-		FlowId flowId20 = new FlowId(20);
-		IFlowPath flowPath10 = op.newFlowPath();
-		IFlowPath flowPath20 = op.newFlowPath();
-		IFlowEntry flowEntry10 = op.newFlowEntry();
-		IFlowEntry flowEntry20 = op.newFlowEntry();
-		IFlowEntry flowEntry30 = op.newFlowEntry();
-		FlowEntryId flowEntryId10 = new FlowEntryId(10); 
-		FlowEntryId flowEntryId20 = new FlowEntryId(20); 
-		FlowEntryId flowEntryId30 = new FlowEntryId(30); 
-		flowEntry10.setFlowEntryId(flowEntryId10.toString());
-		flowEntry20.setFlowEntryId(flowEntryId20.toString());
-		flowEntry30.setFlowEntryId(flowEntryId30.toString());
-		flowPath10.setFlowId(flowId10.toString());
-		flowPath10.addFlowEntry(flowEntry10);
-		flowPath20.setFlowId(flowId20.toString());
-		flowPath20.addFlowEntry(flowEntry20);
-		op.commit();
-
-		flowEntry10 = op.searchFlowEntry(flowEntryId10);
-		IFlowPath obtainedFlowPath = op.getFlowPathByFlowEntry(flowEntry10);
-		assertNotNull(obtainedFlowPath);
-		assertEquals(flowId10.toString(), obtainedFlowPath.getFlowId());
-		
-		flowEntry20 = op.searchFlowEntry(flowEntryId20);
-		obtainedFlowPath = op.getFlowPathByFlowEntry(flowEntry20);
-		assertNotNull(obtainedFlowPath);
-		assertEquals(flowId20.toString(), obtainedFlowPath.getFlowId());
-		
-		flowEntry30 = op.searchFlowEntry(flowEntryId30);
-		obtainedFlowPath = op.getFlowPathByFlowEntry(flowEntry30);
-		assertNull(obtainedFlowPath);
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#getAllFlowPaths(net.onrc.onos.graph.GraphDBConnection)}.
-	 */
-	@Test
-	public final void testGetAllFlowPaths() {
-		List<FlowId> flowids = Arrays.asList(
-				new FlowId(10), new FlowId(20), new FlowId(30)
-				);
-		
-		for (FlowId flowId: flowids)
-			op.newFlowPath().setFlowId(flowId.toString());
-		op.commit();
-
-		List<String> actual_ids = new ArrayList<String>();
-		for (IFlowPath flowPath: op.getAllFlowPaths()) actual_ids.add(flowPath.getFlowId());
-		Collections.sort(actual_ids);
-
-		List<String> expected_ids = new ArrayList<String>();
-		for (FlowId flowid: flowids) expected_ids.add(flowid.toString());
-		Collections.sort(expected_ids);
-		
-		assertArrayEquals(expected_ids.toArray(), actual_ids.toArray());
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#removeFlowPath(net.onrc.onos.graph.GraphDBConnection, net.floodlightcontroller.core.INetMapTopologyObjects.IFlowPath)}.
-	 */
-	@Test
-	public final void testRemoveFlowPath() {
-		FlowId flowId10 = new FlowId(10);
-		FlowId flowId20 = new FlowId(20);
-		op.newFlowPath().setFlowId(flowId10.toString());
-		op.newFlowPath().setFlowId(flowId20.toString());
-		op.commit();
-		
-		IFlowPath flowPath = op.searchFlowPath(flowId10);
-		assertNotNull(flowPath);
-		op.removeFlowPath(flowPath);
-		op.commit();
-		
-		assertNull(op.searchFlowPath(flowId10));
-		assertNotNull(op.searchFlowPath(flowId20));
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#newFlowEntry(net.onrc.onos.graph.GraphDBConnection)}.
-	 */
-	@Test
-	public final void testNewFlowEntry() {
-		IFlowEntry flowEntry = op.newFlowEntry();
-		FlowEntryId flowEntryId = new FlowEntryId();
-		flowEntryId.setValue(12345);
-		flowEntry.setFlowEntryId(flowEntryId.toString());
-		op.commit();
-		
-		flowEntry = op.searchFlowEntry(flowEntryId);
-		assertNotNull(flowEntry);
-		assertEquals(flowEntry.getFlowEntryId(), flowEntryId.toString());		
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#searchFlowEntry(net.onrc.onos.graph.GraphDBConnection, net.floodlightcontroller.util.FlowEntryId)}.
-	 */
-	@Test
-	public final void testSearchFlowEntry() {
-		FlowEntryId flowEntryId10 = new FlowEntryId();
-		flowEntryId10.setValue(10);
-		FlowEntryId flowEntryId20 = new FlowEntryId();
-		flowEntryId20.setValue(20);
-		FlowEntryId flowEntryId30 = new FlowEntryId();
-		flowEntryId30.setValue(30);
-		
-		op.newFlowEntry().setFlowEntryId(flowEntryId10.toString());
-		op.newFlowEntry().setFlowEntryId(flowEntryId20.toString());
-		op.commit();
-		
-		assertNull(op.searchFlowEntry(flowEntryId30));
-		IFlowEntry flowEntry = op.searchFlowEntry(flowEntryId10);
-		assertEquals(flowEntry.getFlowEntryId(), flowEntryId10.toString());
-		flowEntry = op.searchFlowEntry(flowEntryId20);
-		assertEquals(flowEntry.getFlowEntryId(), flowEntryId20.toString());
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#getAllFlowEntries(net.onrc.onos.graph.GraphDBConnection)}.
-	 */
-	@Test
-	public final void testGetAllFlowEntries() {
-		List<FlowEntryId> flowEntryIds = Arrays.asList(
-				new FlowEntryId(10), new FlowEntryId(20), new FlowEntryId(30)
-				);
-		
-		for (FlowEntryId flowEntryId: flowEntryIds)
-			op.newFlowEntry().setFlowEntryId(flowEntryId.toString());
-		op.commit();
-
-		List<String> actual_ids = new ArrayList<String>();
-		for (IFlowEntry flowEntry: op.getAllFlowEntries()) actual_ids.add(flowEntry.getFlowEntryId());
-		Collections.sort(actual_ids);
-
-		List<String> expected_ids = new ArrayList<String>();
-		for (FlowEntryId flowEntryId: flowEntryIds) expected_ids.add(flowEntryId.toString());
-		Collections.sort(expected_ids);
-		
-		assertArrayEquals(expected_ids.toArray(), actual_ids.toArray());
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#removeFlowEntry(net.onrc.onos.graph.GraphDBConnection, net.floodlightcontroller.core.INetMapTopologyObjects.IFlowEntry)}.
-	 */
-	@Test
-	public final void testRemoveFlowEntry() {
-		FlowEntryId flowEntryId10 = new FlowEntryId(10);
-		FlowEntryId flowEntryId20 = new FlowEntryId(20);
-		op.newFlowEntry().setFlowEntryId(flowEntryId10.toString());
-		op.newFlowEntry().setFlowEntryId(flowEntryId20.toString());
-		op.commit();
-		
-		IFlowEntry flowEntry = op.searchFlowEntry(flowEntryId10);
-		assertNotNull(flowEntry);
-		op.removeFlowEntry(flowEntry);
-		op.commit();
-		
-		assertNull(op.searchFlowEntry(flowEntryId10));
-		assertNotNull(op.searchFlowEntry(flowEntryId20));
-	}
-
-}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIDeviceObjectTest.java b/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIDeviceObjectTest.java
deleted file mode 100644
index 7bd75d2..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIDeviceObjectTest.java
+++ /dev/null
@@ -1,206 +0,0 @@
-package net.onrc.onos.ofcontroller.core;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.util.HashMap;
-
-import net.onrc.onos.graph.GraphDBConnection;
-import net.onrc.onos.graph.GraphDBOperation;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IIpv4Address;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
-import net.onrc.onos.ofcontroller.core.internal.SwitchStorageImpl;
-import net.onrc.onos.ofcontroller.core.internal.TestDatabaseManager;
-
-import org.easymock.EasyMock;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.powermock.api.easymock.PowerMock;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.net.InetAddresses;
-import com.thinkaurelius.titan.core.TitanFactory;
-import com.thinkaurelius.titan.core.TitanGraph;
-
-//Add Powermock preparation
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({TitanFactory.class, GraphDBConnection.class, GraphDBOperation.class, SwitchStorageImpl.class})
-public class INetMapTopologyObjectsIDeviceObjectTest {
-	
-	//The test network is ./titan/schema/test-network.xml
-
-	protected static org.slf4j.Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
-
-	String conf;
-    private GraphDBConnection conn = null;
-    private GraphDBOperation ope = null;
-    private TitanGraph titanGraph = null;
-	
-	@Before
-	public void setUp() throws Exception {
-		conf = "/dummy/path/to/db";
-		
-		// Make mock cassandra DB
-		// Replace TitanFactory.open() to return mock DB
-		TestDatabaseManager.deleteTestDatabase();
-		titanGraph = TestDatabaseManager.getTestDatabase();
-		//TestDatabaseManager.populateTestData(titanGraph);
-		PowerMock.mockStatic(TitanFactory.class);
-		EasyMock.expect(TitanFactory.open((String)EasyMock.anyObject())).andReturn(titanGraph);
-		PowerMock.replay(TitanFactory.class);
-		
-		conn = GraphDBConnection.getInstance(conf);
-		ope = new GraphDBOperation(conn);
-	}
-
-	@After
-	public void tearDown() throws Exception {
-		titanGraph.shutdown();
-		TestDatabaseManager.deleteTestDatabase();
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for get and set MacAddress method.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set the mac address.
-	 * 2. Should get the mac address.
-	 */
-	@Test
-	public void testSetGetMacAddress() {
-		String macaddr = "00:00:00:00:00:00:0a:07";
-		IDeviceObject devObj = ope.newDevice();
-		devObj.setMACAddress(macaddr);
-		assertEquals(devObj.getMACAddress(), macaddr);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for get and set IPAddress method.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set the ip address.
-	 * 2. Should get the ip address.
-	 */
-	@Test
-	public void testSetGetIPAddress() {
-		int ipaddr = InetAddresses.coerceToInteger(InetAddresses.forString("192.168.0.1"));
-		IDeviceObject devObj = ope.newDevice();
-		IIpv4Address ipv4Address = ope.newIpv4Address();
-		ipv4Address.setIpv4Address(ipaddr);
-		devObj.addIpv4Address(ipv4Address);
-		assertEquals(devObj.getIpv4Address(ipaddr), ipv4Address);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for get attached port.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should get the attached ports.
-	 */
-	@Test
-	public void testGetAttachedPort() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		Short number = 1;	
-		Short number2 = 2;
-		IPortObject portObj = ope.newPort(dpid, number);
-		IPortObject portObj2 = ope.newPort(dpid, number2);
-		
-		IDeviceObject devObj = ope.newDevice();
-		
-		portObj.setDevice(devObj);
-		portObj2.setDevice(devObj);
-		
-		HashMap<Short, IPortObject> portObjectList = new HashMap<Short, IPortObject>();
-		for(IPortObject port : devObj.getAttachedPorts())
-		{
-			portObjectList.put(port.getNumber(), port);
-		}
-		
-		assertTrue(portObjectList.containsValue(portObj));
-		assertTrue(portObjectList.containsValue(portObj2));
-		
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for set and remove host port method.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set host port from the device.
-	 * 2. Should remove host port from the device.
-	 */
-	@Test
-	public void testSetRemoveHostPort() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		Short number = 1;	
-		IPortObject portObj = ope.newPort(dpid, number);
-		
-		IDeviceObject devObj = ope.newDevice();
-		
-		devObj.setHostPort(portObj);
-		
-		HashMap<String, IDeviceObject> portObjectList = new HashMap<String, IDeviceObject>();
-		for(IDeviceObject dev : portObj.getDevices())
-		{
-			portObjectList.put(dev.getMACAddress(), dev);
-		}
-		assertTrue(portObjectList.containsValue(devObj));
-		
-		devObj.removeHostPort(portObj);
-		
-		HashMap<String, IDeviceObject> portObjectList2 = new HashMap<String, IDeviceObject>();
-		for(IDeviceObject dev : portObj.getDevices())
-		{
-			portObjectList2.put(dev.getMACAddress(), dev);
-		}
-		assertTrue(!portObjectList2.containsValue(devObj));
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for getSwitch method.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should get the switch connected to the device.
-	 */
-	@Test
-	public void testGetSwitches() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		String dpid2 = "00:00:00:00:00:00:0a:08";
-		Short number = 1;	
-		Short number2 = 2;	
-		ISwitchObject swObj = ope.newSwitch(dpid);
-		ISwitchObject swObj2 = ope.newSwitch(dpid2);
-		IPortObject portObj = ope.newPort(dpid, number);
-		IPortObject portObj2 = ope.newPort(dpid2, number2);
-		swObj.addPort(portObj);
-		swObj2.addPort(portObj2);
-		IDeviceObject devObj = ope.newDevice();
-		portObj.setDevice(devObj);
-		portObj2.setDevice(devObj);
-		
-		HashMap<String, ISwitchObject> switchObjectList = new HashMap<String, ISwitchObject>();
-		for(ISwitchObject sw : devObj.getSwitch())
-		{
-			switchObjectList.put(sw.getDPID(), sw);
-		}
-		assertTrue(switchObjectList.containsValue(swObj));
-		assertTrue(switchObjectList.containsValue(swObj2));
-	}
-	
-	
-}
\ No newline at end of file
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIFlowEntryTest.java b/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIFlowEntryTest.java
deleted file mode 100644
index f1c2c71..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIFlowEntryTest.java
+++ /dev/null
@@ -1,476 +0,0 @@
-package net.onrc.onos.ofcontroller.core;
-
-import static org.junit.Assert.*;
-
-import net.onrc.onos.graph.GraphDBConnection;
-import net.onrc.onos.graph.GraphDBOperation;
-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.core.internal.SwitchStorageImpl;
-import net.onrc.onos.ofcontroller.core.internal.TestDatabaseManager;
-import org.easymock.EasyMock;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.powermock.api.easymock.PowerMock;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.slf4j.LoggerFactory;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-import com.thinkaurelius.titan.core.TitanFactory;
-import com.thinkaurelius.titan.core.TitanGraph;
-
-//Add Powermock preparation
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({TitanFactory.class, GraphDBConnection.class, GraphDBOperation.class, SwitchStorageImpl.class})
-public class INetMapTopologyObjectsIFlowEntryTest {
-	
-	//The test network is ./titan/schema/test-network.xml
-
-	protected static org.slf4j.Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
-
-	String conf;
-    private GraphDBConnection conn = null;
-    private GraphDBOperation ope = null;
-    private TitanGraph titanGraph = null;
-	private IFlowEntry flowEntry = null;
-	
-	@Before
-	public void setUp() throws Exception {
-		conf = "/dummy/path/to/db";
-		
-		// Make mock cassandra DB
-		// Replace TitanFactory.open() to return mock DB
-		TestDatabaseManager.deleteTestDatabase();
-		titanGraph = TestDatabaseManager.getTestDatabase();
-		//TestDatabaseManager.populateTestData(titanGraph);
-		PowerMock.mockStatic(TitanFactory.class);
-		EasyMock.expect(TitanFactory.open((String)EasyMock.anyObject())).andReturn(titanGraph);
-		PowerMock.replay(TitanFactory.class);
-		
-		conn = GraphDBConnection.getInstance(conf);
-		ope = new GraphDBOperation(conn);
-		
-		flowEntry = ope.newFlowEntry();
-	}
-
-	@After
-	public void tearDown() throws Exception {
-		titanGraph.shutdown();
-		TestDatabaseManager.deleteTestDatabase();
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for set and get FlowEntryId.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set FlowEntryId.
-	 * 2. Should get FlowEntryId.
-	 */
-	@Test
-	public void testSetGetFlowEntryId() {
-		String flowEntryId = "xx";
-		flowEntry.setFlowEntryId(flowEntryId);
-		assertEquals(flowEntry.getFlowEntryId(), flowEntryId);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for set and get Idle Timeout.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set Idle Timeout.
-	 * 2. Should get Idle Timeout.
-	 */
-	@Test
-	public void testSetGetIdleTimeout() {
-		Integer idleTimeout = 5;
-		flowEntry.setIdleTimeout(idleTimeout);
-		assertEquals(flowEntry.getIdleTimeout(), idleTimeout);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for set and get Hard Timeout.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set Hard Timeout.
-	 * 2. Should get Hard Timeout.
-	 */
-	@Test
-	public void testSetGetHardTimeout() {
-		Integer hardTimeout = 5;
-		flowEntry.setHardTimeout(hardTimeout);
-		assertEquals(flowEntry.getHardTimeout(), hardTimeout);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for set and get SwitchDpid.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set SwitchDpid.
-	 * 2. Should get SwitchDpid.
-	 */
-	@Test
-	public void testSetGetSwitchDpid() {
-		String switchDpid = "00:00:00:00:00:11";
-		flowEntry.setSwitchDpid(switchDpid);
-		assertEquals(flowEntry.getSwitchDpid(), switchDpid);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for set and get UserState.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set UserState.
-	 * 2. Should get UserState.
-	 */
-	@Test
-	public void testSetGetUserState() {
-		String userStete = "good";
-		flowEntry.setUserState(userStete);
-		assertEquals(flowEntry.getUserState(), userStete);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for set and get SwitchState.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set SwitchState.
-	 * 2. Should get SwitchState.
-	 */
-	@Test
-	public void testSetGetSwitchState() {
-		String switchStete = "ACTIVE";
-		flowEntry.setSwitchState(switchStete);
-		assertEquals(flowEntry.getSwitchState(), switchStete);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for set and get ErrorStateType.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set ErrorStateType.
-	 * 2. Should get ErrorStateType.
-	 */
-	@Test
-	public void testSetGetErrorStateType() {
-		String errorSteteType = "error";
-		flowEntry.setErrorStateType(errorSteteType);
-		assertEquals(flowEntry.getErrorStateType(), errorSteteType);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for set and get ErrorStateCode.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set ErrorStateCode.
-	 * 2. Should get ErrorStateCode.
-	 */
-	@Test
-	public void testSetGetErrorStateCode() {
-		String errorSteteCode = "error";
-		flowEntry.setErrorStateCode(errorSteteCode);
-		assertEquals(flowEntry.getErrorStateCode(), errorSteteCode);
-	}	
-	
-	/**
-	 * Desc:
-	 *  Test method for set and get MatchInPort.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchInPort.
-	 * 2. Should get MatchInPort.
-	 */
-	@Test
-	public void testSetGetMatchInPort() {
-		Short inPort = 1;
-		flowEntry.setMatchInPort(inPort);
-		assertEquals(flowEntry.getMatchInPort(), inPort);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for set and get MatchSrcMac.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchSrcMac.
-	 * 2. Should get MatchSrcMac.
-	 */
-	@Test
-	public void testSetGetMatchSrcMac() {
-		String matchSrcMac = "00:00:00:00:00:11";
-		flowEntry.setMatchSrcMac(matchSrcMac);
-		assertEquals(flowEntry.getMatchSrcMac(), matchSrcMac);
-	}	
-	
-	/**
-	 * Desc:
-	 *  Test method for set and get MatchDstMac.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchDstMac.
-	 * 2. Should get MatchDstMac.
-	 */
-	@Test
-	public void testSetGetMatchDstMac() {
-		String matchDstMac = "00:00:00:00:00:11";
-		flowEntry.setMatchDstMac(matchDstMac);
-		assertEquals(flowEntry.getMatchDstMac(), matchDstMac);
-	}	
-
-	/**
-	 * Desc:
-	 *  Test method for set and get MatchEthernetFrameType.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchEthernetFrameType.
-	 * 2. Should get MatchEthernetFrameType.
-	 */
-	@Test
-	public void testSetGetMatchEthernetFrameType() {
-		Short matchEthernetFrameType = 1;
-		flowEntry.setMatchEthernetFrameType(matchEthernetFrameType);
-		assertEquals(flowEntry.getMatchEthernetFrameType(), matchEthernetFrameType);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for set and get MatchVlanId.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchVlanId.
-	 * 2. Should get MatchVlanId.
-	 */
-	@Test
-	public void testSetGetMatchVlanId() {
-		Short matchVlanId = 10;
-		flowEntry.setMatchVlanId(matchVlanId);
-		assertEquals(flowEntry.getMatchVlanId(), matchVlanId);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for set and get MatchVlanPriority.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchVlanPriority.
-	 * 2. Should get MatchVlanPriority.
-	 */
-	@Test
-	public void testSetGetMatchVlanPriority() {
-		Byte matchVlanPriority = 10;
-		flowEntry.setMatchVlanPriority(matchVlanPriority);
-		assertEquals(flowEntry.getMatchVlanPriority(), matchVlanPriority);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for set and get SrcIPv4Net.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set SrcIPv4Net.
-	 * 2. Should get SrcIPv4Net.
-	 */
-	@Test
-	public void testSetGetMatchSrcIPv4Net() {
-		String srcIPv4Net = "192.168.0.1";
-		flowEntry.setMatchSrcIPv4Net(srcIPv4Net);
-		assertEquals(flowEntry.getMatchSrcIPv4Net(), srcIPv4Net);
-	}	
-	
-	/**
-	 * Desc:
-	 *  Test method for set and get MatchDstIPv4Net.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchDstIPv4Net.
-	 * 2. Should get MatchDstIPv4Net.
-	 */
-	@Test
-	public void testSetGetMatchDstIPv4Net() {
-		String dstIPv4Net = "192.168.0.1";
-		flowEntry.setMatchDstIPv4Net(dstIPv4Net);
-		assertEquals(flowEntry.getMatchDstIPv4Net(), dstIPv4Net);
-	}	
-
-	/**
-	 * Desc:
-	 *  Test method for set and get MatchIpProto.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchIpProto.
-	 * 2. Should get MatchIpProto.
-	 */
-	@Test
-	public void testSetGetMatchIpProto() {
-		Byte matchIpProto = 20;
-		flowEntry.setMatchIpProto(matchIpProto);
-		assertEquals(flowEntry.getMatchIpProto(), matchIpProto);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for set and get MatchIpToS.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchIpToS.
-	 * 2. Should get MatchIpToS.
-	 */
-	@Test
-	public void testSetGetMatchIpToS() {
-		Byte matchIpToS = 20;
-		flowEntry.setMatchIpToS(matchIpToS);
-		assertEquals(flowEntry.getMatchIpToS(), matchIpToS);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for set and get MatchSrcTcpUdpPort.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchSrcTcpUdpPort.
-	 * 2. Should get MatchSrcTcpUdpPort.
-	 */
-	@Test
-	public void testSetGetMatchSrcTcpUdpPort() {
-		Short srcTcpUdpPort = (short)65535;
-		flowEntry.setMatchSrcTcpUdpPort(srcTcpUdpPort);
-		assertEquals(flowEntry.getMatchSrcTcpUdpPort(), srcTcpUdpPort);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for set and get MatchDstTcpUdpPort.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchDstTcpUdpPort.
-	 * 2. Should get MatchDstTcpUdpPort.
-	 */
-	@Test
-	public void testSetGetMatchDstTcpUdpPort() {
-		Short dstTcpUdpPort = (short)65535;
-		flowEntry.setMatchDstTcpUdpPort(dstTcpUdpPort);
-		assertEquals(flowEntry.getMatchDstTcpUdpPort(), dstTcpUdpPort);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for set and get ActionOutputPort.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set ActionOutputPort.
-	 * 2. Should get ActionOutputPort.
-	 */
-	@Test
-	public void testSetGetActionOutputPort() {
-		Short actionOutputPort = 1;
-		flowEntry.setActionOutputPort(actionOutputPort);
-		assertEquals(flowEntry.getActionOutputPort(), actionOutputPort);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for set and get FlowPath.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set FlowPath.
-	 * 2. Should get FlowPath.
-	 */
-	@Test
-	public void testSetGetFlowPath() {
-		IFlowPath fp = ope.newFlowPath();
-		String flowId = "xx";
-		fp.setFlowId(flowId);
-		flowEntry.setFlow(fp);
-		IFlowPath fp2 = flowEntry.getFlow();
-		assertEquals(fp2.getFlowId(), flowId);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for set and get Switch.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set Switch.
-	 * 2. Should get Switch.
-	 */
-	@Test
-	public void testSetGetSwitch() {
-		String dpid = "00:00:00:00:00:22";
-		ISwitchObject sw1 = ope.newSwitch(dpid);
-		flowEntry.setSwitch(sw1);
-		ISwitchObject sw2 = flowEntry.getSwitch();
-		assertEquals(sw2, sw1);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for set and get InPort.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set InPort.
-	 * 2. Should get InPort.
-	 */
-	@Test
-	public void testSetGetInPort() {
-		String dpid = "00:00:00:00:00:22";
-		Short portNum = 4;
-		IPortObject port1 = ope.newPort(dpid, portNum);
-		flowEntry.setInPort(port1);
-		IPortObject port2 = flowEntry.getInPort();
-		assertEquals(port2, port1);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for set and get OutPort.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set OutPort.
-	 * 2. Should get OutPort.
-	 */
-	@Test
-	public void testSetGetOutPort() {
-		String dpid = "00:00:00:00:00:22";
-		Short portNum = 4;
-		IPortObject port1 = ope.newPort(dpid, portNum);
-		flowEntry.setOutPort(port1);
-		IPortObject port2 = flowEntry.getOutPort();
-		assertEquals(port2, port1);
-	}
-}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIFlowPathTest.java b/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIFlowPathTest.java
deleted file mode 100644
index 39e4955..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIFlowPathTest.java
+++ /dev/null
@@ -1,563 +0,0 @@
-package net.onrc.onos.ofcontroller.core;
-
-import static org.junit.Assert.*;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-
-import net.onrc.onos.graph.GraphDBConnection;
-import net.onrc.onos.graph.GraphDBOperation;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
-import net.onrc.onos.ofcontroller.core.internal.SwitchStorageImpl;
-import net.onrc.onos.ofcontroller.core.internal.TestDatabaseManager;
-import org.easymock.EasyMock;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.powermock.api.easymock.PowerMock;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.slf4j.LoggerFactory;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-import com.thinkaurelius.titan.core.TitanFactory;
-import com.thinkaurelius.titan.core.TitanGraph;
-
-//Add Powermock preparation
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({TitanFactory.class, GraphDBConnection.class, GraphDBOperation.class, SwitchStorageImpl.class})
-public class INetMapTopologyObjectsIFlowPathTest {
-	
-	//The test network is ./titan/schema/test-network.xml
-
-	protected static org.slf4j.Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
-
-	String conf;
-    private GraphDBConnection conn = null;
-    private GraphDBOperation ope = null;
-    private TitanGraph titanGraph = null;
-	private IFlowPath flowPath = null;
-	private IFlowEntry flowEntry = null;
-	
-	@Before
-	public void setUp() throws Exception {
-		conf = "/dummy/path/to/db";
-		
-		// Make mock cassandra DB
-		// Replace TitanFactory.open() to return mock DB
-		TestDatabaseManager.deleteTestDatabase();
-		titanGraph = TestDatabaseManager.getTestDatabase();
-		//TestDatabaseManager.populateTestData(titanGraph);
-		PowerMock.mockStatic(TitanFactory.class);
-		EasyMock.expect(TitanFactory.open((String)EasyMock.anyObject())).andReturn(titanGraph);
-		PowerMock.replay(TitanFactory.class);
-		
-		conn = GraphDBConnection.getInstance(conf);
-		ope = new GraphDBOperation(conn);
-		
-		flowPath = ope.newFlowPath();
-		flowEntry = ope.newFlowEntry();
-		flowEntry.setState("zz");
-	}
-
-	@After
-	public void tearDown() throws Exception {
-		titanGraph.shutdown();
-		TestDatabaseManager.deleteTestDatabase();
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for get and set FlowId method.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set the flow id.
-	 * 2. Should get the flow id.
-	 */
-	@Test
-	public void testSetGetFlowId() {
-		String flowId = "xx";
-		flowPath.setFlowId(flowId);
-		assertEquals(flowPath.getFlowId(), flowId);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for get and set InstallerId method.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set the installer id.
-	 * 2. Should get the installer id.
-	 */
-	@Test
-	public void testSetGetInstallerId() {
-		String flowId = "xx";
-		String installerId = "yy";
-		flowPath.setFlowId(flowId);
-		flowPath.setInstallerId(installerId);
-		assertEquals(flowPath.getInstallerId(), installerId);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for get and set FlowPathType method.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set the Flow Path Type.
-	 * 2. Should get the Flow Path Type.
-	 */
-	@Test
-	public void testSetGetFlowPathType() {
-		String flowId = "xx";
-		String flowPathType = "FP_TYPE_SHORTEST_PATH";
-		flowPath.setFlowId(flowId);
-		flowPath.setFlowPathType(flowPathType);
-		assertEquals(flowPath.getFlowPathType(), flowPathType);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for get and set FlowPathUserState method.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set the Flow Path User State.
-	 * 2. Should get the Flow Path User State.
-	 */
-	@Test
-	public void testSetGetFlowPathUserState() {
-		String flowId = "xx";
-		String flowPathUserState = "FP_USER_ADD";
-		flowPath.setFlowId(flowId);
-		flowPath.setFlowPathUserState(flowPathUserState);
-		assertEquals(flowPath.getFlowPathUserState(), flowPathUserState);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for get and set FlowPathFlags method.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set the Flow Path Flags.
-	 * 2. Should get the Flow Path Flags.
-	 */
-	@Test
-	public void testSetGetFlowPathFlags() {
-		String flowId = "xx";
-		Long flowPathFlags = new Long(0x3);
-		flowPath.setFlowId(flowId);
-		flowPath.setFlowPathFlags(flowPathFlags);
-		assertEquals(flowPath.getFlowPathFlags(), flowPathFlags);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for get and set Idle Timeout method.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set the Idle Timeout.
-	 * 2. Should get the Idle Timeout.
-	 */
-	@Test
-	public void testSetGetIdleTimeout() {
-		String flowId = "xx";
-		Integer idleTimeout = 5;
-		flowPath.setFlowId(flowId);
-		flowPath.setIdleTimeout(idleTimeout);
-		assertEquals(flowPath.getIdleTimeout(), idleTimeout);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for get and set Hard Timeout method.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set the Hard Timeout.
-	 * 2. Should get the Hard Timeout.
-	 */
-	@Test
-	public void testSetGetHardTimeout() {
-		String flowId = "xx";
-		Integer hardTimeout = 5;
-		flowPath.setFlowId(flowId);
-		flowPath.setHardTimeout(hardTimeout);
-		assertEquals(flowPath.getHardTimeout(), hardTimeout);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for get and set SourceSwitch method.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set the source switch.
-	 * 2. Should get the source switch.
-	 */
-	@Test
-	public void testSetGetSourceSwitch() {
-		String flowId = "xx";
-		String sourceSwitch = "aa";
-		flowPath.setFlowId(flowId);
-		flowPath.setSrcSwitch(sourceSwitch);
-		assertEquals(flowPath.getSrcSwitch(), sourceSwitch);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for get and set SourcePort method.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set the source port.
-	 * 2. Should get the source port.
-	 */
-	@Test
-	public void testSetGetSourcePort() {
-		String flowId = "xx";
-		Short sourcePort = 1;
-		flowPath.setFlowId(flowId);
-		flowPath.setSrcPort(sourcePort);
-		assertEquals(flowPath.getSrcPort(), sourcePort);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for get and set DestSwitch method.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set the dest switch.
-	 * 2. Should get the dest switch.
-	 */
-	@Test
-	public void testSetGetDestSwitch() {
-		String flowId = "xx";
-		String destSwitch = "bb";
-		flowPath.setFlowId(flowId);
-		flowPath.setDstSwitch(destSwitch);
-		assertEquals(flowPath.getDstSwitch(), destSwitch);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for get and set DestPort method.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set the source dest port.
-	 * 2. Should get the source dest port.
-	 */
-	@Test
-	public void testSetGetDstPort() {
-		String flowId = "xx";
-		Short dstPort = 2;
-		flowPath.setFlowId(flowId);
-		flowPath.setDstPort(dstPort);
-		assertEquals(flowPath.getDstPort(), dstPort);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for get and set DataPathSummary method.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set the data path summary.
-	 * 2. Should get the data path summary.
-	 */
-	@Test
-	public void testSetGetDataPathSummary() {
-		String flowId = "xx";
-		String dataPathSummary = "yy";
-		flowPath.setFlowId(flowId);
-		flowPath.setInstallerId(dataPathSummary);
-		assertEquals(flowPath.getInstallerId(), dataPathSummary);
-	}
-	
-	public boolean testIFlowEntry(IFlowPath fp, IFlowEntry fe)
-	{
-		ArrayList<IFlowEntry> flowEntryList = new ArrayList<IFlowEntry>();
-		for(IFlowEntry inFlowEntry : fp.getFlowEntries())
-		{
-			flowEntryList.add(inFlowEntry);
-		}
-		return flowEntryList.contains(fe);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for addFlowEntry and getFlorEntries method.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should add the FlowEntry.
-	 * 2. Should get the FlowEntries. It is tested in the testIFlowEntry method.
-	 */
-	@Test
-	public void testAddFlowEntryAndGetFlowEntries() {
-		String flowId = "xx";
-		flowPath.setFlowId(flowId);
-		flowPath.addFlowEntry(flowEntry);
-		IFlowEntry flowEntry2 = ope.newFlowEntry();
-		flowPath.addFlowEntry(flowEntry2);
-		assertTrue(testIFlowEntry(flowPath, flowEntry));
-		assertTrue(testIFlowEntry(flowPath, flowEntry2));
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for remove FlowEntry.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should remove FlowEntry.
-	 */
-	@Test
-	public void testRemoveFlowEntry() {
-		String flowId = "xx";
-		flowPath.setFlowId(flowId);
-		flowPath.addFlowEntry(flowEntry);
-		flowPath.removeFlowEntry(flowEntry);
-		assertTrue(!testIFlowEntry(flowPath, flowEntry));
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for set and get MatchSrcMac
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchSrcMac.
-	 * 2. Should get MatchSrcMac.
-	 */
-	@Test
-	public void testSetGetMatchSrcMac() {
-		String flowId = "xx";
-		String matchSrcMac = "00:00:00:00:00:11";
-		flowPath.setFlowId(flowId);
-		flowPath.setMatchSrcMac(matchSrcMac);
-		assertEquals(flowPath.getMatchSrcMac(), matchSrcMac);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for set and get MatchDstMac.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchDstMac.
-	 * 2. Should get MatchDstMac.
-	 */
-	@Test
-	public void testSetGetMatchDstMac() {
-		String flowId = "xx";
-		String matchDstMac = "00:00:00:00:00:11";
-		flowPath.setFlowId(flowId);
-		flowPath.setMatchDstMac(matchDstMac);
-		assertEquals(flowPath.getMatchDstMac(), matchDstMac);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for set and get MatchEthernetFrameType
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchEthernetFrameType.
-	 * 2. Should get MatchEthernetFrameType.
-	 */
-	@Test
-	public void testSetGetMatchEthernetFrameType() {
-		String flowId = "xx";
-		Short matchEthernetFrameType = 1;
-		flowPath.setFlowId(flowId);
-		flowPath.setMatchEthernetFrameType(matchEthernetFrameType);
-		assertEquals(flowPath.getMatchEthernetFrameType(), matchEthernetFrameType);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for set and get MatchVlanId
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchVlanId.
-	 * 2. Should get MatchVlanId.
-	 */
-	@Test
-	public void testSetGetMatchVlanId() {
-		String flowId = "xx";
-		Short matchVlanId = 10;
-		flowPath.setFlowId(flowId);
-		flowPath.setMatchVlanId(matchVlanId);
-		assertEquals(flowPath.getMatchVlanId(), matchVlanId);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for set and get MatchVlanPriority
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchVlanPriority.
-	 * 2. Should get MatchVlanPriority.
-	 */
-	@Test
-	public void testSetGetMatchVlanPriority() {
-		String flowId = "xx";
-		Byte matchVlanPriority = 20;
-		flowPath.setFlowId(flowId);
-		flowPath.setMatchVlanPriority(matchVlanPriority);
-		assertEquals(flowPath.getMatchVlanPriority(), matchVlanPriority);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for set and get MatchSrcIPv4Net.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchSrcIPv4Net.
-	 * 2. Should get MatchSrcIPv4Net.
-	 */
-	@Test
-	public void testSetGetMatchSrcIPv4Net() {
-		String flowId = "xx";
-		String ip = "192.168.0.1";
-		flowPath.setFlowId(flowId);
-		flowPath.setMatchSrcIPv4Net(ip);
-		assertEquals(flowPath.getMatchSrcIPv4Net(), ip);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for set and get MatchDstIPv4Net.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchDstIPv4Net.
-	 * 2. Should get MatchDstIPv4Net.
-	 */
-	@Test
-	public void testSetGetMatchDstIPv4Net() {
-		String flowId = "xx";
-		String ip = "192.168.0.1";
-		flowPath.setFlowId(flowId);
-		flowPath.setMatchDstIPv4Net(ip);
-		assertEquals(flowPath.getMatchDstIPv4Net(), ip);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for set and get MatchIpProto
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchIpProto.
-	 * 2. Should get MatchIpProto.
-	 */
-	@Test
-	public void testSetGetMatchIpProto() {
-		String flowId = "xx";
-		Byte matchIpProto = 20;
-		flowPath.setFlowId(flowId);
-		flowPath.setMatchIpProto(matchIpProto);
-		assertEquals(flowPath.getMatchIpProto(), matchIpProto);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for set and get MatchIpToS
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchIpToS.
-	 * 2. Should get MatchIpToS.
-	 */
-	@Test
-	public void testSetGetMatchIpToS() {
-		String flowId = "xx";
-		Byte matchIpToS = 20;
-		flowPath.setFlowId(flowId);
-		flowPath.setMatchIpToS(matchIpToS);
-		assertEquals(flowPath.getMatchIpToS(), matchIpToS);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for set and get MatchSrcTcpUdpPort.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchSrcTcpUdpPort.
-	 * 2. Should get MatchSrcTcpUdpPort.
-	 */
-	@Test
-	public void testSetGetMatchSrcTcpUdpPort() {
-		String flowId = "xx";
-		Short srcTcpUdpPort = (short)65535;
-		flowPath.setFlowId(flowId);
-		flowPath.setMatchSrcTcpUdpPort(srcTcpUdpPort);
-		assertEquals(flowPath.getMatchSrcTcpUdpPort(), srcTcpUdpPort);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for set and get MatchDstTcpUdpPort.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchDstTcpUdpPort.
-	 * 2. Should get MatchDstTcpUdpPort.
-	 */
-	@Test
-	public void testSetGetMatchDstTcpUdpPort() {
-		String flowId = "xx";
-		Short dstTcpUdpPort = (short)65535;
-		flowPath.setFlowId(flowId);
-		flowPath.setMatchDstTcpUdpPort(dstTcpUdpPort);
-		assertEquals(flowPath.getMatchDstTcpUdpPort(), dstTcpUdpPort);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for get Switches.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should get switches.
-	 */
-	@Test
-	public void testGetSwitches() {
-		String flowId = "xx";
-		String dpid = "1";
-		flowPath.setFlowId(flowId);
-		ISwitchObject sw = ope.newSwitch(dpid);
-		flowEntry.setSwitch(sw);
-		flowPath.addFlowEntry(flowEntry);
-		
-		HashMap<String, ISwitchObject> swList = new HashMap<String, ISwitchObject>();
-		for(ISwitchObject insw : flowPath.getSwitches()){
-			swList.put(sw.getDPID(), insw);
-		}
-		
-		assertTrue(swList.containsKey(dpid));
-	}
-	
-	//TODO Dont know how to set the state property.
-	@Test
-	public void testGetState() {
-		String status = null;
-		assertEquals(flowPath.getState(), status);
-	}
-	
-	
-}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIPortObjectTest.java b/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIPortObjectTest.java
deleted file mode 100644
index 74f9758..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIPortObjectTest.java
+++ /dev/null
@@ -1,355 +0,0 @@
-package net.onrc.onos.ofcontroller.core;
-
-import static org.junit.Assert.*;
-
-import net.onrc.onos.graph.GraphDBConnection;
-import net.onrc.onos.graph.GraphDBOperation;
-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.core.internal.SwitchStorageImpl;
-import net.onrc.onos.ofcontroller.core.internal.TestDatabaseManager;
-import org.easymock.EasyMock;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.openflow.protocol.OFPhysicalPort.OFPortState;
-import org.powermock.api.easymock.PowerMock;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.slf4j.LoggerFactory;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-import com.thinkaurelius.titan.core.TitanFactory;
-import com.thinkaurelius.titan.core.TitanGraph;
-import java.util.ArrayList;
-import java.util.HashMap;
-
-//Add Powermock preparation
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({TitanFactory.class, GraphDBConnection.class, GraphDBOperation.class, SwitchStorageImpl.class})
-public class INetMapTopologyObjectsIPortObjectTest {
-	
-	//The test network is ./titan/schema/test-network.xml
-
-	protected static org.slf4j.Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
-
-	String conf;
-    private GraphDBConnection conn = null;
-    private GraphDBOperation ope = null;
-    private TitanGraph titanGraph = null;
-    
-    private ISwitchObject swObj;
-    private IPortObject portObj;
-    private IPortObject portObj2;
-    String dpid;
-    Short number;
-    Short number2;
-    
-    private ISwitchObject swObjParty;
-    private IPortObject portObjParty1;
-    private IPortObject portObjParty2;  
-    String dpidParty;
-    Short numberParty1;
-    Short numberParty2;
-    
-    
-	@Before
-	public void setUp() throws Exception {
-		conf = "/dummy/path/to/db";
-		
-		// Make mock cassandra DB
-		// Replace TitanFactory.open() to return mock DB
-		TestDatabaseManager.deleteTestDatabase();
-		titanGraph = TestDatabaseManager.getTestDatabase();
-		//TestDatabaseManager.populateTestData(titanGraph);
-		PowerMock.mockStatic(TitanFactory.class);
-		EasyMock.expect(TitanFactory.open((String)EasyMock.anyObject())).andReturn(titanGraph);
-		PowerMock.replay(TitanFactory.class);
-		
-		conn = GraphDBConnection.getInstance(conf);
-		ope = new GraphDBOperation(conn);
-		
-		dpid = "00:00:00:00:00:00:0a:07";
-		number = 1;	
-		number2 = 2;
-		swObj = ope.newSwitch(dpid);
-		portObj = ope.newPort(dpid, number);
-		portObj2 = ope.newPort(dpid, number2);
-
-		swObj.addPort(portObj);	
-		swObj.addPort(portObj2);
-		
-		dpidParty = "00:00:00:00:00:00:0a:08";
-		numberParty1 = 1;
-		numberParty2 = 2;
-		swObjParty = ope.newSwitch(dpidParty);
-		portObjParty1 = ope.newPort(dpidParty, numberParty1);
-		portObjParty2 = ope.newPort(dpidParty, numberParty2);
-		swObjParty.addPort(portObjParty1);	
-		swObjParty.addPort(portObjParty2);
-	}
-
-	@After
-	public void tearDown() throws Exception {
-		titanGraph.shutdown();
-		TestDatabaseManager.deleteTestDatabase();
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for set and get port number property.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set the port number.
-	 * 2. Should get the port number.
-	 */
-	@Test
-	public void testSetGetNumber() {
-		assertEquals(portObj.getNumber(), number);
-		Short testedNumber = 4;
-		portObj.setNumber(testedNumber);
-		assertEquals(portObj.getNumber(), testedNumber);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for set and get port id property.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set the port id.
-	 * 2. Should get the port id.
-	 */
-	@Test
-	public void testSetGetPortId() {
-		String portId = "test1";
-		portObj.setPortId(portId);
-		assertEquals(portObj.getPortId(), portId);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for set and get port desc property.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set the port desc.
-	 * 2. Should get the port desc.
-	 */
-	@Test
-	public void testSetGetDesc() {
-		String testedDesc = "port 4 at ATL Switch";
-		portObj.setDesc(testedDesc);
-		assertEquals(portObj.getDesc(), testedDesc);
-	}
-	
-	
-	/**
-	 * Desc:
-	 *  Test method for set and get port status property.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set the port status.
-	 * 2. Should get the port status.
-	 */
-	@Test
-	public void testSetGetPortState() {
-		Integer portState = OFPortState.OFPPS_STP_FORWARD.getValue();
-		portObj.setPortState(portState);
-		assertEquals(portObj.getPortState(), portState);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for get switch object.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should get the switch status.
-	 */
-	@Test
-	public void testGetSwitch() {
-		ISwitchObject sw = portObj.getSwitch();
-		assertEquals(sw.getDPID(), dpid);
-	}
-	
-	private boolean checkIDeviceObject(IPortObject IportObj, String mac)
-	{
-		HashMap<String, IDeviceObject> devList = new HashMap<String, IDeviceObject>();
-		for(IDeviceObject IdevObj : IportObj.getDevices())
-		{
-			devList.put(IdevObj.getMACAddress(), IdevObj);
-		}
-		return devList.containsKey(mac);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for set and remove device object.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set the device object.
-	 * 2. SHould remove the device object.
-	 */
-	@Test
-	public void testSetAndRemoveDevice() {
-		IDeviceObject devObj = ope.newDevice();
-		String devMac = "00:00:00:00:00:11";
-		devObj.setMACAddress(devMac);
-		
-		boolean b = checkIDeviceObject(portObj, devMac);
-		assertTrue(!b);
-		portObj.setDevice(devObj);
-		boolean b2 = checkIDeviceObject(portObj, devMac);
-		assertTrue(b2);
-		
-		portObj.removeDevice(devObj);
-		boolean b3 = checkIDeviceObject(portObj, devMac);
-		assertTrue(!b3);
-		
-	}	
-	
-	/**
-	 * Desc:
-	 *  Test method for get devices object.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should get the device objects.
-	 */
-	@Test
-	public void testGetDevices() {
-		IDeviceObject devObj = ope.newDevice();
-		String devMac = "58:55:ca:c4:1b:a0";
-		devObj.setMACAddress(devMac);
-		
-		portObj.setDevice(devObj);
-		boolean b = checkIDeviceObject(portObj, devMac);
-		assertTrue(b);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for set, get and remove linked port.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set the linked objects.
-	 * 2. Should get the linked objects.
-	 * 3. SHould remove the liked objects.
-	 */
-	@Test
-	public void testSetGetRemoveLinkedPorts() {
-		String dpidParty = "00:00:00:00:00:00:00:08";
-		ISwitchObject swParty = ope.newSwitch(dpidParty);
-		Short poShort = 1;
-		IPortObject poParty = ope.newPort(dpidParty, poShort);
-		swParty.addPort(poParty);
-		
-		portObj.setLinkPort(poParty);
-		
-		ArrayList<IPortObject> iPortList = new ArrayList<IPortObject>();
-		for(IPortObject port : portObj.getLinkedPorts()) {
-			iPortList.add(port);
-		}	
-		assertTrue(iPortList.contains(poParty));	
-		
-		portObj.removeLink(poParty);
-		
-		ArrayList<IPortObject> iPortList2 = new ArrayList<IPortObject>();
-		for(IPortObject port : portObj.getLinkedPorts()) {
-			iPortList2.add(port);
-		}	
-		
-		assertTrue(!iPortList2.contains(poParty));
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for get inbound flowEntry
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should get the inbound flowEntry.
-	 */
-	@Test
-	public void testGetInFlowEntries() {
-
-		portObj.setLinkPort(portObj2);
-		
-		IFlowPath flowPathObj = ope.newFlowPath();
-		
-		String flowEId = "1";
-		IFlowEntry flowEntryObj = ope.newFlowEntry();		
-		flowEntryObj.setFlowEntryId(flowEId);
-		flowEntryObj.setInPort(portObj);
-		flowEntryObj.setOutPort(portObj2);
-		flowEntryObj.setSwitch(swObj);
-		flowEntryObj.setFlow(flowPathObj);
-		
-		String flowEId2 = "2";
-		IFlowEntry flowEntryObj2 = ope.newFlowEntry();		
-		flowEntryObj2.setFlowEntryId(flowEId2);
-		flowEntryObj2.setInPort(portObjParty1);
-		flowEntryObj2.setOutPort(portObjParty2);
-		flowEntryObj.setSwitch(swObjParty);
-		flowEntryObj2.setFlow(flowPathObj);
-		
-		HashMap<String, IFlowEntry> flowEntryList = new HashMap<String, IFlowEntry>();
-		for(IFlowEntry flowEnt : portObj.getInFlowEntries())
-		{				
-			flowEntryList.put(flowEnt.getFlowEntryId(), flowEnt);
-		}
-		
-		assertTrue(flowEntryList.containsValue(flowEntryObj));
-		
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for get outbound flowEntry
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should get the outbound flowEntry.
-	 */
-	@Test
-	public void testGetOutFlowEntries() {
-		
-		portObj.setLinkPort(portObj2);
-		
-		IFlowPath flowPathObj = ope.newFlowPath();
-		
-		String flowEId = "1";
-		IFlowEntry flowEntryObj = ope.newFlowEntry();		
-		flowEntryObj.setFlowEntryId(flowEId);
-		flowEntryObj.setInPort(portObj);
-		flowEntryObj.setOutPort(portObj2);
-		flowEntryObj.setSwitch(swObj);
-		flowEntryObj.setFlow(flowPathObj);
-		
-		String flowEId2 = "2";
-		IFlowEntry flowEntryObj2 = ope.newFlowEntry();		
-		flowEntryObj2.setFlowEntryId(flowEId2);
-		flowEntryObj2.setInPort(portObjParty1);
-		flowEntryObj2.setOutPort(portObjParty2);
-		flowEntryObj.setSwitch(swObjParty);
-		flowEntryObj2.setFlow(flowPathObj);
-		
-		HashMap<String, IFlowEntry> flowEntryList = new HashMap<String, IFlowEntry>();
-		for(IFlowEntry flowEnt : portObj2.getOutFlowEntries())
-		{				
-			flowEntryList.put(flowEnt.getFlowEntryId(), flowEnt);
-		}
-		
-		assertTrue(flowEntryList.containsValue(flowEntryObj));
-		
-	}
-
-}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsISwitchObjectTest.java b/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsISwitchObjectTest.java
deleted file mode 100644
index dacfdb5..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsISwitchObjectTest.java
+++ /dev/null
@@ -1,286 +0,0 @@
-package net.onrc.onos.ofcontroller.core;
-
-import static org.junit.Assert.*;
-
-import java.util.HashMap;
-
-import net.onrc.onos.graph.GraphDBConnection;
-import net.onrc.onos.graph.GraphDBOperation;
-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.core.internal.SwitchStorageImpl;
-import net.onrc.onos.ofcontroller.core.internal.TestDatabaseManager;
-
-import org.easymock.EasyMock;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.powermock.api.easymock.PowerMock;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.slf4j.LoggerFactory;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-import com.thinkaurelius.titan.core.TitanFactory;
-import com.thinkaurelius.titan.core.TitanGraph;
-
-//Add Powermock preparation
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({TitanFactory.class, GraphDBConnection.class, GraphDBOperation.class, SwitchStorageImpl.class})
-public class INetMapTopologyObjectsISwitchObjectTest {
-	
-	//The test network is ./titan/schema/test-network.xml
-
-	protected static org.slf4j.Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
-
-	String conf;
-    private GraphDBConnection conn = null;
-    private GraphDBOperation ope = null;
-    private TitanGraph titanGraph = null;
-	
-	@Before
-	public void setUp() throws Exception {
-		conf = "/dummy/path/to/db";
-		
-		// Make mock cassandra DB
-		// Replace TitanFactory.open() to return mock DB
-		TestDatabaseManager.deleteTestDatabase();
-		titanGraph = TestDatabaseManager.getTestDatabase();
-		//TestDatabaseManager.populateTestData(titanGraph);
-		PowerMock.mockStatic(TitanFactory.class);
-		EasyMock.expect(TitanFactory.open((String)EasyMock.anyObject())).andReturn(titanGraph);
-		PowerMock.replay(TitanFactory.class);
-		
-		conn = GraphDBConnection.getInstance(conf);
-		ope = new GraphDBOperation(conn);
-	}
-
-	@After
-	public void tearDown() throws Exception {
-		titanGraph.shutdown();
-		TestDatabaseManager.deleteTestDatabase();
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for get and set state method.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set the status of the switch.
-	 * 2. Should get the status of the switch.
-	 */
-	@Test
-	public void testSetGetState() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		String state = "ACTIVE";
-		ISwitchObject swObj = ope.newSwitch(dpid);
-		swObj.setState(state);
-		assertEquals(swObj.getState(), state);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for get and set Type method.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set the Type of the switch.
-	 * 2. Should get the Type of the switch.
-	 */
-	@Test
-	public void testSetGetType() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		String type = "Switch";
-		ISwitchObject swObj = ope.newSwitch(dpid);
-		swObj.setType("Switch");
-		assertEquals(swObj.getType(), type);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for getDPID method.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should get the dpid of the switch.
-	 */
-	@Test
-	public void testGetDPID() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		ISwitchObject swObj = ope.newSwitch(dpid);
-		
-		assertEquals(swObj.getDPID(), dpid);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for setDPID method.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set the dpid of the switch.
-	 */
-	@Test
-	public void testSetDPID() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		String dpid2 = "00:00:00:00:00:00:0a:08";
-		ISwitchObject obj = ope.newSwitch(dpid);
-		assertEquals(obj.getDPID(), dpid);
-		
-		obj.setDPID(dpid2);
-		assertEquals(obj.getDPID(), dpid2);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for getPorts method.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should get all of ports taken by the switch.
-	 */
-	@Test
-	public void testGetPorts() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		Short portNumber = 1;
-		final int testSwitchPortNumber = 1;
-		ISwitchObject swObj = ope.newSwitch(dpid);
-		IPortObject portObj = ope.newPort(dpid, portNumber);
-
-		swObj.addPort(portObj);
-		int i = 0;
-		for(@SuppressWarnings("unused") IPortObject port : swObj.getPorts()){
-			i++;
-		}
-		assertEquals(testSwitchPortNumber, i);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for add and getPort method.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should add the port.
-	 * 1. Should get the port.
-	 */
-	@Test
-	public void testGetPort() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		Short portNumber = 1;
-		ISwitchObject swObj = ope.newSwitch(dpid);
-		IPortObject portObj = ope.newPort(dpid, portNumber);
-		
-		swObj.addPort(portObj);
-		IPortObject portObj2 = swObj.getPort(portNumber);
-		assertEquals(portObj, portObj2);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for add and removePort method.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should add a port to the switch.
-	 * 1. Should remove a port from the switch.
-	 */
-	@Test
-	public void testAddRemovePorts() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		Short portNum = 1;
-		ISwitchObject swObj = ope.newSwitch(dpid);
-		IPortObject portObj = ope.newPort(dpid, portNum);
-		swObj.addPort(portObj);
-		
-		IPortObject portObj2 = swObj.getPort(portNum);
-		assertEquals(portObj2, portObj);
-		swObj.removePort(portObj);
-		assertNull(swObj.getPort(portNum));
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for getDevices method.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should get all devices attached to the switch.
-	 */
-	@Test
-	public void testGetDevices() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		Short portNum = 1;
-		String devMac = "00:00:00:00:00:11";
-		int numOfDev = 1;
-		
-		ISwitchObject swObj = ope.newSwitch(dpid);
-		IPortObject portObj = ope.newPort(dpid, portNum);
-		IDeviceObject devObj = ope.newDevice();
-		devObj.setMACAddress(devMac);
-		swObj.addPort(portObj);
-		portObj.setDevice(devObj);
-		
-		int i = 0;
-		for(@SuppressWarnings("unused") IDeviceObject dev : swObj.getDevices()){
-			i++;
-		}
-		assertEquals(i, numOfDev);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for getFlowEntries method.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should get all flowEntries attached to the switch.
-	 */
-	@Test
-	public void testGetFlowEntries() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		Short number = 1;	
-		Short number2 = 2;
-		Short number3 = 3;
-		ISwitchObject swObj = ope.newSwitch(dpid);
-		IPortObject portObj = ope.newPort(dpid, number);
-		IPortObject portObj2 = ope.newPort(dpid, number2);
-		IPortObject portObj3 = ope.newPort(dpid, number3);
-
-		swObj.addPort(portObj);	
-		swObj.addPort(portObj2);
-		swObj.addPort(portObj3);
-		
-		IFlowPath flowPathObj = ope.newFlowPath();
-		
-		String flowEId = "1";
-		IFlowEntry flowEntryObj = ope.newFlowEntry();		
-		flowEntryObj.setFlowEntryId(flowEId);
-		flowEntryObj.setInPort(portObj);
-		flowEntryObj.setOutPort(portObj2);
-		flowEntryObj.setSwitch(swObj);
-		flowEntryObj.setFlow(flowPathObj);
-		
-		String flowEId2 = "2";
-		IFlowEntry flowEntryObj2 = ope.newFlowEntry();		
-		flowEntryObj2.setFlowEntryId(flowEId2);
-		flowEntryObj2.setInPort(portObj);
-		flowEntryObj2.setOutPort(portObj3);
-		flowEntryObj2.setSwitch(swObj);
-		flowEntryObj2.setFlow(flowPathObj);
-		
-		HashMap<String, IFlowEntry> flowEntryList = new HashMap<String, IFlowEntry>();
-		for(IFlowEntry flowEnt : swObj.getFlowEntries())
-		{				
-			flowEntryList.put(flowEnt.getFlowEntryId(), flowEnt);
-		}
-		
-		assertTrue(flowEntryList.containsValue(flowEntryObj));
-		assertTrue(flowEntryList.containsValue(flowEntryObj2));
-	}
-
-}
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
deleted file mode 100644
index 69c3c8a..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImplTest.java
+++ /dev/null
@@ -1,767 +0,0 @@
-package net.onrc.onos.ofcontroller.core.internal;
-
-import static org.junit.Assert.*;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import net.floodlightcontroller.routing.Link;
-import net.onrc.onos.graph.GraphDBConnection;
-import net.onrc.onos.graph.GraphDBOperation;
-import net.onrc.onos.ofcontroller.core.ILinkStorage;
-import net.onrc.onos.ofcontroller.core.INetMapStorage.DM_OPERATION;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
-import net.onrc.onos.ofcontroller.linkdiscovery.LinkInfo;
-
-import org.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;
-
-/**
- * Unit test for {@link LinkStorageImpl}.
- * @author Naoki Shiota
- *
- */
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({LinkStorageImpl.class, GraphDBConnection.class, GraphDBOperation.class})
-@SuppressWarnings("serial")
-public class LinkStorageImplTest {
-	protected final 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 GraphDBOperation ope;
-	
-	// Uncommitted actions executed in LinkStorageImpl
-	private static ArrayList<LinkEvent> actions;
-	
-	// Dictionary of mock IPortObject to information of port
-	// -> Used to refer DPID from IPortObject
-	private static Map<IPortObject,PortInfo> mockToPortInfoMap;
-	
-	
-	// Links existing in virtual graph
-	private List<Link> links;
-	
-	//================ Utility classes for logging actions in LinkStorageImpl ===========
-	private enum LinkEventType {
-		ADD, DELETE
-	}
-	
-	private class LinkEvent {
-		private Long src_dpid = null;
-		private Long dst_dpid = null;
-		private Short src_port = null;
-		private Short dst_port = null;
-		
-		public LinkEventType type;
-		
-		public LinkEvent(Link link, LinkEventType type) {
-			this.src_dpid = link.getSrc();
-			this.src_port = link.getSrcPort();
-			this.dst_dpid = link.getDst();
-			this.dst_port = link.getDstPort();
-			
-			this.type = type;
-		}
-
-		public Long getSrcDpid() { return src_dpid; }
-		public Short getSrcPort() { return src_port; }
-		public Long getDstDpid() { return dst_dpid; }
-		public Short getDstPort() { return dst_port; }
-		public LinkEventType getType() { return type; }
-	}
-	
-	private class PortInfo {
-		public Long dpid = null;
-		public Short port = null;
-		
-		public PortInfo(Long dpid, Short port) { this.dpid = dpid; this.port = port; }
-	}
-
-	/**
-	 * 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{
-		// Create mock GraphDBConnection (replace Singleton object to mock one)
-		PowerMock.mockStatic(GraphDBConnection.class);
-		PowerMock.suppress(PowerMock.constructor(GraphDBConnection.class));
-		conn = PowerMock.createMock(GraphDBConnection.class);
-		EasyMock.expect(GraphDBConnection.getInstance((String)EasyMock.anyObject())).andReturn(conn).anyTimes();
-		PowerMock.replay(GraphDBConnection.class);
-		
-		// Create mock GraphDBOperation
-		ope = createMockGraphDBOperation();
-		PowerMock.expectNew(GraphDBOperation.class, new Class<?>[] {GraphDBConnection.class}, EasyMock.anyObject(GraphDBConnection.class)).andReturn(ope).anyTimes();
-		PowerMock.replay(GraphDBOperation.class);
-		
-		actions = new ArrayList<LinkEvent>();
-		mockToPortInfoMap = new HashMap<IPortObject,PortInfo>();
-		
-		linkStorage = new LinkStorageImpl();
-		linkStorage.init("dummyStore", "/dummy/path/to/conf");
-		
-		initLinks();
-	}
-	
-	/**
-	 * Closing code called after each tests.
-	 * @throws Exception
-	 */
-	@After
-	public void tearDown() throws Exception {
-		linkStorage.close();
-	}
-	
-
-	/**
-	 * Test if {@link LinkStorageImpl#addLink(Link)} can correctly creates a Link.
-	 */
-	@Test
-	public void testAddLink() {
-		Link linkToCreate = createFeasibleLink();
-		Link linkToVerify = createFeasibleLink();
-		
-		//Use the link storage API to add the link
-		linkStorage.addLink(linkToCreate);
-		doTestLinkExist(linkToVerify);
-	}
-	
-	/**
-	 * Test if {@link LinkStorageImpl#update(List, DM_OPERATION)} can correctly creates multiple Links.
-	 */
-	@Test
-	public void testAddLinks() {
-		List<Link> linksToCreate = createFeasibleLinks();
-		List<Link> linksToVerify = createFeasibleLinks();
-	
-		// Test creation of new links
-		linkStorage.addLinks(linksToCreate);
-		for(Link l : linksToVerify) {
-			doTestLinkExist(l);
-		}
-	}
-
-	// TODO: remove @Ignore after UPDATE method is implemented
-	/**
-	 * Test if {@link LinkStorageImpl#updateLinkInfo(Link, LinkInfo, DM_OPERATION)} can correctly updates LinkInfo for a Link.
-	 */
-	@Ignore @Test
-	public void testUpdate_Update() {
-		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 {@link LinkStorageImpl#update(Link, DM_OPERATION)} can correctly creates a Link.
-	 */
-	@Test
-	public void testUpdate_Create() {
-		Link linkToCreate = createFeasibleLink();
-		Link linkToVerify = createFeasibleLink();
-		
-		//Use the link storage API to add the link
-		linkStorage.update(linkToCreate, null, ILinkStorage.DM_OPERATION.CREATE);
-		doTestLinkExist(linkToVerify);
-	}
-
-	/**
-	 * Test if {@link LinkStorageImpl#update(Link, DM_OPERATION)}can correctly inserts a Link.
-	 */
-	@Test
-	public void testUpdate_Insert(){
-		Link linkToInsert = createFeasibleLink();
-		Link linkToVerify = createFeasibleLink();
-		
-		//Use the link storage API to add the link
-		linkStorage.update(linkToInsert, null, ILinkStorage.DM_OPERATION.INSERT);
-		doTestLinkExist(linkToVerify);
-	}
-	
-	/**
-	 * Test if {@link LinkStorageImpl#update(Link, DM_OPERATION)} can correctly deletes a Link.
-	 */
-	@Test
-	public void testUpdate_Delete(){
-		Link linkToDelete = createExistingLink();
-		Link linkToVerify = createExistingLink();
-
-		// Test deletion of existing link
-		linkStorage.update(linkToDelete, null, DM_OPERATION.DELETE);
-		doTestLinkNotExist(linkToVerify);
-	}
-
-	/**
-	 * Test if {@link LinkStorageImpl#getLinks(Long, short)} 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(1, list.size());
-		
-		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(0, list2.size());
-	}
-	
-	/**
-	 * Test if {@link LinkStorageImpl#getLinks(String)} 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 {@link LinkStorageImpl#getReverseLinks(String)} can correctly return Links connected to specific MAC address.
-	 */
-	@Test
-	public void testGetReverseLinks_ByString() {
-		Link linkToVeryfy = createExistingLink();
-		String dpid = HexString.toHexString(linkToVeryfy.getDst());
-		
-		List<Link> links = linkStorage.getReverseLinks(dpid);
-		assertTrue(links.contains(linkToVeryfy));
-
-		Link linkToVerifyNot = createFeasibleLink();
-		assertFalse(links.contains(linkToVerifyNot));
-	}
-	
-	/**
-	 * Test if {@link LinkStorageImpl#deleteLink(Link)} 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 {@link LinkStorageImpl#deleteLinks(List)} 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 {@link LinkStorageImpl#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 {@link LinkStorageImpl#deleteLinksOnPort(Long, short)} can delete Links.
-	 */
-	@Test
-	public void testDeleteLinksOnPort() {
-		Link linkToDelete = createExistingLink();
-		Link linkToVerify = createExistingLink();
-		
-		linkStorage.deleteLinksOnPort(linkToDelete.getSrc(), linkToDelete.getSrcPort());
-		
-		doTestLinkNotExist(linkToVerify);
-	}
-	
-	/**
-	 * Test if {@link LinkStorageImpl#getLinkInfo(Link)} can delete Links.
-	 */
-	@Ignore @Test
-	public void testGetLinkInfo() {
-		fail("not yet implemented");
-	}
-
-	/**
-	 * Test if specific link exists
-	 * @param link 
-	 */
-	private void doTestLinkExist(Link link) {
-		int count = 0;
-		for(Link lt : links) {
-			if(lt.equals(link)) {
-				++count;
-			}
-		}
-		
-		assertTrue(count == 1);
-	}
-	
-	/**
-	 * Test if specific link doesn't exist
-	 * @param link
-	 */
-	private void doTestLinkNotExist(Link link) {
-		assertFalse(links.contains(link));
-	}
-	
-	/**
-	 * Test if titanGraph has specific Link with specific LinkInfo
-	 * @param link 
-	 */
-	// TODO: Fix me
-	private void doTestLinkHasStateOf(Link link, LinkInfo info) {
-	}
-	
-	/**
-	 * Class defines a function called back when {@link IPortObject#removeLink(IPortObject)} is called.
-	 * @author Naoki Shiota
-	 *
-	 */
-	private class RemoveLinkCallback implements IAnswer<Object> {
-		private long dpid;
-		private short port;
-		public RemoveLinkCallback(long dpid, short port) {
-			this.dpid = dpid; this.port = port;
-		}
-		
-		@Override
-		public Object answer() throws Throwable {
-			IPortObject dstPort = (IPortObject) EasyMock.getCurrentArguments()[0];
-			PortInfo dst = mockToPortInfoMap.get(dstPort);
-
-			Link linkToRemove = new Link(this.dpid,this.port,dst.dpid,dst.port);
-			actions.add(new LinkEvent(linkToRemove,LinkEventType.DELETE));
-			
-			return null;
-		}
-	}
-	
-	/**
-	 * Class defines a function called back when {@link IPortObject#setLinkPort(IPortObject)} is called.
-	 * @author Naoki Shiota
-	 */
-	private class SetLinkPortCallback implements IAnswer<Object> {
-		private long dpid;
-		private short port;
-		public SetLinkPortCallback(long dpid, short port) {
-			this.dpid = dpid; this.port = port;
-		}
-
-		@Override
-		public Object answer() throws Throwable {
-			IPortObject dstPort = (IPortObject) EasyMock.getCurrentArguments()[0];
-			PortInfo dst = mockToPortInfoMap.get(dstPort);
-
-			Link linkToAdd = new Link(this.dpid,this.port,dst.dpid,dst.port);
-			actions.add(new LinkEvent(linkToAdd,LinkEventType.ADD));
-
-			return null;
-		}
-		
-	}
-	
-	/**
-	 * Class defines a function called back when {@link IPortObject#getSwitch()} is called.
-	 * @author Naoki Shiota
-	 *
-	 */
-	private class GetSwitchCallback implements IAnswer<ISwitchObject> {
-		private long dpid;
-		
-		public GetSwitchCallback(long dpid) {
-			this.dpid = dpid;
-		}
-
-		@Override
-		public ISwitchObject answer() throws Throwable {
-			ISwitchObject sw = createMockSwitch(dpid);
-			return sw;
-		}
-	}
-	
-	/**
-	 * Class defines a function called back when {@link IPortObject#getLinkedPorts()} is called.
-	 * @author Naoki Shiota
-	 *
-	 */
-	private class GetLinkedPortsCallback implements IAnswer< Iterable<IPortObject> > {
-		private long dpid;
-		private short port;
-		
-		public GetLinkedPortsCallback(long dpid, short port) {
-			this.dpid = dpid;
-			this.port = port;
-		}
-
-		@Override
-		public Iterable<IPortObject> answer() throws Throwable {
-			List<IPortObject> ports = new ArrayList<IPortObject>();
-
-			for(Link lk : links) {
-				if(lk.getSrc() == dpid && lk.getSrcPort() == port) {
-					ports.add(createMockPort(lk.getDst(), lk.getDstPort()));
-				}
-			}
-
-			return ports;
-		}
-		
-	}
-
-	/**
-	 * Class defines a function called back when {@link IPortObject#getReverseLinkedPorts()} is called.
-	 * @author Naoki Shiota
-	 *
-	 */
-	private class GetReverseLinkedPortsCallback implements IAnswer< Iterable<IPortObject> > {
-		private long dpid;
-		private short port;
-		
-		public GetReverseLinkedPortsCallback(long dpid, short port) {
-			this.dpid = dpid;
-			this.port = port;
-		}
-
-		@Override
-		public Iterable<IPortObject> answer() throws Throwable {
-			List<IPortObject> ports = new ArrayList<IPortObject>();
-
-			for(Link lk : links) {
-				if(lk.getDst() == dpid && lk.getDstPort() == port) {
-					ports.add(createMockPort(lk.getSrc(), lk.getSrcPort()));
-				}
-			}
-
-			return ports;
-		}
-		
-	}
-
-	/**
-	 * Class defines a function called back when {@link LinkStorageImplTest} is called.
-	 * @author Naoki Shiota
-	 *
-	 */
-	private class GetPortsCallback implements IAnswer< Iterable <IPortObject> > {
-		private long dpid;
-		
-		public GetPortsCallback(long dpid) {
-			this.dpid = dpid;
-		}
-		
-		@Override
-		public Iterable<IPortObject> answer() throws Throwable {
-			List<IPortObject> ports = new ArrayList<IPortObject>();
-			
-			for(Short number : getPorts(dpid)) {
-				ports.add(createMockPort(dpid, number));
-			}
-
-			return ports;
-		}
-	}
-
-	// ------------------------Creation of Mock-----------------------------
-	/**
-	 * Create a mock {@link GraphDBOperation} which hooks port-related methods.
-	 * @return EasyMock-wrapped GraphDBOperation object.
-	 */
-	private GraphDBOperation createMockGraphDBOperation() {
-		GraphDBOperation mockDBOpe = EasyMock.createNiceMock(GraphDBOperation.class);
-		
-		// Mock searchPort() method to create new mock IPortObject.
-		EasyMock.expect(mockDBOpe.searchPort((String)EasyMock.anyObject(), EasyMock.anyShort())).
-			andAnswer(new IAnswer<IPortObject>() {
-			@Override
-			public IPortObject answer() throws Throwable {
-				long dpid = HexString.toLong((String)EasyMock.getCurrentArguments()[0]);
-				short port = (Short) EasyMock.getCurrentArguments()[1];
-				IPortObject ret = createMockPort(dpid,port);
-				
-				return ret;
-			}
-		}).anyTimes();
-		
-		// Mock searchSwitch() method to create new mock ISwitchObject.
-		EasyMock.expect(mockDBOpe.searchSwitch((String)EasyMock.anyObject())).
-			andAnswer(new IAnswer<ISwitchObject>() {
-			@Override
-			public ISwitchObject answer() throws Throwable {
-				long dpid = HexString.toLong((String)EasyMock.getCurrentArguments()[0]);
-				ISwitchObject ret = createMockSwitch(dpid);
-				
-				return ret;
-			}
-		}).anyTimes();
-		
-		// Mock getActiveSwitches() method to create list of mock ISwitchObject.
-		EasyMock.expect(mockDBOpe.getActiveSwitches()).andReturn(new ArrayList<ISwitchObject> () {{
-			for(Long dpid : getDpids()) {
-				add(createMockSwitch(dpid));
-			}
-		}}).anyTimes();
-
-		// Mock commit() method to commit change of link information
-		mockDBOpe.commit();
-		EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
-			@Override
-			public Object answer() throws Throwable {
-				for(LinkEvent action : actions) {
-					if(action.getType().equals(LinkEventType.ADD)) {
-						Link linkToAdd = new Link(
-								action.getSrcDpid(),
-								action.getSrcPort(),
-								action.getDstDpid(),
-								action.getDstPort());
-						links.add(linkToAdd);
-					} else if(action.getType().equals(LinkEventType.DELETE)) {
-						Link linkToRemove = new Link(
-								action.getSrcDpid(),
-								action.getSrcPort(),
-								action.getDstDpid(),
-								action.getDstPort());
-						links.remove(linkToRemove);
-					} else {
-						log.error("mock commit(): unexpected action {}", new Object[]{action.getType()});
-					}
-				}
-				actions.clear();
-				return null;
-			}
-		}).atLeastOnce();
-		
-		EasyMock.replay(mockDBOpe);
-		return mockDBOpe;
-	}
-	
-	/**
-	 * Create a mock {@link IPortObject} using given DPID and port number.
-	 * {@link IPortObject} can't store DPID, so DPID is stored to mockToPortInfoMap for later use.
-	 * Duplication is not checked.
-	 * @param dpid DPID of a port
-	 * @param number Port Number
-	 * @return EasyMock-wrapped IPortObject
-	 */
-	private IPortObject createMockPort(long dpid, short number) {
-		IPortObject mockPort = EasyMock.createNiceMock(IPortObject.class);
-		
-		EasyMock.expect(mockPort.getNumber()).andReturn(number);
-		
-		// Mock removeLink() method
-		mockPort.removeLink((IPortObject) EasyMock.anyObject());
-		EasyMock.expectLastCall().andAnswer(new RemoveLinkCallback(dpid, number)).anyTimes();
-		
-		// Mock setLinkPort() method
-		mockPort.setLinkPort((IPortObject) EasyMock.anyObject());
-		EasyMock.expectLastCall().andAnswer(new SetLinkPortCallback(dpid, number)).anyTimes();
-		
-		// Mock getLinkPorts() method
-		EasyMock.expect(mockPort.getLinkedPorts()).andAnswer(new GetLinkedPortsCallback(dpid, number)).anyTimes();
-
-		// Mock getReverseLinkPorts() method
-		EasyMock.expect(mockPort.getReverseLinkedPorts()).andAnswer(new GetReverseLinkedPortsCallback(dpid, number)).anyTimes();
-		
-		// Mock getSwitch() method
-		EasyMock.expect(mockPort.getSwitch()).andAnswer(new GetSwitchCallback(dpid)).anyTimes();
-		
-		mockToPortInfoMap.put(mockPort, new PortInfo(dpid,number));
-		EasyMock.replay(mockPort);
-		
-		return mockPort;
-	}
-	
-	/**
-	 * Create a mock {@link ISwitchObject} using given DPID number.
-	 * Duplication is not checked.
-	 * @param dpid DPID of a switch
-	 * @return EasyMock-wrapped ISwitchObject
-	 */
-	private ISwitchObject createMockSwitch(long dpid) {
-		ISwitchObject mockSw = EasyMock.createNiceMock(ISwitchObject.class);
-		
-		EasyMock.expect(mockSw.getPorts()).andAnswer(new GetPortsCallback(dpid)).anyTimes();
-		EasyMock.expect(mockSw.getDPID()).andReturn(HexString.toHexString(dpid)).anyTimes();
-		EasyMock.expect(mockSw.getState()).andReturn("ACTIVE").anyTimes();
-		
-		EasyMock.replay(mockSw);
-		return mockSw;
-	}
-
-
-	//----------------- 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
-	
-	/**
-	 * Initialize links member to represent test topology above.
-	 */
-	private void initLinks() {
-		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));
-	}
-	
-	/**
-	 * Returns list of port number attached to the switch specified by given DPID.
-	 * @param dpid DPID of the switch
-	 * @return List of port number
-	 */
-	private List<Short> getPorts(long dpid) {
-		List<Short> ports;
-		
-		if(dpid == Long.decode("0x0000000000000a01")) {
-			ports = new ArrayList<Short>() {{
-				add((short)1);
-				add((short)2);
-				add((short)3);
-				add((short)4);
-			}};
-		} else if(dpid == Long.decode("0x0000000000000a02") || dpid == Long.decode("0x0000000000000a03")) {
-			ports = new ArrayList<Short>() {{
-				add((short)1);
-				add((short)2);
-			}};
-		} else {
-			ports = new ArrayList<Short>();
-		}
-		
-		return ports;
-	}
-	
-	/**
-	 * Returns list of DPIDs in test topology.
-	 * @return List of DPIDs
-	 */
-	private List<Long> getDpids() {
-		List<Long> dpids = new ArrayList<Long>() {{
-			add(Long.decode("0x0000000000000a01"));
-			add(Long.decode("0x0000000000000a02"));
-			add(Long.decode("0x0000000000000a03"));
-		}};
-		
-		return dpids;
-	}
-	
-	/**
-	 * Returns new {@link Link} object of an existing link
-	 * @return new Link object
-	 */
-	private Link createExistingLink() {
-		return new Link(Long.decode("0x0000000000000a01"), 1, Long.decode("0x0000000000000a02"), 1);
-	}
-	
-	/**
-	 * Returns new {@link Link} object of a not-existing but feasible link
-	 * @return new Link object
-	 */
-	private Link createFeasibleLink() {
-		return new Link(Long.decode("0x0000000000000a01"), 3, Long.decode("0x0000000000000a03"), 1);
-	}
-	
-	/**
-	 * Returns list of existing {@link Link} objects
-	 * @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 Link} objects that are all not-existing but feasible
-	 * @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 {@link 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/onrc/onos/ofcontroller/core/internal/SwitchStorageImplTest.java b/src/test/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImplTest.java
deleted file mode 100644
index fdc13db..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImplTest.java
+++ /dev/null
@@ -1,788 +0,0 @@
-package net.onrc.onos.ofcontroller.core.internal;
-
-import static org.easymock.EasyMock.*;
-import net.onrc.onos.graph.GraphDBConnection;
-import net.onrc.onos.graph.GraphDBOperation;
-import net.onrc.onos.ofcontroller.core.ISwitchStorage;
-import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
-import net.onrc.onos.ofcontroller.core.internal.SwitchStorageImpl;
-import net.onrc.onos.ofcontroller.core.INetMapStorage.DM_OPERATION;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
-
-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.protocol.OFPhysicalPort.OFPortState;
-import org.powermock.api.easymock.PowerMock;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-import org.slf4j.LoggerFactory;
-
-import com.thinkaurelius.titan.core.TitanFactory;
-
-//Add Powermock preparation
-@Ignore //TODO broken 11/19/13, should fix
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({TitanFactory.class, GraphDBConnection.class, GraphDBOperation.class, SwitchStorageImpl.class})
-public class SwitchStorageImplTest {
-
-	protected static org.slf4j.Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
-
-	String conf;
-        String dbStore;
-    private GraphDBConnection mockConn = null;
-    private GraphDBOperation mockOpe = null;
-    ISwitchStorage swSt = null;
-    
-	@Before
-	public void setUp() throws Exception {
-		
-		swSt = new SwitchStorageImpl();
-                dbStore = "dummyStore";
-		conf = "/dummy/path/to/db";
-		
-        // Make mock cassandra DB
-		// Replace TitanFactory.open() to return mock DB
-
-		PowerMock.mockStatic(GraphDBConnection.class);
-		mockConn = createMock(GraphDBConnection.class);
-		PowerMock.suppress(PowerMock.constructor(GraphDBConnection.class));
-		EasyMock.expect(GraphDBConnection.getInstance((String)EasyMock.anyObject())).andReturn(mockConn);
-		PowerMock.replay(GraphDBConnection.class);
-		
-		PowerMock.mockStatic(GraphDBOperation.class);
-		mockOpe = PowerMock.createStrictMock(GraphDBOperation.class);
-		PowerMock.expectNew(GraphDBOperation.class, mockConn).andReturn(mockOpe);
-		PowerMock.replay(GraphDBOperation.class);
-        // Replace the conf to dummy conf
-		// String conf = "/tmp/cassandra.titan";
-		
-
-	}
-
-	@After
-	public void tearDown() throws Exception {
-		swSt.close();
-		swSt = null;
-		
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for addSwitch method.
-	 * Condition:
-	 *  Normal
-	 * Expect:
-	 * 	Call SwitchStorageImpl.addSwitch func with proper properties.
-	 */
-	@Test
-	public void testAddSwitch() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		String state = "ACTIVE";
-		
-		//Mock Switch
-		ISwitchObject mockISw = createMock(ISwitchObject.class);
-		mockISw.setState(state);
-		replay(mockISw);
-		
-		//Expectation of mock operation.
-		expect(mockOpe.searchSwitch(dpid)).andReturn(null);
-		expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
-		mockOpe.commit();
-		mockOpe.close();
-		replay(mockOpe);
-		
-		swSt.init(dbStore, conf);
-		swSt.addSwitch(dpid);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for addSwitch method.
-	 * Condition:
-	 *  The switch is already existing.
-	 * Expect:
-	 * 	Call SwitchStorageImpl.addSwitch func with proper properties.
-	 */
-	//@Ignore 
-	@Test
-	public void testAddSwitchExisting() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		String state = "ACTIVE";
-		
-		//Mock Switch
-		ISwitchObject mockISw = createMock(ISwitchObject.class);
-		mockISw.setState(state);
-		mockISw.setState(state);
-		expect(mockISw.getDPID()).andReturn(dpid).anyTimes();
-		replay(mockISw);
-		
-		//Expectation of mock operation.
-		expect(mockOpe.searchSwitch(dpid)).andReturn(null);
-		expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
-		mockOpe.commit();
-		expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
-		mockOpe.commit();
-		mockOpe.close();
-		replay(mockOpe);
-		
-		swSt.init(dbStore, conf);
-		swSt.addSwitch(dpid);
-		swSt.addSwitch(dpid);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for addSwitch method.
-	 * Condition:
-	 *  The switch construction is fail and return null
-	 * Expect:
-	 * 	Write the status as info log.
-	 */
-	@Test
-	public void testAddSwitchAbnormal() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		
-		//Expectation of mock operation.
-		expect(mockOpe.searchSwitch(dpid)).andReturn(null);
-		expect(mockOpe.newSwitch(dpid)).andReturn(null);
-		mockOpe.rollback();
-		mockOpe.close();
-		replay(mockOpe);
-		
-		swSt.init(dbStore, conf);
-		swSt.addSwitch(dpid);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for addSwitch method.
-	 * Condition:
-	 *  Throw runtimeException. 
-	 * Expect:
-	 * 	The rollback method is called.
-	 */
-	//@Ignore 
-	@Test
-	public void testAddSwitchException() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		String state = "ACTIVE";
-		
-		//Mock Switch
-		ISwitchObject mockISw = createMock(ISwitchObject.class);
-		mockISw.setState(state);
-		replay(mockISw);
-		
-		//Expectation of mock operation.
-		expect(mockOpe.searchSwitch(dpid)).andReturn(null);
-		expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
-		mockOpe.commit();
-		expectLastCall().andThrow(new RuntimeException());
-		mockOpe.rollback();
-		mockOpe.close();
-		replay(mockOpe);
-		
-		swSt.init(dbStore, conf);
-		swSt.addSwitch(dpid);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for updateSwitch method.
-	 * Condition:
-	 *  SwitchState : INACTIVE
-	 *  DMOPERATION : UPDATE
-	 * Expect:
-	 * 	Should call addSwitch function and commit.
-	 */
-	//@Ignore 
-	@Test
-	public void testUpdateUPDATE() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		SwitchState stateINACTIVE = SwitchState.INACTIVE;
-		DM_OPERATION opUPDATE = DM_OPERATION.UPDATE;
-		
-		//Mock Switch
-		ISwitchObject mockISw = createMock(ISwitchObject.class);
-		mockISw.setState(stateINACTIVE.toString());
-		expect(mockISw.getDPID()).andReturn(dpid).anyTimes();
-		replay(mockISw);
-		
-		//Expectation of mock operation.
-		expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
-		mockOpe.commit();
-		mockOpe.close();
-		replay(mockOpe);
-		
-		swSt.init(dbStore, conf);
-		swSt.updateSwitch(dpid, stateINACTIVE, opUPDATE);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for updateSwitch method.
-	 * Condition:
-	 *  SwitchState : INACTIVE
-	 *  DMOPERATION : CREATE
-	 * Expect:
-	 * 	Should call addSwitch function and commit.
-	 */
-	//@Ignore 
-	@Test
-	public void testUpdateCREATE() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		SwitchState stateINACTIVE = SwitchState.INACTIVE;
-		DM_OPERATION opCREATE = DM_OPERATION.CREATE;
-		
-		//Mock Switch
-		ISwitchObject mockISw = createMock(ISwitchObject.class);
-		mockISw.setState("ACTIVE");
-		mockISw.setState(stateINACTIVE.toString());
-		expect(mockISw.getDPID()).andReturn(dpid).anyTimes();
-		replay(mockISw);
-		
-		//Expectation of mock operation.
-		expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);	
-		mockOpe.commit();
-		mockOpe.close();
-		replay(mockOpe);
-		
-		swSt.init(dbStore, conf);
-		swSt.updateSwitch(dpid, stateINACTIVE, opCREATE);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for updateSwitch method.
-	 * Condition:
-	 *  SwitchState : INACTIVE
-	 *  DMOPERATION : INSERT
-	 * Expect:
-	 * 	Should call addSwitch function and commit.
-	 */
-	//@Ignore 
-	@Test
-	public void testUpdateINSERT() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		SwitchState stateINACTIVE = SwitchState.INACTIVE;
-		DM_OPERATION opINSERT = DM_OPERATION.INSERT;
-		
-		//Mock Switch
-		ISwitchObject mockISw = createMock(ISwitchObject.class);
-		mockISw.setState("ACTIVE");
-		mockISw.setState(stateINACTIVE.toString());
-		expect(mockISw.getDPID()).andReturn(dpid).anyTimes();
-		replay(mockISw);
-		
-		//Expectation of mock operation.
-		expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
-		mockOpe.commit();
-		mockOpe.close();
-		replay(mockOpe);
-		
-		swSt.init(dbStore, conf);
-		swSt.updateSwitch(dpid, stateINACTIVE, opINSERT);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for updateSwitch method.
-	 * Condition:
-	 *  SwitchState : ACTIVE
-	 *  DMOPERATION : DELETE
-	 * Expect:
-	 * 	Should call removeSwitch function and commit.
-	 */
-	//@Ignore 
-	@Test
-	public void testUpdateDELETE() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		SwitchState stateACTIVE = SwitchState.ACTIVE;
-		DM_OPERATION opDELETE = DM_OPERATION.DELETE;
-		
-		//Mock Switch
-		ISwitchObject mockISw = createMock(ISwitchObject.class);
-		mockISw.setState(stateACTIVE.toString());
-		expect(mockISw.getDPID()).andReturn(dpid).anyTimes();
-		replay(mockISw);
-		
-		//Expectation of mock operation.
-		expect(mockOpe.searchSwitch(dpid)).andReturn(null);
-		expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
-		mockOpe.commit();
-		expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
-		mockOpe.removeSwitch(mockISw);
-		mockOpe.commit();
-		mockOpe.close();
-		replay(mockOpe);
-		
-		swSt.init(dbStore, conf);
-		swSt.addSwitch(dpid);
-		swSt.updateSwitch(dpid, stateACTIVE, opDELETE);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for deleteSwitch method.
-	 * Condition:
-	 *  The switch is existing.
-	 * Expect:
-	 * 	Should call removeSwitch function and commit.
-	 */
-	//@Ignore
-	@Test
-	public void testDeleteSwitch() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		String state = "ACTIVE";
-	
-		//Mock Switch
-		ISwitchObject mockISw = createMock(ISwitchObject.class);
-		mockISw.setState(state);
-		expect(mockISw.getDPID()).andReturn(dpid).anyTimes();
-		replay(mockISw);
-		
-		//Expectation of mock operation.
-		expect(mockOpe.searchSwitch(dpid)).andReturn(null);
-		expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
-		mockOpe.commit();
-		expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
-    	mockOpe.removeSwitch(mockISw);
-    	mockOpe.commit();
-		mockOpe.close();
-		replay(mockOpe);
-		
-		swSt.init(dbStore, conf);
-		swSt.addSwitch(dpid);
-		swSt.deleteSwitch(dpid);
-		
-		//Iterator<Vertex> it = titanGraph.getVertices("dpid", dpid).iterator();
-		//assertFalse(it.hasNext());
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for deleteSwitch method.
-	 * Condition:
-	 *  The commit func throw exception.
-	 * Expect:
-	 * 	Should call rollback.
-	 */
-	@Test
-	public void testDeleteSwitchException() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		String state = "ACTIVE";
-		
-		//Mock Switch
-		ISwitchObject mockISw = createMock(ISwitchObject.class);
-		mockISw.setState(state);
-		expect(mockISw.getDPID()).andReturn(dpid).anyTimes();
-		replay(mockISw);
-		
-		//Expectation of mock operation.
-		expect(mockOpe.searchSwitch(dpid)).andReturn(null);
-		expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
-		mockOpe.commit();
-		expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
-		mockOpe.removeSwitch(mockISw);
-		mockOpe.commit();
-		expectLastCall().andThrow(new RuntimeException());
-		mockOpe.rollback();
-		mockOpe.close();
-		replay(mockOpe);
-		
-		swSt.init(dbStore, conf);
-		swSt.addSwitch(dpid);
-		swSt.deleteSwitch(dpid);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for addPort method.
-	 * Condition:
-	 *  port is existing.
-	 * Expect:
-	 * 	Should call addPort and commit.
-	 */
-	//@Ignore
-	@Test
-	public void testAddPort() {
-		String dpid = "00:00:00:00:00:00:0a:01";
-		short portNumber = 5;
-		String state = "ACTIVE";
-		String name = "port 5 at SEA switch";
-		
-		OFPhysicalPort portToAdd = new OFPhysicalPort();
-		portToAdd.setName(name);
-		portToAdd.setCurrentFeatures(OFPhysicalPort.OFPortFeatures.OFPPF_100MB_FD.getValue());
-		portToAdd.setPortNumber(portNumber);
-		portToAdd.setState(OFPortState.OFPPS_STP_FORWARD.getValue());
-		
-		//Expectation of  mock Port
-		IPortObject mockIPort = createMock(IPortObject.class);
-		mockIPort.setState(state);
-		mockIPort.setPortState(OFPortState.OFPPS_STP_FORWARD.getValue());
-		mockIPort.setDesc(name);
-		replay(mockIPort);
-		
-		//Expectation of mock Switch
-		ISwitchObject mockISw = createMock(ISwitchObject.class);
-		mockISw.setState(state);
-		mockISw.addPort(mockIPort);
-		expect(mockISw.getPort(anyShort())).andReturn(null);
-		expect(mockISw.getDPID()).andReturn(dpid).anyTimes();
-		replay(mockISw);
-		
-		//Expectation of mock operation.
-		expect(mockOpe.searchSwitch(dpid)).andReturn(null);
-		expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
-		mockOpe.commit();
-		expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
-//		expect(mockOpe.searchPort(dpid, portNumber)).andReturn(null);
-		expect(mockOpe.newPort(dpid, portNumber)).andReturn(mockIPort);	
-		mockOpe.commit();
-		mockOpe.close();
-		replay(mockOpe);
-
-		swSt.init(dbStore, conf);
-		swSt.addSwitch(dpid);
-		swSt.addPort(dpid, portToAdd);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for addPort method.
-	 * Condition:
-	 *  Port status is down.
-	 * Expect:
-	 * 	Should call removePort and commit.
-	 */
-	//@Ignore
-	@Test
-	public void testAddPortWithPortLinkDown() {
-		String dpid = "00:00:00:00:00:00:0a:01";
-		short portNumber = 5;
-		String swState = "ACTIVE";
-//		String portState = "INACTIVE";
-		String portId = "5";
-		String name = "port 5 at SEA switch";
-		
-		OFPhysicalPort portToAdd = new OFPhysicalPort();
-		portToAdd.setName(name);
-		portToAdd.setCurrentFeatures(OFPhysicalPort.OFPortFeatures.OFPPF_100MB_FD.getValue());
-		portToAdd.setPortNumber(portNumber);
-		portToAdd.setState(OFPortState.OFPPS_LINK_DOWN.getValue());
-		
-		//Expectation of  mock Port
-		IPortObject mockIPort = createMock(IPortObject.class);
-		expect(mockIPort.getPortId()).andReturn(portId);
-//		mockIPort.setState(portState);
-//		mockIPort.setPortState(OFPortState.OFPPS_STP_FORWARD.getValue());
-//		mockIPort.setDesc(name);
-		replay(mockIPort);
-		
-		//Expectation of mock Switch
-		ISwitchObject mockISw = createMock(ISwitchObject.class);
-		mockISw.setState(swState);
-//		mockISw.removePort(mockIPort);
-		expect(mockISw.getPort(anyShort())).andReturn(mockIPort);
-		expect(mockISw.getDPID()).andReturn(dpid).anyTimes();
-		replay(mockISw);
-		
-		//Expectation of mock operation.
-		expect(mockOpe.searchSwitch(dpid)).andReturn(null);
-		expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);	
-		mockOpe.commit();
-		expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
-//		expect(mockOpe.searchPort(dpid, portNumber)).andReturn(mockIPort);
-		mockOpe.removePort(mockIPort);
-		mockOpe.commit();
-		mockOpe.close();
-		replay(mockOpe);
-
-		swSt.init(dbStore, conf);
-		swSt.addSwitch(dpid);
-		swSt.addPort(dpid, portToAdd);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for addPort method.
-	 * Condition:
-	 *  The switch is not existing.
-	 * Expect:
-	 * 	Nothing happens.
-	 */
-	@Test
-	public void testAddPortAbnormalNoSwitch() {
-		String dpid = "00:00:00:00:00:00:0a:01";
-		short portNumber = 5;
-		String name = "port 5 at SEA switch";
-		
-		OFPhysicalPort portToAdd = new OFPhysicalPort();
-		portToAdd.setName(name);
-		portToAdd.setCurrentFeatures(OFPhysicalPort.OFPortFeatures.OFPPF_100MB_FD.getValue());
-		portToAdd.setPortNumber(portNumber);
-		portToAdd.setState(OFPortState.OFPPS_STP_FORWARD.getValue());
-		
-		//Expectation of  mock Port
-		IPortObject mockIPort = createStrictMock(IPortObject.class);
-		replay(mockIPort);
-		
-		//Expectation of mock Switch
-		ISwitchObject mockISw = createStrictMock(ISwitchObject.class);
-		expect(mockISw.getDPID()).andReturn(dpid).anyTimes();
-		replay(mockISw);
-		
-		//Expectation of mock operation.
-		expect(mockOpe.searchSwitch(dpid)).andReturn(null);
-		mockOpe.close();
-		replay(mockOpe);
-
-		swSt.init(dbStore, conf);
-		swSt.addPort(dpid, portToAdd);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for addPort method.
-	 * Condition:
-	 *  port is not existing.
-	 * Expect:
-	 * 	Should call addPort and commit.
-	 */
-	//@Ignore
-	@Test
-	public void testAddPortAbnormalNoPort() {
-		String dpid = "00:00:00:00:00:00:0a:01";
-		short portNumber = 5;
-		String state = "ACTIVE";
-		String name = "port 5 at SEA switch";
-		
-		OFPhysicalPort portToAdd = new OFPhysicalPort();
-		portToAdd.setName(name);
-		portToAdd.setCurrentFeatures(OFPhysicalPort.OFPortFeatures.OFPPF_100MB_FD.getValue());
-		portToAdd.setPortNumber(portNumber);
-		portToAdd.setState(OFPortState.OFPPS_STP_FORWARD.getValue());
-		
-		//Expectation of  mock Port
-		IPortObject mockIPort = createMock(IPortObject.class);
-		mockIPort.setState(state);
-		mockIPort.setPortState(OFPortState.OFPPS_STP_FORWARD.getValue());
-		mockIPort.setDesc(name);
-		replay(mockIPort);
-		
-		//Expectation of mock Switch
-		ISwitchObject mockISw = createMock(ISwitchObject.class);
-		mockISw.setState(state);
-		mockISw.addPort(mockIPort);
-		expect(mockISw.getPort(portNumber)).andReturn(null);
-		expect(mockISw.getDPID()).andReturn(dpid).anyTimes();
-		replay(mockISw);
-		
-		//Expectation of mock operation.
-		expect(mockOpe.searchSwitch(dpid)).andReturn(null);
-		expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
-		mockOpe.commit();
-		expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
-//		expect(mockOpe.searchPort(dpid, portNumber)).andReturn(null);
-		expect(mockOpe.newPort(dpid, portNumber)).andReturn(null);	
-		mockOpe.rollback();
-		mockOpe.close();
-		replay(mockOpe);
-
-		swSt.init(dbStore, conf);
-		swSt.addSwitch(dpid);
-		swSt.addPort(dpid, portToAdd);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for addPort method.
-	 * Condition:
-	 *  commit throw the exception.
-	 * Expect:
-	 * 	Should call rollback.
-	 */
-	//@Ignore
-	@Test
-	public void testAddPortWithException() {
-		String dpid = "00:00:00:00:00:00:0a:01";
-		short portNumber = 5;
-		String state = "ACTIVE";
-		String name = "port 5 at SEA switch";
-		
-		OFPhysicalPort portToAdd = new OFPhysicalPort();
-		portToAdd.setName(name);
-		portToAdd.setCurrentFeatures(OFPhysicalPort.OFPortFeatures.OFPPF_100MB_FD.getValue());
-		portToAdd.setPortNumber(portNumber);
-		portToAdd.setState(OFPortState.OFPPS_STP_FORWARD.getValue());
-		
-		//Expectation of  mock Port
-		IPortObject mockIPort = createMock(IPortObject.class);
-		mockIPort.setState(state);
-		mockIPort.setPortState(OFPortState.OFPPS_STP_FORWARD.getValue());
-		mockIPort.setDesc(name);
-		replay(mockIPort);
-		
-		//Expectation of mock Switch
-		ISwitchObject mockISw = createMock(ISwitchObject.class);
-		mockISw.setState(state);
-		mockISw.addPort(mockIPort);
-		expect(mockISw.getPort(portNumber)).andReturn(null);
-		expect(mockISw.getDPID()).andReturn(dpid).anyTimes();
-		replay(mockISw);
-		
-		//Expectation of mock operation.
-		expect(mockOpe.searchSwitch(dpid)).andReturn(null);
-		expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
-		mockOpe.commit();
-		expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
-//		expect(mockOpe.searchPort(dpid, portNumber)).andReturn(null);
-		expect(mockOpe.newPort(dpid, portNumber)).andReturn(mockIPort);	
-		mockOpe.commit();
-		expectLastCall().andThrow(new RuntimeException());
-		mockOpe.rollback();
-		mockOpe.close();
-		replay(mockOpe);
-
-		swSt.init(dbStore, conf);
-		swSt.addSwitch(dpid);
-		swSt.addPort(dpid, portToAdd);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for deletePort method.
-	 * Condition:
-	 *  port is existing.
-	 * Expect:
-	 * 	Should call removePort and commit.
-	 */
-	//@Ignore
-	@Test
-	public void testDeletePort() {
-		String dpid = "00:00:00:00:00:00:0a:01";
-		short portNumber = 5;
-		String portState = "INACTIVE";
-		String swState = "ACTIVE";
-		String portId = "5";
-		String name = "port 5 at SEA switch";
-		
-		OFPhysicalPort portToAdd = new OFPhysicalPort();
-		portToAdd.setName(name);
-		portToAdd.setCurrentFeatures(OFPhysicalPort.OFPortFeatures.OFPPF_100MB_FD.getValue());
-		portToAdd.setPortNumber(portNumber);
-		portToAdd.setState(OFPortState.OFPPS_STP_FORWARD.getValue());
-		
-		//Expectation of  mock Port
-		IPortObject mockIPort = createMock(IPortObject.class);
-		mockIPort.setState(swState);
-//		mockIPort.setPortState(OFPortState.OFPPS_STP_FORWARD.getValue());
-		mockIPort.setDesc(name);
-		mockIPort.setState(portState);
-		expect(mockIPort.getPortId()).andReturn(portId);
-		replay(mockIPort);
-		
-		//Expectation of mock Switch
-		ISwitchObject mockISw = createMock(ISwitchObject.class);
-		mockISw.setState(swState);
-//		mockISw.removePort(mockIPort);
-		expect(mockISw.getPort(portNumber)).andReturn(null);
-		mockISw.addPort(mockIPort);
-		expect(mockISw.getPort(portNumber)).andReturn(mockIPort);
-		expect(mockISw.getDPID()).andReturn(dpid).anyTimes();
-		replay(mockISw);
-		
-		//Expectation of mock operation.
-		expect(mockOpe.searchSwitch(dpid)).andReturn(null);
-		expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
-		mockOpe.commit();
-		expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
-//		expect(mockOpe.searchPort(dpid, portNumber)).andReturn(null);
-		expect(mockOpe.newPort(dpid, portNumber)).andReturn(mockIPort);	
-		mockOpe.commit();
-		expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
-//		expect(mockOpe.searchPort(dpid, portNumber)).andReturn(mockIPort);
-		mockOpe.removePort(mockIPort);
-		mockOpe.commit();
-		mockOpe.close();
-		replay(mockOpe);
-
-		swSt.init(dbStore, conf);
-		swSt.addSwitch(dpid);
-		swSt.addPort(dpid, portToAdd);
-		swSt.deletePort(dpid, portNumber);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for addPort method.
-	 * Condition:
-	 *  commit throws the exception.
-	 * Expect:
-	 * 	Should call rollback.
-	 */
-	//@Ignore
-	@Test
-	public void testDeletePortException() {
-		String dpid = "00:00:00:00:00:00:0a:01";
-		short portNumber = 5;
-		String swState = "ACTIVE";
-		String portState = "INACTIVE";
-		String portId = "5";
-		String name = "port 5 at SEA switch";
-		
-		OFPhysicalPort portToAdd = new OFPhysicalPort();
-		portToAdd.setName(name);
-		portToAdd.setCurrentFeatures(OFPhysicalPort.OFPortFeatures.OFPPF_100MB_FD.getValue());
-		portToAdd.setPortNumber(portNumber);
-		portToAdd.setState(OFPortState.OFPPS_STP_FORWARD.getValue());
-		
-		//Expectation of  mock Port
-		IPortObject mockIPort = createMock(IPortObject.class);
-		mockIPort.setState(swState);
-		mockIPort.setPortState(OFPortState.OFPPS_STP_FORWARD.getValue());
-		mockIPort.setDesc(name);
-		mockIPort.setState(portState);
-		expect(mockIPort.getPortId()).andReturn(portId);
-		replay(mockIPort);
-		
-		//Expectation of mock Switch
-		ISwitchObject mockISw = createMock(ISwitchObject.class);
-		mockISw.setState(swState);
-		mockISw.addPort(mockIPort);
-		expect(mockISw.getPort(portNumber)).andReturn(null);
-		expect(mockISw.getPort(portNumber)).andReturn(mockIPort).anyTimes();
-//		mockISw.removePort(mockIPort);
-		
-		expect(mockISw.getDPID()).andReturn(dpid).anyTimes();
-		replay(mockISw);
-		
-		//Expectation of mock operation.
-		expect(mockOpe.searchSwitch(dpid)).andReturn(null);
-		expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
-		mockOpe.commit();
-		expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
-//		expect(mockOpe.searchPort(dpid, portNumber)).andReturn(null);
-		expect(mockOpe.newPort(dpid, portNumber)).andReturn(mockIPort);	
-		mockOpe.commit();
-		expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
-//		expect(mockOpe.searchPort(dpid, portNumber)).andReturn(mockIPort);
-//		mockOpe.commit(); // Cannot generate exception..need to revisit this test
-		mockOpe.removePort(mockIPort);
-		expectLastCall().andThrow(new RuntimeException());
-		mockOpe.rollback();
-		mockOpe.close();
-		replay(mockOpe);
-	
-		swSt.init(dbStore, conf);
-		swSt.addSwitch(dpid);
-		swSt.addPort(dpid, portToAdd);
-		swSt.deletePort(dpid, portNumber);
-	}
-}
\ No newline at end of file
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImplTestBB.java b/src/test/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImplTestBB.java
deleted file mode 100644
index fe51f95..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImplTestBB.java
+++ /dev/null
@@ -1,349 +0,0 @@
-package net.onrc.onos.ofcontroller.core.internal;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import net.floodlightcontroller.core.internal.TestDatabaseManager;
-import net.onrc.onos.graph.GraphDBConnection;
-import net.onrc.onos.graph.GraphDBOperation;
-import net.onrc.onos.ofcontroller.core.INetMapStorage;
-import net.onrc.onos.ofcontroller.core.INetMapStorage.DM_OPERATION;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
-import net.onrc.onos.ofcontroller.core.ISwitchStorage;
-import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
-
-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.protocol.OFPhysicalPort.OFPortState;
-import org.powermock.api.easymock.PowerMock;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-import org.slf4j.LoggerFactory;
-
-import com.thinkaurelius.titan.core.TitanFactory;
-import com.thinkaurelius.titan.core.TitanGraph;
-
-/*
- * Jono, 11/4/2013
- * These tests are being ignored because they don't work because they
- * rely on test functionality that was written ages ago and hasn't been
- * updated as the database schema has evolved. 
- * These tests work by getting an in-memory Titan database and testing
- * the SwitchStorageImpl on top of that. In this regard they're not really
- * unit tests as they test the entire DB stack (i.e. GraphDBOperation and
- * GraphDBConnection), not just SwitchStorageImpl.
- * I've left them here as we may wish to resurrect this kind of 
- * integration testing of the DB layers in the future.
- */
-@Ignore
-//Add Powermock preparation
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({TitanFactory.class, GraphDBConnection.class, GraphDBOperation.class, SwitchStorageImpl.class})
-public class SwitchStorageImplTestBB {
-
-	protected static org.slf4j.Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
-
-	String conf;
-        String dbStore;
-    private GraphDBConnection conn = null;
-    private GraphDBOperation ope = null;
-    private TitanGraph titanGraph = null;
-    ISwitchStorage swSt = null;
-    
-	@Before
-	public void setUp() throws Exception {
-		
-		swSt = new SwitchStorageImpl();
-		conf = "/dummy/path/to/db";
-                dbStore ="dummyStore";
-		
-		// Make mock cassandra DB
-		// Replace TitanFactory.open() to return mock DB
-		titanGraph = TestDatabaseManager.getTestDatabase();
-		TestDatabaseManager.populateTestData(titanGraph);
-		PowerMock.mockStatic(TitanFactory.class);
-		EasyMock.expect(TitanFactory.open((String)EasyMock.anyObject())).andReturn(titanGraph);
-		PowerMock.replay(TitanFactory.class);
-		
-		conn = GraphDBConnection.getInstance(conf);
-		ope = new GraphDBOperation(conn);
-		
-		swSt.init(dbStore, conf);
-	}
-
-	@After
-	public void tearDown() throws Exception {
-		
-		titanGraph.shutdown();
-		TestDatabaseManager.deleteTestDatabase();
-
-		swSt.close();
-		swSt = null;
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for addSwitch method.
-	 * Condition:
-	 *  Normal
-	 * Expect:
-	 * 1. Switch should be generated.
-	 * 2. The status of switch should be ACTIVE
-	 */
-	//@Ignore 
-	@Test
-	public void testAddSwitch() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		
-		ISwitchObject sw = ope.searchSwitch(dpid);
-		assertTrue(sw == null);
-		swSt.addSwitch(dpid);
-		ISwitchObject sw2 = ope.searchSwitch(dpid);
-		assertTrue(sw2 != null);
-		assertEquals(sw2.getState(), "ACTIVE");
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for addSwitch method.
-	 * Condition:
-	 *  The existing switch status is INACTIVE.
-	 *  The switch is already existing.
-	 * Expect:
-	 * 1. After add the same switch, the status of switch should be ACTIVE
-	 */
-	//@Ignore 
-	@Test
-	public void testAddSwitchExisting() {
-		String dpid = "00:00:00:00:00:00:0a:06";
-		
-		swSt.updateSwitch(dpid, SwitchState.INACTIVE, DM_OPERATION.UPDATE);
-		ISwitchObject sw = ope.searchSwitch(dpid);
-		assertTrue(sw != null);
-		assertEquals(sw.getState(), SwitchState.INACTIVE.toString());
-		swSt.addSwitch(dpid);
-		ISwitchObject sw2 = ope.searchSwitch(dpid);
-		assertTrue(sw2 != null);
-		assertEquals(sw2.getState(), SwitchState.ACTIVE.toString());
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for testUpdate method.
-	 * Condition:
-	 *  The switch is not existing.
-	 *  The status of added switch is INACTIVE.
-	 *  DM_OPERATION is CREATE.
-	 * Expect:
-	 * 1. Switch should be created.
-	 * 2. The status of switch should be INACTIVE.
-	 */
-	//@Ignore 
-	@Test
-	public void testUpdate() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		SwitchState state = ISwitchStorage.SwitchState.INACTIVE;
-		DM_OPERATION dmope = INetMapStorage.DM_OPERATION.CREATE;
-		
-		ISwitchObject sw = ope.searchSwitch(dpid);
-		assertTrue(sw == null);
-		swSt.updateSwitch(dpid, state, dmope);
-		ISwitchObject sw2 = ope.searchSwitch(dpid);
-		assertTrue(sw2 != null);
-		assertEquals(sw2.getState(), state.toString());
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for testUpdate method.
-	 * Condition:
-	 *  The switch is existing.
-	 *  The status of added switch is ACTIVE.
-	 *  DM_OPERATION is DELETE.
-	 * Expect:
-	 * 1. Switch should be deleted.
-	 */
-	//@Ignore 
-	@Test
-	public void testUpdateWithDELETE() {
-		String dpid = "00:00:00:00:00:00:0a:06";
-		SwitchState state = ISwitchStorage.SwitchState.ACTIVE;
-		DM_OPERATION dmope = INetMapStorage.DM_OPERATION.DELETE;
-		
-		ISwitchObject sw = ope.searchSwitch(dpid);
-		assertTrue(sw != null);
-		swSt.updateSwitch(dpid, state, dmope);
-		ISwitchObject sw2 = ope.searchSwitch(dpid);
-		assertTrue(sw2 == null);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for delete switch method.
-	 * Condition:
-	 *  The switch is existing.
-	 * Expect:
-	 * 1. Switch should be deleted.
-	 */
-	//@Ignore 
-	@Test
-	public void testDeleteSwitch() {
-		String dpid = "00:00:00:00:00:00:0a:06";
-		
-		ISwitchObject sw = ope.searchSwitch(dpid);
-		assertTrue(sw != null);
-		swSt.deleteSwitch(dpid);
-		ISwitchObject sw2 = ope.searchSwitch(dpid);
-		assertTrue(sw2 == null);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for delete switch method.
-	 * Condition:
-	 *  The switch is not existing.
-	 * Expect:
-	 * Nothing happens.
-	 */
-	//@Ignore 
-	@Test
-	public void testDeleteNonExistingSwitch() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		
-		ISwitchObject sw = ope.searchSwitch(dpid);
-		assertTrue(sw == null);
-		swSt.deleteSwitch(dpid);
-		ISwitchObject sw2 = ope.searchSwitch(dpid);
-		assertTrue(sw2 == null);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for delete port method.
-	 * Condition:
-	 *  The port is existing.
-	 * Expect:
-	 *  Deleted the port.
-	 */
-	//@Ignore 
-	@Test
-	public void testDeletePort() {
-		String dpid = "00:00:00:00:00:00:0a:06";
-		short portNumber = 3;
-		
-		IPortObject portObj1 = ope.searchPort(dpid, portNumber);
-		assertTrue(portObj1 != null);
-		swSt.deletePort(dpid, portNumber);
-		IPortObject portObj2 = ope.searchPort(dpid, portNumber);
-		assertTrue(portObj2 == null);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for delete port method.
-	 * Condition:
-	 *  The port is not existing.
-	 * Expect:
-	 *  Nothing happens.
-	 */
-	//@Ignore 
-	@Test
-	public void testDeleteNonExistingPort() {
-		String dpid = "00:00:00:00:00:00:0a:06";
-		short portNumber = 4;
-		
-		IPortObject portObj1 = ope.searchPort(dpid, portNumber);
-		assertTrue(portObj1 == null);
-		swSt.deletePort(dpid, portNumber);
-		IPortObject portObj2 = ope.searchPort(dpid, portNumber);
-		assertTrue(portObj2 == null);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for add port method.
-	 * Condition:
-	 *  The port is not existing.
-	 * Expect:
-	 *  The port should be added.
-	 *  The desc of IPortObject is the same as the name of OFPhysicalPort.
-	 */
-	//@Ignore 
-	@Test
-	public void testAddPort() {
-		String dpid = "00:00:00:00:00:00:0a:06";
-		short portNumber = 4;
-		String name = "port 4 at ATL Switch";
-		int state = OFPortState.OFPPS_STP_FORWARD.getValue();
-		OFPhysicalPort port = new OFPhysicalPort(); 
-		port.setPortNumber(portNumber);
-		port.setName(name);
-		port.setState(state);
-		
-		ISwitchObject sw = ope.searchSwitch(dpid);
-		assertTrue(sw != null);
-		swSt.addPort(dpid, port);
-		IPortObject portObj = ope.searchPort(dpid, portNumber);
-		assertTrue(portObj != null);
-		assertEquals(portObj.getDesc(), name);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for add method.
-	 * Condition:
-	 *  The port is existing.
-	 * Expect:
-	 *  Nothing happens.
-	 */
-	//@Ignore 
-	@Test
-	public void testAddExistingPort() {
-		String dpid = "00:00:00:00:00:00:0a:06";
-		short portNumber = 3;
-		String name = "xxx";
-		int state = OFPortState.OFPPS_STP_FORWARD.getValue();
-		OFPhysicalPort port = new OFPhysicalPort(); 
-		port.setPortNumber(portNumber);
-		port.setName(name);
-		port.setState(state);
-		
-		ISwitchObject sw = ope.searchSwitch(dpid);
-		assertTrue(sw != null);
-		swSt.addPort(dpid, port);
-		IPortObject portObj = ope.searchPort(dpid, portNumber);
-		assertTrue(portObj != null);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for add method.
-	 * Condition:
-	 *  The port status is down.
-	 * Expect:
-	 *  Delete the port.
-	 */
-	//@Ignore 
-	@Test
-	public void testAddDownPort() {
-		String dpid = "00:00:00:00:00:00:0a:06";
-		short portNumber = 3;
-		String name = "port 3 at ATL Switch";
-		int state = OFPortState.OFPPS_LINK_DOWN.getValue();
-		OFPhysicalPort port = new OFPhysicalPort(); 
-		port.setPortNumber(portNumber);
-		port.setName(name);
-		port.setState(state);
-		
-		ISwitchObject sw = ope.searchSwitch(dpid);
-		assertTrue(sw != null);
-		swSt.addPort(dpid, port);
-		IPortObject portObj = ope.searchPort(dpid, portNumber);
-		assertTrue(portObj == null);
-	}
-}
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
deleted file mode 100644
index 8da306f..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableGraphDBOperation.java
+++ /dev/null
@@ -1,1619 +0,0 @@
-package net.onrc.onos.ofcontroller.core.internal;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.codehaus.jackson.annotate.JsonIgnore;
-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.Property;
-import com.tinkerpop.frames.annotations.gremlin.GremlinParam;
-
-import net.onrc.onos.graph.GraphDBConnection;
-import net.onrc.onos.graph.GraphDBOperation;
-import net.onrc.onos.graph.IDBConnection;
-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.IIpv4Address;
-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;
-
-/**
- * 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 final 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<IPortObject> reverseLinkedPorts;
-		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>();
-			reverseLinkedPorts = 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 Iterable<IPortObject> getReverseLinkedPorts() { return reverseLinkedPorts; }
-
-		@Override
-		public void removeLink(IPortObject dest_port) { linkedPortsToRemove.add(dest_port); }
-
-		@Override
-		public void setLinkPort(IPortObject dest_port) { linkedPortsToAdd.add(dest_port); }
-
-		@Override
-		@JsonIgnore
-		@Property("port_id")
-		public void setPortId(String id) {
-			// TODO Auto-generated method stub
-			
-		}
-
-		@Override
-		@JsonIgnore
-		@Property("port_id")
-		public String getPortId() {
-			// TODO Auto-generated method stub
-			return null;
-		}
-	}
-		
-	/*
-	 * Note by Jono, 11/4/2013
-	 * I changed the interface of IDeviceObject but I didn't spend the
-	 * time to update this class, because I can't see where this is used.
-	 * I think this whole file is a candidate for deletion if it is not
-	 * used anywhere - the graphDB objects are tested elsewhere by the
-	 * tests in net.onrc.onos.ofcontroller.core.*
-	 */
-	public static class TestDeviceObject implements IDeviceObject {
-		@SuppressWarnings("unused")
-		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; }
-
-		@Override
-		public Iterable<IIpv4Address> getIpv4Addresses() {
-			// TODO Auto-generated method stub
-			return null;
-		}
-
-		@Override
-		public IIpv4Address getIpv4Address(int ipv4Address) {
-			// TODO Auto-generated method stub
-			return null;
-		}
-
-		@Override
-		public void addIpv4Address(IIpv4Address ipv4Address) {
-			// TODO Auto-generated method stub
-			
-		}
-
-		@Override
-		public void removeIpv4Address(IIpv4Address ipv4Address) {
-			// TODO Auto-generated method stub
-			
-		}
-	}
-	
-	public static class TestFlowPath implements IFlowPath {
-		private String state,type,flowId,installerId,srcSw,dstSw;
-		private String flowPathType;
-		private String flowPathUserState;
-		private Long flowPathFlags;
-		private Integer idleTimeout;
-		private Integer hardTimeout;
-		private String dataPathSummary;
-		private Short srcPort,dstPort;
-		private String matchSrcMac,matchDstMac;
-		private Short matchEthernetFrameType;
-		private Short matchVlanId;
-		private Byte matchVlanPriority;
-		private String matchSrcIpaddr,matchDstIpaddr;
-		private Byte matchIpProto, matchIpToS;
-		private Short matchSrcTcpUdpPort, matchDstTcpUdpPort;
-		private String actions;
-		
-		private List<IFlowEntry> entries;
-		private List<ISwitchObject> switches;
-
-		private String stateToUpdate,typeToUpdate,flowIdToUpdate,installerIdToUpdate,srcSwToUpdate,dstSwToUpdate;
-		private String flowPathTypeToUpdate;
-		private String flowPathUserStateToUpdate;
-		private Long flowPathFlagsToUpdate;
-		private Integer idleTimeoutToUpdate;
-		private Integer hardTimeoutToUpdate;
-		private String dataPathSummaryToUpdate;
-		private Short srcPortToUpdate,dstPortToUpdate;
-		private String matchSrcMacToUpdate,matchDstMacToUpdate;
-		private Short matchEthernetFrameTypeToUpdate;
-		private Short matchVlanIdToUpdate;
-		private Byte matchVlanPriorityToUpdate;
-		private String matchSrcIpaddrToUpdate,matchDstIpaddrToUpdate;
-		private Byte matchIpProtoToUpdate, matchIpToSToUpdate;
-		private Short matchSrcTcpUdpPortToUpdate, matchDstTcpUdpPortToUpdate;
-		private String actionsToUpdate;
-
-		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(flowPathTypeToUpdate != null) { flowPathType = flowPathTypeToUpdate; }
-			if(flowPathUserStateToUpdate != null) { flowPathUserState = flowPathUserStateToUpdate; }
-			if(flowPathFlagsToUpdate != null) { flowPathFlags = flowPathFlagsToUpdate; }
-			if(idleTimeoutToUpdate != null) { idleTimeout = idleTimeoutToUpdate; }
-			if(hardTimeoutToUpdate != null) { hardTimeout = hardTimeoutToUpdate; }
-			if(srcSwToUpdate != null) { srcSw = srcSwToUpdate; }
-			if(dstSwToUpdate != null) { dstSw = dstSwToUpdate; }
-			if(dataPathSummaryToUpdate != null) { dataPathSummary = dataPathSummaryToUpdate; }
-			if(srcPortToUpdate != null) { srcPort = srcPortToUpdate; }
-			if(dstPortToUpdate != null) { dstPort = dstPortToUpdate; }
-			if(matchSrcMacToUpdate != null) { matchSrcMac = matchSrcMacToUpdate; }
-			if(matchDstMacToUpdate != null) { matchDstMac = matchDstMacToUpdate; }
-			if(matchEthernetFrameTypeToUpdate != null) { matchEthernetFrameType = matchEthernetFrameTypeToUpdate; }
-			if(matchVlanIdToUpdate != null) { matchVlanId = matchVlanIdToUpdate; }
-			if(matchVlanPriorityToUpdate != null) { matchVlanPriority = matchVlanPriorityToUpdate; }
-			if(matchSrcIpaddrToUpdate != null) { matchSrcIpaddr = matchSrcIpaddrToUpdate; }
-			if(matchDstIpaddrToUpdate != null) { matchDstIpaddr = matchDstIpaddrToUpdate; }
-			if(matchIpProtoToUpdate != null) { matchIpProto = matchIpProtoToUpdate; }
-			if(matchIpToSToUpdate != null) { matchIpToS = matchIpToSToUpdate; }
-			if(matchSrcTcpUdpPortToUpdate != null) { matchSrcTcpUdpPort = matchSrcTcpUdpPortToUpdate; }
-			if(matchDstTcpUdpPortToUpdate != null) { matchDstTcpUdpPort = matchDstTcpUdpPortToUpdate; }
-			if(actionsToUpdate != null) { actions = actionsToUpdate; }
-		}
-		
-		public void rollback() {
-			clear();
-		}
-		
-		public void clear() {
-			flowsToAdd.clear();
-			flowsToRemove.clear();
-			
-			stateToUpdate = typeToUpdate = flowIdToUpdate = installerIdToUpdate = null;
-			flowPathTypeToUpdate = null;
-			flowPathUserStateToUpdate = null;
-			flowPathFlagsToUpdate = null;
-			idleTimeoutToUpdate = null;
-			hardTimeoutToUpdate = null;
-			srcSwToUpdate = dstSwToUpdate = dataPathSummaryToUpdate = null;
-			srcPortToUpdate = dstPortToUpdate = null;
-			matchSrcMacToUpdate = matchDstMacToUpdate = null;
-			matchEthernetFrameTypeToUpdate = null;
-			matchVlanIdToUpdate = null;
-			matchVlanPriorityToUpdate = null;
-			matchSrcIpaddrToUpdate = matchDstIpaddrToUpdate = null;
-			matchIpProtoToUpdate = matchIpToSToUpdate = null;
-			matchSrcTcpUdpPortToUpdate = matchDstTcpUdpPortToUpdate = null;
-			actionsToUpdate = 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 setFlowPathTypeForTest(String flowPathType) { this.flowPathType = flowPathType; }
-		public void setFlowPathUserStateForTest(String flowPathUserState) { this.flowPathUserState = flowPathUserState; }
-		public void setFlowPathFlagsForTest(Long flowPathFlags) { this.flowPathFlags = flowPathFlags; }
-		public void setIdleTimeoutForTest(Integer idleTimeout) { this.idleTimeout = idleTimeout; }
-		public void setHardTimeoutForTest(Integer hardTimeout) { this.hardTimeout = hardTimeout; }
-		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 setSrcPortForTest(Short srcPort) { this.srcPort = srcPort; }
-		public void setDstPortForTest(Short dstPort) { this.dstPort = dstPort; }
-		public void setMatchSrcMacForTest(String matchSrcMac) { this.matchSrcMac = matchSrcMac; }
-		public void setMatchDstMacForTest(String matchDstMac) { this.matchDstMac = matchDstMac; }
-		public void setMatchEthernetFrameTypeForTest(Short matchEthernetFrameType) { this.matchEthernetFrameType = matchEthernetFrameType; }
-		public void setMatchVlanIdForTest(Short matchVlanId) { this.matchVlanId = matchVlanId; }
-		public void setMatchVlanPriorityForTest(Byte matchVlanPriority) { this.matchVlanPriority = matchVlanPriority; }
-		public void setMatchSrcIpaddrForTest(String matchSrcIpaddr) { this.matchSrcIpaddr = matchSrcIpaddr; }
-		public void setMatchDstIpaddrForTest(String matchDstIpaddr) { this.matchDstIpaddr = matchDstIpaddr; }
-		public void setMatchIpProtoForTest(Byte matchIpProto) { this.matchIpProto = matchIpProto; }
-		public void setMatchIpToSForTest(Byte matchIpToS) { this.matchIpToS = matchIpToS; }
-		public void setMatchSrcTcpUdpPortForTest(Short matchSrcTcpUdpPort) { this.matchSrcTcpUdpPort = matchSrcTcpUdpPort; }
-		public void setMatchDstTcpUdpPortForTest(Short matchDstTcpUdpPort) { this.matchDstTcpUdpPort = matchDstTcpUdpPort; }
-		public void setActionsForTest(String actions) { this.actions = actions; }
-		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 getFlowPathType() { return flowPathType; }
-
-		@Override
-		public void setFlowPathType(String flowPathType) { flowPathTypeToUpdate = flowPathType; }
-
-		@Override
-		public String getFlowPathUserState() { return flowPathUserState; }
-
-		@Override
-		public void setFlowPathUserState(String flowPathUserState) { flowPathUserStateToUpdate = flowPathUserState; }
-
-		@Override
-		public Long getFlowPathFlags() { return flowPathFlags; }
-
-		@Override
-		public void setFlowPathFlags(Long flowPathFlags) { flowPathFlagsToUpdate = flowPathFlags; }
-
-		@Override
-		public Integer getIdleTimeout() { return idleTimeout; }
-
-		@Override
-		public void setIdleTimeout(Integer idleTimeout) { idleTimeoutToUpdate = idleTimeout; }
-
-		@Override
-		public Integer getHardTimeout() { return hardTimeout; }
-
-		@Override
-		public void setHardTimeout(Integer hardTimeout) { hardTimeoutToUpdate = hardTimeout; }
-
-		@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 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 Short getMatchEthernetFrameType() { return matchEthernetFrameType; }
-
-		@Override
-		public void setMatchEthernetFrameType(Short matchEthernetFrameType) {
-			matchEthernetFrameTypeToUpdate = matchEthernetFrameType; }
-
-		@Override
-		public Short getMatchVlanId() { return matchVlanId; }
-
-		@Override
-		public void setMatchVlanId(Short matchVlanId) {
-			matchVlanIdToUpdate = matchVlanId; }
-
-		@Override
-		public Byte getMatchVlanPriority() { return matchVlanPriority; }
-
-		@Override
-		public void setMatchVlanPriority(Byte matchVlanPriority) {
-			matchVlanPriorityToUpdate = matchVlanPriority; }
-
-		@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 Byte getMatchIpProto() { return matchIpProto; }
-
-		@Override
-		public void setMatchIpProto(Byte matchIpProto) {
-			matchIpProtoToUpdate = matchIpProto; }
-
-		@Override
-		public Byte getMatchIpToS() { return matchIpToS; }
-
-		@Override
-		public void setMatchIpToS(Byte matchIpToS) {
-			matchIpToSToUpdate = matchIpToS; }
-
-		@Override
-		public Short getMatchSrcTcpUdpPort() { return matchSrcTcpUdpPort; }
-
-		@Override
-		public void setMatchSrcTcpUdpPort(Short matchSrcTcpUdpPort) {
-			matchSrcTcpUdpPortToUpdate = matchSrcTcpUdpPort; }
-
-		@Override
-		public Short getMatchDstTcpUdpPort() { return matchDstTcpUdpPort; }
-
-		@Override
-		public void setMatchDstTcpUdpPort(Short matchDstTcpUdpPort) {
-			matchDstTcpUdpPortToUpdate = matchDstTcpUdpPort; }
-
-		@Override
-		public String getActions() { return actions; }
-
-		@Override
-		public void setActions(String actions) {
-			actionsToUpdate = actions; }
-
-		@Override
-		public Iterable<ISwitchObject> getSwitches() { return switches; }
-	}
-
-	public static class TestFlowEntry implements IFlowEntry {
-		private String state,type,entryId,dpid,userState,switchState,errorStateType,errorStateCode;
-		private Integer idleTimeout;
-		private Integer hardTimeout;
-		private Short matchInPort;
-		private String matchSrcMac,matchDstMac;
-		private Short matchEtherFrameType;
-		private Short matchVlanId;
-		private Byte matchVlanPriority;
-		private String matchSrcIpaddr,matchDstIpaddr;
-		private Byte matchIpProto, matchIpToS;
-		private Short matchSrcTcpUdpPort, matchDstTcpUdpPort;
-		private Short actionOutputPort;
-		private String actions;
-		
-		private IFlowPath flowPath;
-		private ISwitchObject sw;
-		private IPortObject inport,outport;
-	
-		private String stateToUpdate,typeToUpdate,entryIdToUpdate,dpidToUpdate,
-			userStateToUpdate,switchStateToUpdate,errorStateTypeToUpdate,errorStateCodeToUpdate;
-		private Integer idleTimeoutToUpdate;
-		private Integer hardTimeoutToUpdate;
-		private Short matchInPortToUpdate;
-		private String matchSrcMacToUpdate,matchDstMacToUpdate;
-		private Short matchEtherFrameTypeToUpdate;
-		private Short matchVlanIdToUpdate;
-		private Byte matchVlanPriorityToUpdate;
-		private String matchSrcIpaddrToUpdate,matchDstIpaddrToUpdate;
-		private Byte matchIpProtoToUpdate, matchIpToSToUpdate;
-		private Short matchSrcTcpUdpPortToUpdate, matchDstTcpUdpPortToUpdate;
-		private Short actionOutputPortToUpdate;
-		private String actionsToUpdate;
-	
-		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(idleTimeoutToUpdate != null) { idleTimeout = idleTimeoutToUpdate; }
-			if(hardTimeoutToUpdate != null) { hardTimeout = hardTimeoutToUpdate; }
-			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(matchInPortToUpdate != null) { matchInPort = matchInPortToUpdate; }
-			if(matchSrcMacToUpdate != null) { matchSrcMac = matchSrcMacToUpdate; }
-			if(matchDstMacToUpdate != null) { matchDstMac = matchDstMacToUpdate; }
-			if(matchEtherFrameTypeToUpdate != null) { matchEtherFrameType = matchEtherFrameTypeToUpdate; }
-			if(matchVlanIdToUpdate != null) { matchVlanId = matchVlanIdToUpdate; }
-			if(matchVlanPriorityToUpdate != null) { matchVlanPriority = matchVlanPriorityToUpdate; }
-			if(matchSrcIpaddrToUpdate != null) { matchSrcIpaddr = matchSrcIpaddrToUpdate; }
-			if(matchDstIpaddrToUpdate != null) { matchDstIpaddr = matchDstIpaddrToUpdate; }
-			if(matchIpProtoToUpdate != null) { matchIpProto = matchIpProtoToUpdate; }
-			if(matchIpToSToUpdate != null) { matchIpToS = matchIpToSToUpdate; }
-			if(matchSrcTcpUdpPortToUpdate != null) { matchSrcTcpUdpPort = matchSrcTcpUdpPortToUpdate; }
-			if(matchDstTcpUdpPortToUpdate != null) { matchDstTcpUdpPort = matchDstTcpUdpPortToUpdate; }
-			if(actionOutputPortToUpdate != null) { actionOutputPort = actionOutputPortToUpdate; }
-			if(actionsToUpdate != null) { actions = actionsToUpdate; }
-			
-			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;
-			idleTimeoutToUpdate = hardTimeoutToUpdate = null;
-			userStateToUpdate = switchStateToUpdate = errorStateTypeToUpdate = errorStateCodeToUpdate = null;
-			matchInPortToUpdate = null;
-			matchSrcMacToUpdate = matchDstMacToUpdate = null;
-			matchEtherFrameTypeToUpdate = null;
-			matchVlanIdToUpdate = null;
-			matchVlanPriorityToUpdate = null;
-			matchSrcIpaddrToUpdate = matchDstIpaddrToUpdate = null;
-			matchIpProtoToUpdate = matchIpToSToUpdate = null;
-			matchSrcTcpUdpPortToUpdate = matchDstTcpUdpPortToUpdate = null;
-			actionOutputPortToUpdate = null;
-			actionsToUpdate = 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 setIdleTimeoutForTest(Integer idleTimeout) { this.idleTimeout = idleTimeout; }
-		public void setHardTimeoutForTest(Integer hardTimeout) { this.hardTimeout = hardTimeout; }
-		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 setMatchInPortForTest(Short matchInPort) { this.matchInPort = matchInPort; }
-		public void setMatchSrcMacForTest(String matchSrcMac) { this.matchSrcMac = matchSrcMac; }
-		public void setMatchDstMacForTest(String matchDstMac) { this.matchDstMac = matchDstMac; }
-		public void setMatchEtherFrameTypeForTest(Short matchEtherFrameType) { this.matchEtherFrameType = matchEtherFrameType; }
-		public void setMatchVlanIdForTest(Short matchVlanId) { this.matchVlanId = matchVlanId; }
-		public void setMatchVlanPriorityForTest(Byte matchVlanPriority) { this.matchVlanPriority = matchVlanPriority; }
-		public void setMatchSrcIpaddrForTest(String matchSrcIpaddr) { this.matchSrcIpaddr = matchSrcIpaddr; }
-		public void setMatchDstIpaddrForTest(String matchDstIpaddr) { this.matchDstIpaddr = matchDstIpaddr; }
-		public void setMatchIpProtoForTest(Byte matchIpProto) { this.matchIpProto = matchIpProto; }
-		public void setMatchIpToSForTest(Byte matchIpToS) { this.matchIpToS = matchIpToS; }
-		public void setMatchSrcTcpUdpPortForTest(Short matchSrcTcpUdpPort) { this.matchSrcTcpUdpPort = matchSrcTcpUdpPort; }
-		public void setMatchDstTcpUdpPortForTest(Short matchDstTcpUdpPort) { this.matchDstTcpUdpPort = matchDstTcpUdpPort; }
-		public void setActionOutputPortForTest(Short actionOutputPort) { this.actionOutputPort = actionOutputPort; }
-		public void setActionsForTest(String actions) { this.actions = actions; }
-		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 Integer getIdleTimeout() { return idleTimeout; }
-	
-		@Override
-		public void setIdleTimeout(Integer idleTimeout) { idleTimeoutToUpdate = idleTimeout; }
-
-		@Override
-		public Integer getHardTimeout() { return hardTimeout; }
-	
-		@Override
-		public void setHardTimeout(Integer hardTimeout) { hardTimeoutToUpdate = hardTimeout; }
-	
-		@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 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 Short getMatchEthernetFrameType() {return matchEtherFrameType; }
-	
-		@Override
-		public void setMatchEthernetFrameType(Short matchEthernetFrameType) { matchEtherFrameTypeToUpdate = matchEthernetFrameType; }
-
-		@Override
-		public Short getMatchVlanId() {return matchVlanId; }
-	
-		@Override
-		public void setMatchVlanId(Short matchVlanId) { matchVlanIdToUpdate = matchVlanId; }
-
-		@Override
-		public Byte getMatchVlanPriority() {return matchVlanPriority; }
-	
-		@Override
-		public void setMatchVlanPriority(Byte matchVlanPriority) { matchVlanPriorityToUpdate = matchVlanPriority; }
-		
-		@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 Byte getMatchIpProto() {return matchIpProto; }
-	
-		@Override
-		public void setMatchIpProto(Byte matchIpProto) { matchIpProtoToUpdate = matchIpProto; }
-
-		@Override
-		public Byte getMatchIpToS() {return matchIpToS; }
-	
-		@Override
-		public void setMatchIpToS(Byte matchIpToS) { matchIpToSToUpdate = matchIpToS; }
-
-		@Override
-		public Short getMatchSrcTcpUdpPort() {return matchSrcTcpUdpPort; }
-	
-		@Override
-		public void setMatchSrcTcpUdpPort(Short matchSrcTcpUdpPort) { matchSrcTcpUdpPortToUpdate = matchSrcTcpUdpPort; }
-
-		@Override
-		public Short getMatchDstTcpUdpPort() {return matchDstTcpUdpPort; }
-	
-		@Override
-		public void setMatchDstTcpUdpPort(Short matchDstTcpUdpPort) { matchDstTcpUdpPortToUpdate = matchDstTcpUdpPort; }
-	
-		@Override
-		public Short getActionOutputPort() { return actionOutputPort; }
-	
-		@Override
-		public void setActionOutputPort(Short actionOutputPort) { actionOutputPortToUpdate = actionOutputPort; }
-
-		@Override
-		public String getActions() { return actions; }
-	
-		@Override
-		public void setActions(String actions) { actionsToUpdate = actions; }
-	
-		@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
-
-	}
-}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/devicemanager/internal/DeviceStorageImplTest.java b/src/test/java/net/onrc/onos/ofcontroller/devicemanager/internal/DeviceStorageImplTest.java
deleted file mode 100644
index d017546..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/devicemanager/internal/DeviceStorageImplTest.java
+++ /dev/null
@@ -1,522 +0,0 @@
-package net.onrc.onos.ofcontroller.devicemanager.internal;
-
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import net.floodlightcontroller.devicemanager.IDevice;
-import net.floodlightcontroller.devicemanager.SwitchPort;
-import net.onrc.onos.graph.GraphDBConnection;
-import net.onrc.onos.graph.GraphDBOperation;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IIpv4Address;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
-import net.onrc.onos.ofcontroller.core.internal.DeviceStorageImpl;
-import net.onrc.onos.ofcontroller.core.internal.SwitchStorageImpl;
-
-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.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;
-
-import com.google.common.net.InetAddresses;
-import com.thinkaurelius.titan.core.TitanFactory;
-
-//Add Powermock preparation
-@Ignore //TODO broken 11/19/13, should fix
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({TitanFactory.class, GraphDBConnection.class, GraphDBOperation.class, DeviceStorageImpl.class})
-public class DeviceStorageImplTest{
-	
-	protected final static Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
-	
-	String conf;
-        String dbStore;
-	DeviceStorageImpl deviceImpl;
-    private GraphDBConnection mockConn;
-    private GraphDBOperation mockOpe;
-    
-	@Before
-	public void setUp() throws Exception {
-	    deviceImpl = new DeviceStorageImpl();	
-		conf = "/dummy/path/to/db";
-                dbStore = "dummyStore";
-				
-		PowerMock.mockStatic(GraphDBConnection.class);
-		mockConn = createMock(GraphDBConnection.class);
-		PowerMock.suppress(PowerMock.constructor(GraphDBConnection.class));
-		EasyMock.expect(GraphDBConnection.getInstance((String)EasyMock.anyObject())).andReturn(mockConn);
-		PowerMock.replay(GraphDBConnection.class);
-			
-		//PowerMock.mockStatic(GraphDBOperation.class);
-		mockOpe = PowerMock.createMock(GraphDBOperation.class);
-		PowerMock.expectNew(GraphDBOperation.class, new Class<?>[]{String.class}, conf).andReturn(mockOpe);
-		//mockOpe.close();
-		PowerMock.replay(GraphDBOperation.class);
-        // Replace the conf to dummy conf
-		// String conf = "/tmp/cassandra.titan";
-
-		deviceImpl.init(dbStore, conf);
-
-	}
-
-	@After
-	public void tearDown() throws Exception {	
-		verify(mockOpe);
-	}
-	
-	private IPortObject getMockPort(long dpid, short port) {
-		IPortObject mockPortObject = createMock(IPortObject.class);
-		expect(mockPortObject.getNumber()).andReturn(port).anyTimes();
-		expect(mockPortObject.getDesc()).andReturn("test port").anyTimes();
-		return mockPortObject;
-	}
-	
-	private IDevice getMockDevice(String strMacAddress, long attachmentDpid, 
-			short attachmentPort, int ipv4Address) {
-		IDevice mockIDevice = createMock(IDevice.class);
-		
-		
-		long longMacAddress = HexString.toLong(strMacAddress);
-		
-		SwitchPort[] attachmentSwitchPorts = {new SwitchPort(attachmentDpid, attachmentPort)};
-		
-		expect(mockIDevice.getMACAddress()).andReturn(longMacAddress).anyTimes();
-		expect(mockIDevice.getMACAddressString()).andReturn(strMacAddress).anyTimes();
-		expect(mockIDevice.getAttachmentPoints()).andReturn(attachmentSwitchPorts).anyTimes();
-		expect(mockIDevice.getIPv4Addresses()).andReturn(new Integer[] {ipv4Address}).anyTimes();
-		
-		replay(mockIDevice);
-		
-		return mockIDevice;
-	}
-	
-	/**
-	 * Description:
-	 *  Test method for addDevice method.
-	 * Condition:
-	 *  The device does not already exist in the database
-	 * Expect:
-	 * 	Get proper IDeviceObject
-	 */
-	@Test
-	public void testAddNewDevice() {
-		String strMacAddress = "99:99:99:99:99:99";
-		long attachmentDpid = HexString.toLong("00:00:00:00:00:00:0a:01");
-		short attachmentPort = 2;
-		int intIpv4Address = InetAddresses.coerceToInteger(InetAddresses.forString("192.168.100.1"));
-		
-		IDevice device = getMockDevice(strMacAddress, attachmentDpid, attachmentPort, intIpv4Address);
-		
-		IDeviceObject mockDeviceObject = createMock(IDeviceObject.class);
-		IPortObject mockPortObject = getMockPort(attachmentDpid, attachmentPort); 
-		IIpv4Address mockIpv4Address = createMock(IIpv4Address.class);
-		
-		expect(mockOpe.searchDevice(strMacAddress)).andReturn(null);
-		expect(mockOpe.newDevice()).andReturn(mockDeviceObject);
-		expect(mockDeviceObject.getAttachedPorts()).andReturn(Collections.<IPortObject>emptyList());
-		expect(mockOpe.searchPort(HexString.toHexString(attachmentDpid), attachmentPort)).andReturn(mockPortObject);
-		mockPortObject.setDevice(mockDeviceObject);
-		expect(mockDeviceObject.getIpv4Address(intIpv4Address)).andReturn(null);
-		expect(mockOpe.ensureIpv4Address(intIpv4Address)).andReturn(mockIpv4Address);
-		mockDeviceObject.addIpv4Address(mockIpv4Address);
-		expect(mockDeviceObject.getIpv4Addresses()).andReturn(Collections.singleton(mockIpv4Address));
-		expect(mockIpv4Address.getIpv4Address()).andReturn(intIpv4Address);
-		
-		mockDeviceObject.setMACAddress(strMacAddress);
-		mockDeviceObject.setType("device");
-		mockDeviceObject.setState("ACTIVE");
-		mockOpe.commit();
-		
-		replay(mockDeviceObject);
-		replay(mockPortObject);
-		replay(mockIpv4Address);
-		replay(mockOpe);
-		
-		IDeviceObject addedObject = deviceImpl.addDevice(device);
-		assertNotNull(addedObject);
-		
-		verify(mockDeviceObject);
-	}
-	
-	/**
-	 * Description:
-	 * 	Test method for addDevice method.
-	 * Condition:
-	 *  The device already exists in the database.
-	 * Expect:
-	 * 	Get proper IDeviceObject still.
-	 *  Check the IDeviceObject properties set expectedly. 
-	 */
-	@Test
-	public void testAddExistingDevice() {
-		String strMacAddress = "99:99:99:99:99:99";
-		long attachmentDpid = HexString.toLong("00:00:00:00:00:00:0a:01");
-		short attachmentPort = 2;
-		int intIpv4Address = InetAddresses.coerceToInteger(InetAddresses.forString("192.168.100.1"));
-		
-		IDevice device = getMockDevice(strMacAddress, attachmentDpid, attachmentPort, intIpv4Address);
-		
-		IDeviceObject mockDeviceObject = createMock(IDeviceObject.class);
-		IPortObject mockPortObject = getMockPort(attachmentDpid, attachmentPort); 
-		IIpv4Address mockIpv4Address = createMock(IIpv4Address.class);
-		
-		expect(mockOpe.searchDevice(strMacAddress)).andReturn(mockDeviceObject);
-		expect(mockDeviceObject.getAttachedPorts()).andReturn(Collections.singleton(mockPortObject));
-		expect(mockOpe.searchPort(HexString.toHexString(attachmentDpid), attachmentPort)).andReturn(mockPortObject);
-		expect(mockDeviceObject.getIpv4Address(intIpv4Address)).andReturn(mockIpv4Address);
-		expect(mockDeviceObject.getIpv4Addresses()).andReturn(Collections.singleton(mockIpv4Address));
-		expect(mockIpv4Address.getIpv4Address()).andReturn(intIpv4Address);
-		
-		mockDeviceObject.setMACAddress(strMacAddress);
-		mockDeviceObject.setType("device");
-		mockDeviceObject.setState("ACTIVE");
-		mockOpe.commit();
-		
-		replay(mockDeviceObject);
-		replay(mockPortObject);
-		replay(mockIpv4Address);
-		replay(mockOpe);
-		
-		IDeviceObject addedObject = deviceImpl.addDevice(device);
-		assertNotNull(addedObject);
-		
-		verify(mockDeviceObject);
-	}
-	
-	/**
-	 * Description:
-	 * 	Test method for updateDevice method.
-	 *  NB. this is the same test as testAddExistingDevice
-	 * Condition:
-	 * 	The MAC address and attachment point are the same. 
-	 *  All of the other parameter are different.
-	 * Expect:
-	 * 	Changed parameters are set expectedly.
-	 */
-	@Test
-	public void testAddUpdateDevice() {
-		String strMacAddress = "99:99:99:99:99:99";
-		long attachmentDpid = HexString.toLong("00:00:00:00:00:00:0a:01");
-		short attachmentPort = 2;
-		int intIpv4Address = InetAddresses.coerceToInteger(InetAddresses.forString("192.168.100.1"));
-		
-		IDevice device = getMockDevice(strMacAddress, attachmentDpid, attachmentPort, intIpv4Address);
-		
-		IDeviceObject mockDeviceObject = createMock(IDeviceObject.class);
-		IPortObject mockPortObject = getMockPort(attachmentDpid, attachmentPort); 
-		IIpv4Address mockIpv4Address = createMock(IIpv4Address.class);
-		
-		expect(mockOpe.searchDevice(strMacAddress)).andReturn(mockDeviceObject);
-		expect(mockDeviceObject.getAttachedPorts()).andReturn(Collections.singleton(mockPortObject));
-		expect(mockOpe.searchPort(HexString.toHexString(attachmentDpid), attachmentPort)).andReturn(mockPortObject);
-		expect(mockDeviceObject.getIpv4Address(intIpv4Address)).andReturn(mockIpv4Address);
-		expect(mockDeviceObject.getIpv4Addresses()).andReturn(Collections.singleton(mockIpv4Address));
-		expect(mockIpv4Address.getIpv4Address()).andReturn(intIpv4Address);
-		
-		mockDeviceObject.setMACAddress(strMacAddress);
-		mockDeviceObject.setType("device");
-		mockDeviceObject.setState("ACTIVE");
-		mockOpe.commit();
-		
-		replay(mockDeviceObject);
-		replay(mockPortObject);
-		replay(mockIpv4Address);
-		replay(mockOpe);
-		
-		IDeviceObject addedObject = deviceImpl.updateDevice(device);
-		assertNotNull(addedObject);
-		
-		verify(mockDeviceObject);
-
-	}
-
-	/**
-	 * Description:
-	 * 	Test method for testRemoveDevice method.
-	 * Condition:
-	 * 	1. Unregistered IDeviceObject argument is put. 
-	 * Expect:
-	 *  1. Nothing happen when unregistered IDeviceObject is put
-	 * 	2. IDeviceObject will be removed.
-	 */
-	@Test
-	public void testRemoveDevice() {
-		String strMacAddress = "99:99:99:99:99:99";
-		long attachmentDpid = HexString.toLong("00:00:00:00:00:00:0a:01");
-		short attachmentPort = 2;
-		int intIpv4Address = InetAddresses.coerceToInteger(InetAddresses.forString("192.168.100.1"));
-		
-		IIpv4Address ipv4AddressObject = createMock(IIpv4Address.class);
-		IDeviceObject deviceObject = createMock(IDeviceObject.class);
-		expect(deviceObject.getIpv4Addresses()).andReturn(Collections.singleton(ipv4AddressObject));
-		expect(deviceObject.getMACAddress()).andReturn(strMacAddress);
-		replay(deviceObject);
-		
-		expect(mockOpe.searchDevice(strMacAddress)).andReturn(deviceObject);
-		mockOpe.removeIpv4Address(ipv4AddressObject);
-		mockOpe.removeDevice(deviceObject);
-		mockOpe.commit();
-		replay(mockOpe);
-		
-		IDevice device = getMockDevice(strMacAddress, attachmentDpid, attachmentPort, intIpv4Address);
-
-		deviceImpl.removeDevice(device);
-		
-		verify(mockOpe);
-	}
-
-	/**
-	 * Description:
-	 * 	Test method for getDeviceByMac
-	 * Condition:
-	 * 	1. Unregistered MAC address argument is set
-	 * Expect:
-	 * 	1.Nothing happen when you put unregistered MAC address
-	 *  2.Get the proper IDeviceObject.
-	 *  3.Check the IDeviceObject properties set expectedly.
-	 */
-	@Test
-	public void testGetDeviceByMac() {
-		String mac = "99:99:99:99:99:99";
-		
-		IDeviceObject mockDevice = createMock(IDeviceObject.class);
-		
-		expect(mockOpe.searchDevice(mac)).andReturn(mockDevice);
-		
-		replay(mockOpe);
-		
-		IDeviceObject result = deviceImpl.getDeviceByMac(mac);
-		assertNotNull(result);
-		
-		verify(mockOpe);
-	}
-	
-	/**
-	 * Description:
-	 * 	Test method for getDeviceByIP method.
-	 * Condition:
-	 * 	1. Unregistered IP address argument is set
-	 * Expect:
-	 * 	1. Nothing happen when you put unregistered IP address
-	 * 	2. Get the proper IDeviceObject.
-	 *  3. Check the IDeviceObject properties set expectedly.
-	 */
-	@Test
-	public void testGetDeviceByIP() {
-		int nonExistingIp = InetAddresses.coerceToInteger(InetAddresses.forString("192.168.10.50"));
-		int existingIp = InetAddresses.coerceToInteger(InetAddresses.forString("10.5.12.128"));
-		
-		IDeviceObject mockDevice = createMock(IDeviceObject.class);
-		IIpv4Address mockExistingIp = createMock(IIpv4Address.class);
-		expect(mockExistingIp.getDevice()).andReturn(mockDevice);
-		
-		expect(mockOpe.searchIpv4Address(nonExistingIp)).andReturn(null);
-		expect(mockOpe.searchIpv4Address(existingIp)).andReturn(mockExistingIp);
-		
-		replay(mockExistingIp);
-		replay(mockOpe);
-		
-		IDeviceObject result = deviceImpl.getDeviceByIP(nonExistingIp);
-		assertNull(result);
-		
-		result = deviceImpl.getDeviceByIP(existingIp);
-		assertNotNull(result);
-		
-		verify(mockOpe);
-	}
-
-	/**
-	 * Description:
-	 * 	Test method for testChangeDeviceAttachmentsIDevice
-	 * Condition:
-	 * 	1. The device is not currently attached to any point.
-	 * Expect:
-	 * 	1. Nothing happen when you put nonexistent attachment point.
-	 * 	2. Set the attachment point expectedly;
-	 */
-	@Test
-	public void testChangeDeviceAttachementsWhenUnattached() {
-		String strMacAddress = "99:99:99:99:99:99";
-		long attachmentDpid = HexString.toLong("00:00:00:00:00:00:0a:01");
-		short attachmentPort = 2;
-		int intIpv4Address = InetAddresses.coerceToInteger(InetAddresses.forString("192.168.100.1"));
-		
-		IDevice device = getMockDevice(strMacAddress, attachmentDpid, attachmentPort, intIpv4Address);
-		
-		IDeviceObject mockDeviceObject = createMock(IDeviceObject.class);
-		IPortObject mockPortObject = getMockPort(attachmentDpid, attachmentPort); 
-		
-		expect(mockOpe.searchDevice(strMacAddress)).andReturn(mockDeviceObject);
-		expect(mockDeviceObject.getAttachedPorts()).andReturn(Collections.<IPortObject>emptyList());
-		expect(mockOpe.searchPort(HexString.toHexString(attachmentDpid), attachmentPort)).andReturn(mockPortObject);
-		mockPortObject.setDevice(mockDeviceObject);
-		mockOpe.commit();
-		
-		replay(mockDeviceObject);
-		replay(mockPortObject);
-		replay(mockOpe);
-		
-		deviceImpl.changeDeviceAttachments(device);
-		
-		verify(mockDeviceObject);
-		verify(mockPortObject);
-		verify(mockOpe);
-	}
-	
-	/**
-	 * Description:
-	 * 	Test method for testChangeDeviceAttachmentsIDevice
-	 * Condition:
-	 * 	1. The device is currently attached to a switch, but this attachment point
-	 *     has now changed.
-	 * Expect:
-	 * 	1. The device should be removed from the old attachment point.
-	 * 	2. Set the attachment point expectedly;
-	 */
-	@Test
-	public void testChangeDeviceAttachementsWhenAttached() {
-		String strMacAddress = "99:99:99:99:99:99";
-		long attachmentDpid = HexString.toLong("00:00:00:00:00:00:0a:01");
-		short attachmentPort = 2;
-		int intIpv4Address = InetAddresses.coerceToInteger(InetAddresses.forString("192.168.100.1"));
-		
-		//Details for the port the device will be moved from
-		long alreadyAttachedDpid = HexString.toLong("00:00:00:00:00:00:0b:01");
-		short alreadyAttachedPort = 5;
-		
-		IDevice device = getMockDevice(strMacAddress, attachmentDpid, attachmentPort, intIpv4Address);
-		
-		IDeviceObject mockDeviceObject = createMock(IDeviceObject.class);
-		IPortObject mockPortObject = getMockPort(attachmentDpid, attachmentPort);
-		IPortObject alreadyAttachedPortObject = getMockPort(alreadyAttachedDpid, alreadyAttachedPort);
-		
-		expect(mockOpe.searchDevice(strMacAddress)).andReturn(mockDeviceObject);
-		expect(mockDeviceObject.getAttachedPorts()).andReturn(Collections.singletonList(alreadyAttachedPortObject));
-		expect(mockOpe.searchPort(HexString.toHexString(attachmentDpid), attachmentPort)).andReturn(mockPortObject);
-		mockPortObject.setDevice(mockDeviceObject);
-		alreadyAttachedPortObject.removeDevice(mockDeviceObject);
-		mockOpe.commit();
-		
-		replay(mockDeviceObject);
-		replay(alreadyAttachedPortObject);
-		replay(mockPortObject);
-		replay(mockOpe);
-		
-		deviceImpl.changeDeviceAttachments(device);
-		
-		verify(mockDeviceObject);
-		verify(alreadyAttachedPortObject);
-		verify(mockPortObject);
-		verify(mockOpe);
-	}
-
-	@Ignore
-	@Test
-	public void testChangeDeviceAttachmentsIDeviceIDeviceObject() {
-		//It is tested by the testChangeDeviceAttachmentsIDevice
-	}
-
-	/**
-	 * Description:
-	 * 	Test method for testChangeDeviceIPv4Address
-	 * Condition:
-	 * 	N/A
-	 * Expect:
-	 *  1. Set the IP address expectedly.
-	 */
-	@Test
-	public void testChangeDeviceIpv4Address() {
-		String strMacAddress = "99:99:99:99:99:99";
-		long attachmentDpid = HexString.toLong("00:00:00:00:00:00:0a:01");
-		short attachmentPort = 2;
-		int intIpv4Address = InetAddresses.coerceToInteger(InetAddresses.forString("192.168.100.1"));
-		
-		IDevice device = getMockDevice(strMacAddress, attachmentDpid, attachmentPort, intIpv4Address);
-		
-		IDeviceObject mockDeviceObject = createMock(IDeviceObject.class);
-		IIpv4Address mockIpv4Address = createMock(IIpv4Address.class);
-		
-		expect(mockOpe.searchDevice(strMacAddress)).andReturn(mockDeviceObject);
-		expect(mockDeviceObject.getIpv4Address(intIpv4Address)).andReturn(null);
-		expect(mockOpe.ensureIpv4Address(intIpv4Address)).andReturn(mockIpv4Address);
-		mockDeviceObject.addIpv4Address(mockIpv4Address);
-		expect(mockDeviceObject.getIpv4Addresses()).andReturn(Collections.singletonList(mockIpv4Address));
-		expect(mockIpv4Address.getIpv4Address()).andReturn(intIpv4Address);
-		mockOpe.commit();
-		
-		replay(mockDeviceObject);
-		replay(mockIpv4Address);
-		replay(mockOpe);
-		
-		deviceImpl.changeDeviceIPv4Address(device);
-		
-		verify(mockDeviceObject);
-		verify(mockIpv4Address);
-		verify(mockOpe);
-	}
-	
-	/**
-	 * Description:
-	 * 	Test method for testChangeDeviceIPv4Address
-	 * Condition:
-	 * 	1. The device had an old IP address which has now changed.
-	 * Expect:
-	 *  1. The old IP address should be removed from the device.
-	 *  2. Set the IP address expectedly.
-	 */
-	@Test
-	public void testChangeDeviceIpv4AddressAndRemoveExisting() {
-		String strMacAddress = "99:99:99:99:99:99";
-		long attachmentDpid = HexString.toLong("00:00:00:00:00:00:0a:01");
-		short attachmentPort = 2;
-		int intIpv4Address = InetAddresses.coerceToInteger(InetAddresses.forString("192.168.100.1"));
-		
-		IDevice device = getMockDevice(strMacAddress, attachmentDpid, attachmentPort, intIpv4Address);
-		
-		IDeviceObject mockDeviceObject = createMock(IDeviceObject.class);
-		
-		IIpv4Address mockIpv4Address = createMock(IIpv4Address.class);
-		IIpv4Address mockDeletingIpv4Address = createMock(IIpv4Address.class);
-		List<IIpv4Address> ipv4Vertices = new ArrayList<IIpv4Address>(2);
-		ipv4Vertices.add(mockIpv4Address);
-		ipv4Vertices.add(mockDeletingIpv4Address);
-		
-		expect(mockOpe.searchDevice(strMacAddress)).andReturn(mockDeviceObject);
-		expect(mockDeviceObject.getIpv4Address(intIpv4Address)).andReturn(null);
-		expect(mockOpe.ensureIpv4Address(intIpv4Address)).andReturn(mockIpv4Address);
-		expect(mockIpv4Address.getDevice()).andReturn(null);
-		mockDeviceObject.addIpv4Address(mockIpv4Address);
-		expect(mockDeviceObject.getIpv4Addresses()).andReturn(ipv4Vertices);
-		expect(mockIpv4Address.getIpv4Address()).andReturn(intIpv4Address);
-		expect(mockDeletingIpv4Address.getIpv4Address()).andReturn(1);
-		mockDeviceObject.removeIpv4Address(mockDeletingIpv4Address);
-		mockOpe.commit();
-		
-		replay(mockDeviceObject);
-		replay(mockIpv4Address);
-		replay(mockOpe);
-		
-		deviceImpl.changeDeviceIPv4Address(device);
-		
-		verify(mockDeviceObject);
-		verify(mockIpv4Address);
-		verify(mockOpe);
-	}
-
-}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/devicemanager/internal/DeviceStorageImplTestBB.java b/src/test/java/net/onrc/onos/ofcontroller/devicemanager/internal/DeviceStorageImplTestBB.java
deleted file mode 100644
index c80b52a..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/devicemanager/internal/DeviceStorageImplTestBB.java
+++ /dev/null
@@ -1,674 +0,0 @@
-package net.onrc.onos.ofcontroller.devicemanager.internal;
-
-import static org.junit.Assert.*;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.Arrays;
-import java.util.List;
-
-import net.floodlightcontroller.core.internal.TestDatabaseManager;
-import net.floodlightcontroller.devicemanager.IDevice;
-import net.floodlightcontroller.devicemanager.SwitchPort;
-import net.floodlightcontroller.devicemanager.internal.Device;
-import net.floodlightcontroller.packet.IPv4;
-import net.onrc.onos.graph.GraphDBConnection;
-import net.onrc.onos.graph.GraphDBOperation;
-import net.onrc.onos.ofcontroller.core.IDeviceStorage;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
-import net.onrc.onos.ofcontroller.core.internal.DeviceStorageImpl;
-import net.onrc.onos.ofcontroller.core.internal.SwitchStorageImpl;
-
-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.util.HexString;
-import org.powermock.api.easymock.PowerMock;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.slf4j.LoggerFactory;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-import com.thinkaurelius.titan.core.TitanFactory;
-import com.thinkaurelius.titan.core.TitanGraph;
-
-/*
- * Jono, 11/4/2013
- * These tests are being ignored because they don't work because they
- * rely on test functionality that was written ages ago and hasn't been
- * updated as the database schema has evolved. 
- * These tests work by getting an in-memory Titan database and testing
- * the DeviceStorageImpl on top of that. In this regard they're not really
- * unit tests as they test the entire DB stack (i.e. GraphDBOperation and
- * GraphDBConnection), not just DeviceStorageImpl.
- * I've left them here as we may wish to resurrect this kind of 
- * integration testing of the DB layers in the future.
- */
-@Ignore
-//Add Powermock preparation
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({TitanFactory.class, GraphDBConnection.class, GraphDBOperation.class, SwitchStorageImpl.class})
-public class DeviceStorageImplTestBB {
-	protected static org.slf4j.Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
-
-	String conf;
-        String dbStore;
-    private GraphDBConnection conn = null;
-    private GraphDBOperation ope = null;
-    private TitanGraph titanGraph = null;
-    IDeviceStorage deviceImpl = null;
-    
-	@Before
-	public void setUp() throws Exception {
-		
-		deviceImpl = new DeviceStorageImpl();
-		conf = "/dummy/path/to/db";
-                dbStore = "dummyStore";
-		
-		// Make mock cassandra DB
-		// Replace TitanFactory.open() to return mock DB
-		titanGraph = TestDatabaseManager.getTestDatabase();
-		TestDatabaseManager.populateTestData(titanGraph);
-		PowerMock.mockStatic(TitanFactory.class);
-		EasyMock.expect(TitanFactory.open((String)EasyMock.anyObject())).andReturn(titanGraph);
-		PowerMock.replay(TitanFactory.class);
-		
-		conn = GraphDBConnection.getInstance(conf);
-		ope = new GraphDBOperation(conn);
-		
-		deviceImpl.init(dbStore, conf);
-	}
-
-	@After
-	public void tearDown() throws Exception {
-		titanGraph.shutdown();
-		TestDatabaseManager.deleteTestDatabase();
-
-		deviceImpl.close();
-		deviceImpl = null;
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for addDevice method.
-	 * Codition:
-	 *  N/A
-	 * Expect:
-	 * 	Get proper IDeviceObject
-	 *  Check the IDeviceObject properties set
-	 */
-	@Test
-	public void testAddDevice() {
-		try 
-		{	   
-			//Make mockDevice
-			IDevice mockDev = EasyMock.createMock(Device.class);
-			// Mac addr for test device.
-			String macAddr = "99:99:99:99:99:99";
-			// IP addr for test device
-			String ip = "192.168.100.1";
-			Integer ipInt = IPv4.toIPv4Address(ip);
-			Integer[] ipaddrs = {ipInt};
-			// Mac addr for attached switch
-			String switchMacAddr = "00:00:00:00:00:00:0a:01";		
-			long switchMacAddrL = HexString.toLong(switchMacAddr);
-			// Port number for attached switch
-			short portNum = 2; 
-			SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
-			SwitchPort[] sps = {sp1};
-
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
-			EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-
-			EasyMock.replay(mockDev);
-
-			//Add the device
-	        IDeviceObject obj = deviceImpl.addDevice(mockDev);	
-			assertNotNull(obj);
-
-			//Test to take a Device from DB correctly
-			IDeviceObject devObj1 = ope.searchDevice(macAddr);
-			assertEquals(macAddr, devObj1.getMACAddress());
-
-			//Test to take a attached sw  from DB correctly
-			for(ISwitchObject sw1: devObj1.getSwitch())
-			{
-				String swMacFromDB = sw1.getDPID();
-				assertEquals(switchMacAddr, swMacFromDB);
-			}
-
-			//Test to take a IP addr from DB
-			//TodoForGettingIPaddr. There may be bug in the test class.
-			
-			//XXX not updated to new interface
-			//String ipFromDB = devObj1.getIPAddress();
-			String ipFromDB = "foo";
-			
-			String[] ipsFromDB = ipFromDB.replace("[", "").replace("]", "").split(",");
-			List<String> ipsList = Arrays.asList(ipsFromDB);
-			assertTrue(ipsList.contains(ip));
-
-			//Test to take a attached port from DB
-			for(IPortObject port : devObj1.getAttachedPorts())
-			{
-
-				//In this implementing, the object was not set the port. So it must be null.
-				if(port.getNumber() != null)
-				{
-					String portNumFromDB = port.getNumber().toString();
-					assertEquals(String.valueOf(portNum), portNumFromDB);				
-				}
-			}	
-		} catch(Exception e) {
-			fail(e.getMessage());
-		}
-	}
-	
-	/**
-	 * Desc:
-	 * 	Test method for addDevice method.
-	 * Condition:
-	 * 	Already added device is existed.
-	 * Expect:
-	 * 	Get proper IDeviceObject still.
-	 *  Check the IDeviceObject properties set.
-	 */
-	@Test
-	public void testAddDeviceExisting() {
-		try 
-		{	   
-			IDevice mockDev = EasyMock.createMock(Device.class);
-			String macAddr = "99:99:99:99:99:99";
-			String ip = "192.168.100.1";
-			Integer ipInt = IPv4.toIPv4Address(ip);
-			Integer[] ipaddrs = {ipInt};
-			String switchMacAddr = "00:00:00:00:00:00:0a:01";		
-			long switchMacAddrL = HexString.toLong(switchMacAddr);
-			short portNum = 2; 
-			SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
-			SwitchPort[] sps = {sp1};
-
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
-			EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
-			EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.replay(mockDev);
-
-			//Add the device
-	        IDeviceObject obj = deviceImpl.addDevice(mockDev);	
-			assertNotNull(obj);
-
-			//Test to take a Device from DB correctly
-			IDeviceObject devObj1 = ope.searchDevice(macAddr);
-			assertEquals(macAddr, devObj1.getMACAddress());
-
-			//Add the same device
-	        IDeviceObject obj2 = deviceImpl.addDevice(mockDev);	
-			assertNotNull(obj2);
-
-			IDeviceObject devObj2 = ope.searchDevice(macAddr);
-			assertEquals(macAddr, devObj2.getMACAddress());	
-
-			//Test to take a attached port from DB
-			for(IPortObject port : devObj2.getAttachedPorts())
-			{
-				//In this implementing, the object was not set the port. So it must be null.
-				if(port.getNumber() != null)
-				{
-
-					String portNumFromDB = port.getNumber().toString();
-					assertEquals(String.valueOf(portNum), portNumFromDB);
-
-				}
-			}	
-
-			//XXX not updated to new interface
-			//String ipFromDB = devObj2.getIPAddress();
-			String ipFromDB = "foo";
-			
-			String[] ipsFromDB = ipFromDB.replace("[", "").replace("]", "").split(",");
-			List<String> ipsList = Arrays.asList(ipsFromDB);
-			assertTrue(ipsList.contains(ip));
-
-			//Test to take a attached port from DB
-			for(IPortObject port : devObj2.getAttachedPorts())
-			{
-
-				//In this implementing, the object was not set the port. So it must be null.
-				if(port.getNumber() != null)
-				{
-					String portNumFromDB = port.getNumber().toString();
-					assertEquals(String.valueOf(portNum), portNumFromDB);				
-				}
-			}	
-		} catch(Exception e) {
-			fail(e.getMessage());
-		}
-	}
-	/**
-	 * Desc:
-	 * 	Test method for updateDevice method.
-	 * Condition:
-	 * 	The mac address and attachment point are the same. 
-	 *  All of the other parameter are different.
-	 * Expect:
-	 * 	Changed parameters are set properly.
-	 */
-	//@Ignore
-	@Test
-	public void testUpdateDevice() {
-		try
-		{
-			IDevice mockDev = EasyMock.createMock(Device.class);
-			String macAddr = "99:99:99:99:99:99";
-			String ip = "192.168.100.1";
-			Integer ipInt = IPv4.toIPv4Address(ip);
-			Integer[] ipaddrs = {ipInt};
-			String switchMacAddr = "00:00:00:00:00:00:0a:01";		
-			long switchMacAddrL = HexString.toLong(switchMacAddr);
-			short portNum = 2; 
-			SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
-			SwitchPort[] sps = {sp1};
-
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
-			EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.replay(mockDev);
-
-			//Dev2 (attached port is the same)
-			IDevice mockDev2 = EasyMock.createMock(Device.class);
-			String macAddr2 = "99:aa:aa:aa:aa:aa";
-			Integer ip2 = IPv4.toIPv4Address("192.168.100.2");
-			Integer[] ipaddrs2 = {ip2};
-
-			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr2);
-			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr2);
-			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr2);
-			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr2);
-			EasyMock.expect(mockDev2.getIPv4Addresses()).andReturn(ipaddrs2);
-			EasyMock.expect(mockDev2.getAttachmentPoints()).andReturn(sps);
-			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr2);
-			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr2);
-			EasyMock.replay(mockDev2);
-
-	        IDeviceObject obj = deviceImpl.addDevice(mockDev);	
-			assertNotNull(obj);
-
-			IDeviceObject dev1 = ope.searchDevice(macAddr);
-			assertEquals(macAddr, dev1.getMACAddress());
-
-			//update theDevice
-			deviceImpl.updateDevice(mockDev2);
-			IDeviceObject dev2 = ope.searchDevice(macAddr2);
-			assertEquals(macAddr2, dev2.getMACAddress());
-			IPortObject iport = ope.searchPort(switchMacAddr, portNum);
-
-			//Test to take a attached port from DB
-			for(IDeviceObject dev : iport.getDevices())
-			{
-				String macAddrFromDB = dev.getMACAddress();	
-				if(macAddr2.equals(macAddrFromDB)){
-					//Nothing to do
-				}
-				else{
-					fail("notFoundTheDeviceOnThePort");			
-				}
-			}
-
-		} catch(Exception e) {
-			fail(e.getMessage());
-		}
-	}
-
-	/**
-	 * Desc:
-	 * 	Test method for testRemoveDevice method.
-	 * Condition:
-	 * 	1. Unregistered IDeviceObject argument is put. 
-	 * Expect:
-	 *  1. Nothing happen when unregistered IDeviceObject is put
-	 * 	2. IDeviceObject will be removed.
-	 */
-	//@Ignore
-	@Test
-	public void testRemoveDevice() {
-		try
-		{
-			IDevice mockDev = EasyMock.createMock(Device.class);
-			String macAddr = "99:99:99:99:99:99";
-			String ip = "192.168.100.1";
-			Integer ipInt = IPv4.toIPv4Address(ip);
-			Integer[] ipaddrs = {ipInt};
-			String switchMacAddr = "00:00:00:00:00:00:0a:01";		
-			long switchMacAddrL = HexString.toLong(switchMacAddr);
-			short portNum = 2; 
-			SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
-			SwitchPort[] sps = {sp1};
-
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.replay(mockDev);
-
-	        IDeviceObject obj = deviceImpl.addDevice(mockDev);	
-			assertNotNull(obj);
-
-			IDeviceObject dev1 = ope.searchDevice(macAddr);
-			assertEquals(macAddr, dev1.getMACAddress());
-
-			deviceImpl.removeDevice(mockDev);		
-		    IDeviceObject dev = deviceImpl.getDeviceByMac(macAddr);
-		    assertNull(dev);
-
-		} catch(Exception e) {
-			fail(e.getMessage());
-		}
-	}
-
-	/**
-	 * Desc:
-	 * 	Test method for getDeviceByMac
-	 * Condition:
-	 * 	1. Unregistered mac address argument is set
-	 * Expect:
-	 * 	1.Nothing happen when you put unregistered mac address
-	 *  2.Get the proper IDeviceObject.
-	 *  3.Check the IDeviceObject properties set.
-	 */
-	//@Ignore
-	@Test
-	public void testGetDeviceByMac() {
-		try
-		{
-			IDevice mockDev = EasyMock.createMock(Device.class);
-			String macAddr = "99:99:99:99:99:99";
-			String ip = "192.168.100.1";
-			Integer ipInt = IPv4.toIPv4Address(ip);
-			Integer[] ipaddrs = {ipInt};
-			String switchMacAddr = "00:00:00:00:00:00:0a:01";		
-			long switchMacAddrL = HexString.toLong(switchMacAddr);
-			short portNum = 2; 
-			SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
-			SwitchPort[] sps = {sp1};
-
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
-			EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.replay(mockDev);
-
-	        IDeviceObject obj = deviceImpl.addDevice(mockDev);	
-			assertNotNull(obj);
-
-			IDeviceObject dev1 = ope.searchDevice(macAddr);
-			assertEquals(macAddr, dev1.getMACAddress());
-
-		    IDeviceObject dev = deviceImpl.getDeviceByMac(macAddr);
-		    assertNotNull(dev);
-			assertEquals(macAddr, dev.getMACAddress());
-
-		} catch(Exception e) {
-			fail(e.getMessage());
-		}
-	}
-
-	/**
-	 * Desc:
-	 * 	Test method for getDeviceByIP method.
-	 * Condition:
-	 * 	1. Unregistered ip address argument is set
-	 * Expect:
-	 * 	1. Nothing happen when you put unregistered mac address
-	 * 	2. Get the proper IDeviceObject.
-	 *  3. Check the IDeviceObject properties set.
-	 */
-	//@Ignore
-	@Test
-	public void testGetDeviceByIP() {
-		try
-		{
-			IDevice mockDev = EasyMock.createMock(Device.class);
-			String macAddr = "99:99:99:99:99:99";
-			String ip = "192.168.100.1";
-			Integer ipInt = IPv4.toIPv4Address(ip);
-			Integer[] ipaddrs = {ipInt};
-			String switchMacAddr = "00:00:00:00:00:00:0a:01";		
-			long switchMacAddrL = HexString.toLong(switchMacAddr);
-			short portNum = 2; 
-			SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
-			SwitchPort[] sps = {sp1};
-
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
-			EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.replay(mockDev);
-
-	        IDeviceObject obj = deviceImpl.addDevice(mockDev);	
-			assertNotNull(obj);
-
-			IDeviceObject dev1 = ope.searchDevice(macAddr);
-			assertEquals(macAddr, dev1.getMACAddress());
-
-			int ip_int = getPackedIPv4Address(ip);
-			//XXX not updated to new interface
-		    IDeviceObject dev = deviceImpl.getDeviceByIP(ip_int);
-			//IDeviceObject dev = null;
-			
-		    assertNotNull(dev);
-		    
-		    //XXX not updated to new interface
-			//String ipFromDB = dev.getIPAddress();
-		    String ipFromDB = "foo";
-		    
-			String[] ipsFromDB = ipFromDB.replace("[", "").replace("]", "").split(",");
-			List<String> ipsList = Arrays.asList(ipsFromDB);
-			assertTrue(ipsList.contains(ip));
-
-		} catch(Exception e) {
-			fail(e.getMessage());
-		}
-	}
-
-	/**
-	 * Desc:
-	 * 	Test method for testChangeDeviceAttachmentsIDevice
-	 * Condition:
-	 * 	1. Unexisting attachment point argument is set
-	 * Expect:
-	 * 	1. Unexisting attachment point is ignored, so nothing happen.
-	 * 	2. Change the attachment point.
-	 */
-	//@Ignore
-	@Test
-	public void testChangeDeviceAttachmentsIDevice() {
-		try
-		{
-			IDevice mockDev = EasyMock.createMock(Device.class);
-			String macAddr = "99:99:99:99:99:99";
-			String ip = "192.168.100.1";
-			Integer ipInt = IPv4.toIPv4Address(ip);
-			Integer[] ipaddrs = {ipInt};
-			String switchMacAddr = "00:00:00:00:00:00:0a:01";		
-			long switchMacAddrL = HexString.toLong(switchMacAddr);
-			short portNum = 2; 
-			SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
-			SwitchPort[] sps = {sp1};
-
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
-			EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.replay(mockDev);
-
-			//Dev2
-			IDevice mockDev2 = EasyMock.createMock(Device.class);
-			String switchMacAddr2 = "00:00:00:00:00:00:0a:02";
-			long lSwitchMacAddr2 = HexString.toLong(switchMacAddr2);
-			short portNum2 = 2; 
-			SwitchPort sp2 = new SwitchPort(lSwitchMacAddr2, portNum2);
-			SwitchPort sps2[] = {sp2};
-
-			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev2.getIPv4Addresses()).andReturn(ipaddrs);
-			EasyMock.expect(mockDev2.getAttachmentPoints()).andReturn(sps2);
-			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr);
-			EasyMock.replay(mockDev2);
-
-	        IDeviceObject obj = deviceImpl.addDevice(mockDev);	
-			assertNotNull(obj);
-
-		    deviceImpl.changeDeviceAttachments(mockDev2);
-
-		    IDeviceObject dev = deviceImpl.getDeviceByMac(macAddr);
-		    assertNotNull(dev);
-
-			for(ISwitchObject sw1: dev.getSwitch())
-			{
-				String swMacFromDB = sw1.getDPID();
-				assertEquals(switchMacAddr2, swMacFromDB);
-			}
-		} catch(Exception e) {
-			fail(e.getMessage());
-		}
-	}
-
-	//@Ignore
-	@Test
-	public void testChangeDeviceAttachmentsIDeviceIDeviceObject() {
-		//It is tested by the testChangeDeviceAttachmentsIDevice
-	}
-
-	/**
-	 * Desc:
-	 * 	Test method for testChangeDeviceIPv4Address
-	 * Condition:
-	 * 	N/A
-	 * Expect:
-	 *  1. Check correctly changed the ipadress
-	 */
-	//@Ignore
-	@Test
-	public void testChangeDeviceIPv4Address() {
-		try
-		{
-			//Dev1
-			IDevice mockDev = EasyMock.createMock(Device.class);
-			String macAddr = "99:99:99:99:99:99";
-			String ip = "192.168.100.1";
-			Integer ipInt = IPv4.toIPv4Address(ip);
-			Integer[] ipaddrs = {ipInt};
-			String switchMacAddr = "00:00:00:00:00:00:0a:01";		
-			long switchMacAddrL = HexString.toLong(switchMacAddr);
-			short portNum = 2; 
-			SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
-			SwitchPort[] sps = {sp1};
-
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
-			EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.replay(mockDev);
-
-	        IDeviceObject obj = deviceImpl.addDevice(mockDev);	
-			assertNotNull(obj);
-
-			IDevice mockDev2 = EasyMock.createMock(Device.class);
-			String ip2 = "192.168.100.2";
-			Integer ipInt2 = IPv4.toIPv4Address(ip2);
-			Integer[] ipaddrs2 = {ipInt2};
-			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev2.getIPv4Addresses()).andReturn(ipaddrs2);
-			EasyMock.replay(mockDev2);
-
-			IDeviceObject dev1 = ope.searchDevice(macAddr);
-			assertEquals(macAddr, dev1.getMACAddress());
-			
-			//XXX not updated to new interface
-			//String ipFromDB = dev1.getIPAddress();
-			String ipFromDB = "foo";
-			
-			String[] ipsFromDB = ipFromDB.replace("[", "").replace("]", "").split(",");
-			List<String> ipsList = Arrays.asList(ipsFromDB);
-			assertTrue(ipsList.contains(ip));
-
-	        deviceImpl.changeDeviceIPv4Address(mockDev2);	
-
-			IDeviceObject dev2 = ope.searchDevice(macAddr);
-			assertEquals(macAddr, dev2.getMACAddress());
-			
-			//XXX not updated to new interface
-			//String ipFromDB2 = dev2.getIPAddress();
-			String ipFromDB2 = "foo";
-			
-			String[] ipsFromDB2 = ipFromDB2.replace("[", "").replace("]", "").split(",");
-			List<String> ipsList2 = Arrays.asList(ipsFromDB2);
-			assertTrue(ipsList2.contains(ip2));
-		} 
-		catch(Exception e) {
-			fail(e.getMessage());
-		}
-	}
-
-	int getPackedIPv4Address(String ip) throws UnknownHostException {
-		byte[] bytes = InetAddress.getByName(ip).getAddress();
-
-		int val = 0;
-		  for (int i = 0; i < bytes.length; i++) {
-		    val <<= 8;
-		    val |= bytes[i] & 0xff;
-		  }
-		  return val;
-	}
-}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/flowmanager/FlowManagerTest.java b/src/test/java/net/onrc/onos/ofcontroller/flowmanager/FlowManagerTest.java
deleted file mode 100644
index 73577c1..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/flowmanager/FlowManagerTest.java
+++ /dev/null
@@ -1,808 +0,0 @@
-package net.onrc.onos.ofcontroller.flowmanager;
-
-import static org.junit.Assert.*;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.cmpEq;
-import static org.powermock.api.easymock.PowerMock.*;
-
-import java.lang.reflect.Method;
-import java.util.*;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.module.IFloodlightService;
-import net.floodlightcontroller.restserver.IRestApiService;
-import net.onrc.onos.datagrid.IDatagridService;
-import net.onrc.onos.graph.GraphDBOperation;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
-import net.onrc.onos.ofcontroller.flowmanager.web.FlowWebRoutable;
-import net.onrc.onos.ofcontroller.topology.ITopologyNetService;
-import net.onrc.onos.ofcontroller.topology.TopologyManager;
-import net.onrc.onos.ofcontroller.util.*;
-
-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.OFFlowMod;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.factory.BasicFactory;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-/**
- * @author Toshio Koide
- */
-@Ignore
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({FlowManager.class, FlowDatabaseOperation.class, GraphDBOperation.class, System.class, Executors.class})
-public class FlowManagerTest {
-	private static FloodlightModuleContext context;
-	private static IFloodlightProviderService floodlightProvider;
-	private static TopologyManager topologyManager;
-	private static IDatagridService datagridService;
-	private static IRestApiService restApi;
-	private static GraphDBOperation op;
-	
-	/**
-	 * @throws java.lang.Exception
-	 */
-	@Before
-	public void setUp() throws Exception {
-	}
-
-	/**
-	 * @throws java.lang.Exception
-	 */
-	@After
-	public void tearDown() throws Exception {
-	}
-	
-	/**
-	 * @throws java.lang.Exception
-	 */
-	private void expectInitWithContext() throws Exception {
-		// create mock objects
-		context = createMock(FloodlightModuleContext.class);
-		floodlightProvider = createMock(IFloodlightProviderService.class);
-		topologyManager = createMock(TopologyManager.class);
-		datagridService = createMock(IDatagridService.class);
-		restApi = createMock(IRestApiService.class);
-		op = createMock(GraphDBOperation.class);
-
-		// setup expectations
-		expect(context.getServiceImpl(IFloodlightProviderService.class)).andReturn(floodlightProvider);
-		expect(context.getServiceImpl(ITopologyNetService.class)).andReturn(topologyManager);
-		expect(context.getServiceImpl(IDatagridService.class)).andReturn(datagridService);
-		expect(context.getServiceImpl(IRestApiService.class)).andReturn(restApi);
-		expectNew(GraphDBOperation.class, new Class<?>[] {String.class}, EasyMock.isA(String.class)).andReturn(op);
-		expectNew(TopologyManager.class, new Class<?>[] {String.class}, EasyMock.isA(String.class)).andReturn(topologyManager);
-	}
-	
-	private IFlowPath createIFlowPathMock(long flowId, String installerID,
-			String flowPathType, String flowPathUserState,
-			long flowPathFlags, long srcDpid, int srcPort,
-			long dstDpid, int dstPort) {
-		IFlowPath iFlowPath = createNiceMock(IFlowPath.class);
-		expect(iFlowPath.getFlowId()).andReturn(new FlowId(flowId).toString()).anyTimes();
-		expect(iFlowPath.getInstallerId()).andReturn(installerID).anyTimes();
-		expect(iFlowPath.getFlowPathType()).andReturn(flowPathType).anyTimes();
-		expect(iFlowPath.getFlowPathUserState()).andReturn(flowPathUserState).anyTimes();
-		expect(iFlowPath.getFlowPathFlags()).andReturn(new Long(flowPathFlags)).anyTimes();
-		expect(iFlowPath.getSrcSwitch()).andReturn(new Dpid(srcDpid).toString()).anyTimes();
-		expect(iFlowPath.getSrcPort()).andReturn(new Short((short)srcPort)).anyTimes();
-		expect(iFlowPath.getDstSwitch()).andReturn(new Dpid(dstDpid).toString()).anyTimes();
-		expect(iFlowPath.getDstPort()).andReturn(new Short((short)dstPort)).anyTimes();
-		return iFlowPath;
-	}
-	
-	private FlowPath createTestFlowPath(long flowId, String installerId,
-			String flowPathType, String flowPathUserState,
-			final long flowPathFlags,
-			final long srcDpid, final int srcPort,
-			final long dstDpid, final int dstPort
-			) {
-		FlowPath flowPath = new FlowPath();
-		flowPath.setFlowId(new FlowId(flowId));
-		flowPath.setInstallerId(new CallerId(installerId));
-		flowPath.setFlowPathType(FlowPathType.valueOf(flowPathType));
-		flowPath.setFlowPathUserState(FlowPathUserState.valueOf(flowPathUserState));
-		flowPath.setFlowPathFlags(new FlowPathFlags(flowPathFlags));
-		flowPath.setDataPath(new DataPath() {{
-			setSrcPort(new SwitchPort(new Dpid(srcDpid), new Port((short)srcPort)));
-			setDstPort(new SwitchPort(new Dpid(dstDpid), new Port((short)dstPort)));
-		}});
-		flowPath.setFlowEntryMatch(new FlowEntryMatch());
-		return flowPath;
-	}
-	
-	/*
-	private ArrayList<FlowPath> createTestFlowPaths() {
-		FlowPath flowPath1 = createTestFlowPath(1, "foo caller id", "FP_TYPE_SHORTEST_PATH", "FP_USER_ADD", 0, 1, 1, 2, 2); 
-		FlowPath flowPath2 = createTestFlowPath(2, "caller id", "FP_TYPE_SHORTEST_PATH", "FP_USER_ADD", 0, 1, 1, 2, 2); 
-		FlowPath flowPath3 = createTestFlowPath(3, "caller id", "FP_TYPE_SHORTEST_PATH", "FP_USER_ADD", 0, 1, 5, 2, 2); 
-
-		ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
-		flowPaths.add(flowPath1);
-		flowPaths.add(flowPath2);
-		flowPaths.add(flowPath3);
-		
-		return flowPaths;
-	}
-	*/
-	
-
-	// IFlowService methods
-
-
-	/**
-	 * Test method for {@link FlowManager#addFlow(FlowPath)}.
-	 * @throws Exception 
-	 */
-	@Test
-	public final void testAddFlowFailGraphCreatesNoFlow() throws Exception {
-		// instantiate required objects
-		FlowId flowId = new FlowId(123);
-		FlowPath flowPath = new FlowPath();
-		flowPath.setFlowId(flowId);
-		FlowManager fm = new FlowManager();
-		
-		// setup expectations
-		expectInitWithContext();
-		expect(op.searchFlowPath(flowId)).andReturn(null);
-		expect(op.newFlowPath()).andReturn(null);
-		op.rollback();
-
-		// start the test
-		replayAll();
-
-		fm.init(context);
-		FlowId result = fm.addFlow(flowPath);
-
-		// verify the test
-		verifyAll();
-		assertNotNull(result);
-	}
-
-	/**
-	 * Test method for {@link FlowManager#addFlow(FlowPath)}.
-	 * @throws Exception 
-	 */
-	@Test
-	public final void testAddFlowSuccessNormally() throws Exception {
-		final String addFlowEntry = "addFlowEntry";
-		// create mock objects
-		IFlowPath createdFlowPath = createNiceMock(IFlowPath.class);
-		IFlowEntry createdFlowEntry1 = createNiceMock(IFlowEntry.class);
-		IFlowEntry createdFlowEntry2 = createNiceMock(IFlowEntry.class);
-		FlowManager fm = createPartialMockAndInvokeDefaultConstructor(FlowManager.class, addFlowEntry);
-
-		// instantiate required objects
-		final FlowEntry flowEntry1 = new FlowEntry();
-		final FlowEntry flowEntry2 = new FlowEntry();
-		ArrayList<FlowEntry> flowEntries = new ArrayList<FlowEntry>();
-		flowEntries.add(flowEntry1);
-		flowEntries.add(flowEntry2);
-		
-		DataPath dataPath = new DataPath();
-		dataPath.setSrcPort(new SwitchPort(new Dpid(0x1234), new Port((short)1)));
-		dataPath.setDstPort(new SwitchPort(new Dpid(0x5678), new Port((short)2)));
-		dataPath.setFlowEntries(flowEntries);
-
-		FlowEntryMatch match = new FlowEntryMatch();
-		
-		FlowPath flowPath = new FlowPath();
-		flowPath.setFlowId(new FlowId(0x100));
-		flowPath.setInstallerId(new CallerId("installer id"));
-		flowPath.setFlowPathType(FlowPathType.valueOf("FP_TYPE_SHORTEST_PATH"));
-		flowPath.setFlowPathUserState(FlowPathUserState.valueOf("FP_USER_ADD"));
-		flowPath.setFlowPathFlags(new FlowPathFlags(0));
-		flowPath.setDataPath(dataPath);
-		flowPath.setFlowEntryMatch(match);
-		
-		// setup expectations
-		expectInitWithContext();
-		expect(op.searchFlowPath(cmpEq(new FlowId(0x100)))).andReturn(null);
-		expect(op.newFlowPath()).andReturn(createdFlowPath);
-		createdFlowPath.setFlowId("0x100");
-		createdFlowPath.setType("flow");
-		createdFlowPath.setInstallerId("installer id");
-		createdFlowPath.setFlowPathType("FP_TYPE_SHORTEST_PATH");
-		createdFlowPath.setFlowPathUserState("FP_USER_ADD");
-		createdFlowPath.setFlowPathFlags(new Long((long)0));
-		createdFlowPath.setSrcSwitch("00:00:00:00:00:00:12:34");
-		createdFlowPath.setSrcPort(new Short((short)1));
-		createdFlowPath.setDstSwitch("00:00:00:00:00:00:56:78");
-		createdFlowPath.setDstPort(new Short((short)2));
-		createdFlowPath.setDataPathSummary("data path summary");
-		
-		expectPrivate(fm, addFlowEntry, createdFlowPath, flowEntry1)
-			.andReturn(createdFlowEntry1);
-		expectPrivate(fm, addFlowEntry, createdFlowPath, flowEntry2)
-			.andReturn(createdFlowEntry2);
-		
-		op.commit();
-		
-		// start the test
-		replayAll();
-		
-		fm.init(context);
-		FlowId result = fm.addFlow(flowPath);
-
-		// verify the test
-		verifyAll();
-		assertNotNull(result);
-	}
-
-	/**
-	 * Test method for {@link FlowManager#deleteFlow(FlowId)}.
-	 * @throws Exception
-	 */
-	@Test
-	public final void testDeleteFlowSuccessNormally() throws Exception {
-		// create mock objects
-		IFlowPath flowPath = createIFlowPathMock(123, "id", "FP_TYPE_SHORTEST_PATH", "FP_USER_ADD", 0, 1, 2, 3, 4);
-		IFlowEntry flowEntry1 = createMock(IFlowEntry.class);
-		IFlowEntry flowEntry2 = createMock(IFlowEntry.class);
-		IFlowEntry flowEntry3 = createMock(IFlowEntry.class);
-		
-		// instantiate required objects
-		FlowManager fm = new FlowManager();
-		FlowId flowId = new FlowId(123);
-		ArrayList<IFlowEntry> flowEntries = new ArrayList<IFlowEntry>();
-		flowEntries.add(flowEntry1);
-		flowEntries.add(flowEntry2);
-		flowEntries.add(flowEntry3);
-
-		// setup expectations
-		expectInitWithContext();
-		expect(op.searchFlowPath(cmpEq(flowId))).andReturn(flowPath);
-		expect(flowPath.getFlowEntries()).andReturn(flowEntries);
-		flowPath.removeFlowEntry(flowEntry1);
-		flowPath.removeFlowEntry(flowEntry2);
-		flowPath.removeFlowEntry(flowEntry3);
-		op.removeFlowEntry(flowEntry1);
-		op.removeFlowEntry(flowEntry2);
-		op.removeFlowEntry(flowEntry3);
-		op.removeFlowPath(flowPath);
-		op.commit();
-
-		// start the test
-		replayAll();
-		
-		fm.init(context);
-		fm.deleteFlow(flowId);
-
-		// verify the test
-		verifyAll();
-	}
-	
-	/**
-	 * Test method for {@link FlowManager#deleteFlow(FlowId)}.
-	 * @throws Exception
-	 */
-	@Test
-	public final void testDeleteFlowSuccessEmptyFlowPath() throws Exception {
-		// instantiate required objects
-		FlowManager fm = new FlowManager();
-		
-		// create mock objects
-		IFlowPath flowObj = createNiceMock(IFlowPath.class);
-
-		// setup expectations
-		expectInitWithContext();
-		expect(op.searchFlowPath(cmpEq(new FlowId(1)))).andReturn(flowObj);
-		expect(flowObj.getFlowEntries()).andReturn(new ArrayList<IFlowEntry>());
-		op.removeFlowPath(flowObj);
-		op.commit();
-		expectLastCall().anyTimes();
-		
-		// start the test
-		replayAll();
-		
-		fm.init(context);
-		Boolean result = fm.deleteFlow(new FlowId(1));
-		
-		// verify the test
-		verifyAll();
-		assertTrue(result);
-	}
-	
-	/**
-	 * Test method for {@link FlowManager#deleteAllFlows()}.
-	 * @throws Exception 
-	 */
-	@Test
-	public final void testDeleteAllFlowsSuccessNormally() throws Exception {
-		// create mock objects
-		IFlowPath flowPath1 = createNiceMock(IFlowPath.class);
-		IFlowPath flowPath2 = createNiceMock(IFlowPath.class);
-		IFlowPath flowPath3 = createNiceMock(IFlowPath.class);
-		FlowManager fm = createPartialMockAndInvokeDefaultConstructor(FlowManager.class, "deleteFlow");
-		
-		// instantiate required objects
-		ArrayList<IFlowPath> flowPaths = new ArrayList<IFlowPath>();
-		flowPaths.add(flowPath1);
-		flowPaths.add(flowPath2);
-		flowPaths.add(null);
-		flowPaths.add(flowPath3);
-		
-		// setup expectations
-		expectInitWithContext();
-		expect(op.getAllFlowPaths()).andReturn(flowPaths);
-		expect(flowPath1.getFlowId()).andReturn(new FlowId(1).toString());
-		expect(flowPath2.getFlowId()).andReturn(null);
-		expect(flowPath3.getFlowId()).andReturn(new FlowId(3).toString());
-		expect(fm.deleteFlow(cmpEq(new FlowId(1)))).andReturn(true);
-		expect(fm.deleteFlow(cmpEq(new FlowId(3)))).andReturn(true);
-		
-		// start the test
-		replayAll();
-
-		fm.init(context);
-		Boolean result = fm.deleteAllFlows();
-		
-		// verify the test
-		verifyAll();
-		assertTrue(result);
-	}
-	
-	/**
-	 * Test method for {@link FlowManager#getFlow()}.
-	 * @throws Exception 
-	 */
-	@Test
-	public final void testGetFlowSuccessNormally() throws Exception {
-		// instantiate required objects
-		FlowManager fm = new FlowManager();
-		IFlowPath iFlowPath = createIFlowPathMock(1, "caller id", "FP_TYPE_SHORTEST_PATH", "FP_USER_ADD", 0, 1, 1, 2, 2); 
-
-		// setup expectations
-		expectInitWithContext();
-		expect(op.searchFlowPath(cmpEq(new FlowId(1)))).andReturn(iFlowPath);
-		expect(iFlowPath.getFlowEntries()).andReturn(new ArrayList<IFlowEntry>()).anyTimes();
-		op.commit();
-		
-		// start the test
-		replayAll();
-
-		fm.init(context);
-		FlowPath flowPath = fm.getFlow(new FlowId(1));
-		String installerId = flowPath.installerId().toString();
-		String flowPathType = flowPath.flowPathType().toString();
-		String flowPathUserState = flowPath.flowPathUserState().toString();
-		long flowPathFlags = flowPath.flowPathFlags().flags();
-		
-		//verify the test
-		verifyAll();
-		assertEquals("caller id", installerId);
-		assertEquals("FP_TYPE_SHORTEST_PATH", flowPathType);
-		assertEquals("FP_USER_ADD", flowPathUserState);
-		assertEquals(0L, flowPathFlags);
-	}
-	
-	/**
-	 * Test method for {@link FlowManager#getAllFlowsSummary(FlowId, int)}.
-	 * @throws Exception 
-	 */
-	@Test
-	public final void testGetAllFlowsSummarySuccessNormally() throws Exception {
-		final String getAllFlowsWithDataPathSummary = "getAllFlowsWithDataPathSummary";
-		// create mock objects
-		FlowManager fm = createPartialMockAndInvokeDefaultConstructor(FlowManager.class, getAllFlowsWithDataPathSummary);
-		FlowPath flowPath1 = createTestFlowPath(1, "", "FP_TYPE_SHORTEST_PATH", "FP_USER_ADD", 0, 1, 2, 3, 4);
-		FlowPath flowPath2 = createTestFlowPath(5, "", "FP_TYPE_SHORTEST_PATH", "FP_USER_ADD", 0, 2, 3, 4, 5);
-		FlowPath flowPath3 = createTestFlowPath(10, "", "FP_TYPE_SHORTEST_PATH", "FP_USER_ADD", 0, 3, 4, 5, 6);
-
-		// instantiate required objects
-		ArrayList<FlowPath> flows = new ArrayList<FlowPath>();
-		flows.add(flowPath3);
-		flows.add(flowPath1);
-		flows.add(flowPath2);
-		
-		// setup expectations
-		expectInitWithContext();
-		expectPrivate(fm, getAllFlowsWithDataPathSummary).andReturn(flows);
-
-		// start the test
-		replayAll();
-		
-		fm.init(context);
-		ArrayList<FlowPath> returnedFlows = fm.getAllFlowsSummary(null, 0);
-		
-		// verify the test
-		verifyAll();
-		assertEquals(3, returnedFlows.size());
-		assertEquals(1, new FlowId(returnedFlows.get(0).flowId().value()).value());
-		assertEquals(5, new FlowId(returnedFlows.get(1).flowId().value()).value());
-		assertEquals(10, new FlowId(returnedFlows.get(2).flowId().value()).value());
-	}
-
-	/**
-	 * Test method for {@link FlowManager#getAllFlows()}.
-	 * @throws Exception 
-	 */
-	@Test
-	public final void testGetAllFlowsSuccessNormally() throws Exception {
-		// create mock objects
-		IFlowPath iFlowPath1 = createIFlowPathMock(1, "caller id", "FP_TYPE_SHORTEST_PATH", "FP_USER_ADD", 0, 1, 1, 2, 2); 
-		IFlowPath iFlowPath2 = createIFlowPathMock(2, "caller id", "FP_TYPE_SHORTEST_PATH", "FP_USER_ADD", 0, 2, 5, 3, 5);
-		
-		// instantiate required objects
-		ArrayList<IFlowPath> flowPaths = new ArrayList<IFlowPath>();
-		flowPaths.add(iFlowPath1);
-		flowPaths.add(iFlowPath2);
-		FlowManager fm = new FlowManager();
-
-		// setup expectations
-		expectInitWithContext();
-		expect(op.getAllFlowPaths()).andReturn(flowPaths);
-		expect(iFlowPath1.getFlowEntries()).andReturn(new ArrayList<IFlowEntry>()).anyTimes();
-		expect(iFlowPath2.getFlowEntries()).andReturn(new ArrayList<IFlowEntry>()).anyTimes();
-		op.commit();
-		
-		// start the test
-		replayAll();
-		
-		fm.init(context);
-		ArrayList<FlowPath> flows = fm.getAllFlows();
-
-		// verify the test
-		verifyAll();
-		assertEquals(2, flows.size());
-		assertEquals(new SwitchPort(new Dpid(1), new Port((short)1)).toString(),
-				flows.get(0).dataPath().srcPort().toString());
-		assertEquals(new SwitchPort(new Dpid(2), new Port((short)5)).toString(),
-				flows.get(1).dataPath().srcPort().toString());
-		// TODO: more asserts
-		// TODO: ignore seq. of the list
-	}
-		
-	// INetMapStorage methods
-	
-	/**
-	 * Test method for {@link FlowManager#init(String)}.
-	 * @throws Exception 
-	 */
-	@Test
-	public final void testInitSuccessNormally() throws Exception {
-		// instantiate required objects
-		FlowManager fm = new FlowManager();
-
-		// create mock objects
-		op = createMock(GraphDBOperation.class);
-
-		// setup expectations
-		expectNew(GraphDBOperation.class, "/dummy/path").andReturn(op);
-		
-		// start the test
-		replayAll();
-		
-		fm.init("dummy_store", "/dummy/path");
-		
-		// verify the test
-		verifyAll();
-	}
-	
-	/**
-	 * Test method for {@link FlowManager#close()}.
-	 * @throws Exception 
-	 */
-	@Test
-	public final void testCloseSuccessNormally() throws Exception {
-		// instantiate required objects
-		FlowManager fm = new FlowManager();
-
-		// setup expectations
-		expectInitWithContext();
-		op.close();
-		
-		// start the test
-		replayAll();
-		
-		fm.init(context);
-		fm.close();
-		
-		// verify the test
-		verifyAll();
-	}
-	
-	
-	// IFloodlightModule methods
-	
-	
-	/**
-	 * Test method for {@link FlowManager#getModuleServices()}.
-	 * @throws Exception 
-	 */
-	@Test
-	public final void testGetModuleServicesSuccessNormally() throws Exception {
-		// instantiate required objects
-		FlowManager fm = new FlowManager();
-
-		// setup expectations
-		expectInitWithContext();
-
-		// start the test
-		replayAll();
-		
-		fm.init(context);
-		Collection<Class<? extends IFloodlightService>> l = fm.getModuleServices();
-
-		// verify the test
-		verifyAll();
-		assertEquals(1, l.size());
-		assertEquals(IFlowService.class, l.iterator().next());
-	}
-
-	/**
-	 * Test method for {@link FlowManager#getServiceImpls()}.
-	 * @throws Exception 
-	 */
-	@Test
-	public final void testGetServiceImplsSuccessNormally() throws Exception {
-		// instantiate required objects
-		FlowManager fm = new FlowManager();
-
-		// setup expectations
-		expectInitWithContext();
-
-		// start the test
-		replayAll();
-		
-		fm.init(context);
-		Map<Class<? extends IFloodlightService>, IFloodlightService> si = fm.getServiceImpls();
-
-		// verify the test
-		verifyAll();
-		assertEquals(1, si.size());
-		assertTrue(si.containsKey(IFlowService.class));
-		assertEquals(fm, si.get(IFlowService.class));	
-	}
-
-	/**
-	 * Test method for {@link FlowManager#getModuleDependencies()}.
-	 * @throws Exception
-	 */
-	@Test
-	public final void testGetModuleDependenciesSuccessNormally() throws Exception {
-		// instantiate required objects
-		FlowManager fm = new FlowManager();
-
-		// setup expectations
-		expectInitWithContext();
-
-		// start the test
-		replayAll();
-		
-		fm.init(context);
-		Collection<Class<? extends IFloodlightService>> md = fm.getModuleDependencies();
-
-		// verify the test
-		verifyAll();
-		assertEquals(4, md.size());
-		assertTrue(md.contains(IFloodlightProviderService.class));
-		assertTrue(md.contains(IRestApiService.class));
-	}
-
-	/**
-	 * Test method for {@link FlowManager#init(FloodlightModuleContext)}.
-	 * @throws Exception 
-	 */
-	@Test
-	public final void testInitWithFloodlightModuleContextSuccessNormally() throws Exception {
-		// instantiate required objects
-		FlowManager fm = new FlowManager();
-		
-		// setup expectations
-		expectInitWithContext();
-
-		// start the test
-		replayAll();
-		
-		fm.init(context);
-
-		// verify the test
-		verifyAll();
-	}
-
-	/**
-	 * Test method for {@link FlowManager#startUp(FloodlightModuleContext)}.
-	 * @throws Exception
-	 */
-	@Test
-	public final void testStartupSuccessNormally() throws Exception {
-		// create mock objects
-		mockStaticPartial(Executors.class, "newScheduledThreadPool");
-		ScheduledExecutorService scheduler = createMock(ScheduledExecutorService.class);
-
-		// instantiate required objects
-		FlowManager fm = new FlowManager();
-		
-		// setup expectations
-		expectInitWithContext();
-		expect(Executors.newScheduledThreadPool(1)).andReturn(scheduler);
-		expect(Executors.newScheduledThreadPool(1)).andReturn(scheduler);
-		expect(scheduler.scheduleAtFixedRate(
-				EasyMock.anyObject(Runnable.class),
-				EasyMock.anyLong(),
-				EasyMock.anyLong(),
-				EasyMock.anyObject(TimeUnit.class))).andReturn(null).times(2);
-		restApi.addRestletRoutable(EasyMock.anyObject(FlowWebRoutable.class));
-
-		// start the test
-		replayAll();
-		
-		fm.init(context);
-		fm.startUp(context);
-
-		// verify the test
-		verifyAll();
-	}
-	
-	
-	// other methods
-	
-	/**
-	 * Test method for {@link FlowManager#reconcileFlow(IFlowPath, DataPath)}.
-	 * @throws Exception
-	 */
-	@Test
-	public final void testReconcileFlowWithFlowPathAndDataPathSuccessNormally() throws Exception {
-		final String addFlowEntry = "addFlowEntry";
-		
-		// create mock objects
-		IFlowPath iFlowPath1 = createIFlowPathMock(1, "caller id", "FP_TYPE_SHORTEST_PATH", "FP_USER_ADD", 0, 1, 1, 2, 2);
-		IFlowEntry iFlowEntry1 = createMock(IFlowEntry.class);
-		IFlowEntry iFlowEntry2 = createMock(IFlowEntry.class);
-		FlowManager fm = createPartialMockAndInvokeDefaultConstructor(FlowManager.class, addFlowEntry);
-		
-		// instantiate required objects
-		FlowEntry flowEntry1 = new FlowEntry();
-		flowEntry1.setDpid(new Dpid(1));
-		flowEntry1.setFlowId(new FlowId(1));
-		flowEntry1.setInPort(new Port((short) 1));
-		flowEntry1.setOutPort(new Port((short) 11));
-		flowEntry1.setFlowEntryId(new FlowEntryId(1));
-		flowEntry1.setFlowEntryMatch(new FlowEntryMatch());
-		flowEntry1.setFlowEntryActions(new FlowEntryActions());
-		flowEntry1.setFlowEntryErrorState(new FlowEntryErrorState());
-		
-		FlowEntry flowEntry2 = new FlowEntry();
-		flowEntry2.setDpid(new Dpid(2));
-		flowEntry2.setFlowId(new FlowId(2));
-		flowEntry2.setInPort(new Port((short) 22)); 
-		flowEntry2.setOutPort(new Port((short) 2));
-		flowEntry2.setFlowEntryId(new FlowEntryId(2));
-		flowEntry2.setFlowEntryMatch(new FlowEntryMatch());
-		flowEntry2.setFlowEntryActions(new FlowEntryActions());
-		flowEntry2.setFlowEntryErrorState(new FlowEntryErrorState());
-		
-		DataPath dataPath = new DataPath();
-		ArrayList<FlowEntry> flowEntries = new ArrayList<FlowEntry>();
-		flowEntries.add(flowEntry1);
-		flowEntries.add(flowEntry2);
-		dataPath.setFlowEntries(flowEntries);
-		
-		ArrayList<IFlowEntry> oldFlowEntries = new ArrayList<IFlowEntry>();
-		oldFlowEntries.add(iFlowEntry1);
-		oldFlowEntries.add(iFlowEntry2);
-
-		// setup expectations
-		expectInitWithContext();
-		expect(iFlowPath1.getFlowEntries()).andReturn(oldFlowEntries);
-		iFlowEntry1.setUserState("FE_USER_DELETE");
-		iFlowEntry1.setSwitchState("FE_SWITCH_NOT_UPDATED");
-		iFlowEntry2.setUserState("FE_USER_DELETE");
-		iFlowEntry2.setSwitchState("FE_SWITCH_NOT_UPDATED");
-		expectPrivate(fm, addFlowEntry, iFlowPath1, flowEntry1).andReturn(null);
-		expectPrivate(fm, addFlowEntry, iFlowPath1, flowEntry2).andReturn(null);
-
-		// start the test
-		replayAll();
-		
-		fm.init(context);
-		// Use reflection to test the private method
-		// Boolean result = fm.reconcileFlow(iFlowPath1, dataPath);
-		Class<?> fmClass = FlowManager.class;
-		Method method = fmClass.getDeclaredMethod(
-			"reconcileFlow",
-			new Class[] { IFlowPath.class, DataPath.class });
-		method.setAccessible(true);
-		Boolean result = (Boolean)method.invoke(fm,
-			new Object[] { iFlowPath1, dataPath });
-		
-		// verify the test
-		verifyAll();
-		assertTrue(result);
-		// TODO: write more asserts
-	}
-	
-	/**
-	 * Test method for {@link FlowManager#installFlowEntry(net.floodlightcontroller.core.IOFSwitch, IFlowPath, IFlowEntry)}.
-	 * @throws Exception 
-	 */
-	@Test
-	public final void testInstallFlowEntryWithIFlowPathSuccessNormally() throws Exception {
-		// create mock object
-		IOFSwitch iofSwitch = createNiceMock(IOFSwitch.class);
-		IFlowPath iFlowPath = createIFlowPathMock(1, "id", "FP_TYPE_SHORTEST_PATH", "FP_USER_ADD", 0, 1, 2, 3, 4); 
-		IFlowEntry iFlowEntry = createMock(IFlowEntry.class);
-		BasicFactory basicFactory = createMock(BasicFactory.class);
-		
-		// instantiate required objects
-		FlowManager fm = new FlowManager();
-		
-		FlowEntryAction action = new FlowEntryAction();
-		action.setActionOutput(new Port((short)2));
-		FlowEntryActions actions = new FlowEntryActions();
-		actions.addAction(action);
-
-		// setup expectations
-		expectInitWithContext();
-		expect(iFlowEntry.getFlowEntryId()).andReturn(new FlowEntryId(123).toString());
-		expect(iFlowEntry.getUserState()).andReturn("FE_USER_ADD");
-		iFlowEntry.setSwitchState("FE_SWITCH_UPDATED");
-		expect(iFlowEntry.getMatchInPort()).andReturn(new Short((short) 1));
-		expect(iFlowEntry.getMatchSrcMac()).andReturn("01:23:45:67:89:01");
-		expect(iFlowEntry.getMatchDstMac()).andReturn("01:23:45:67:89:02");
-		expect(iFlowEntry.getMatchEthernetFrameType()).andReturn(new Short((short)0x0800));
-		expect(iFlowEntry.getMatchVlanId()).andReturn(new Short((short)0x1234));
-		expect(iFlowEntry.getMatchVlanPriority()).andReturn(new Byte((byte)0x10));
-		expect(iFlowEntry.getMatchSrcIPv4Net()).andReturn("192.168.0.1");
-		expect(iFlowEntry.getMatchDstIPv4Net()).andReturn("192.168.0.2");
-		expect(iFlowEntry.getMatchIpProto()).andReturn(new Byte((byte)0x20));
-		expect(iFlowEntry.getMatchIpToS()).andReturn(new Byte((byte)0x3));
-		expect(iFlowEntry.getMatchSrcTcpUdpPort()).andReturn(new Short((short)40000));
-		expect(iFlowEntry.getMatchDstTcpUdpPort()).andReturn(new Short((short)80));
-		expect(iFlowEntry.getActions()).andReturn(actions.toString());
-		expect(floodlightProvider.getOFMessageFactory()).andReturn(basicFactory);
-		expect(basicFactory.getMessage(OFType.FLOW_MOD)).andReturn(new OFFlowMod());
-		expect(iofSwitch.getStringId()).andReturn(new Dpid(100).toString());
-
-		// start the test
-		replayAll();
-		
-		fm.init(context);
-		// Use reflection to test the private method
-		// Boolean result = fm.installFlowEntry(iofSwitch, iFlowPath, iFlowEntry);
-		Class<?> fmClass = FlowManager.class;
-		Method method = fmClass.getDeclaredMethod(
-			"installFlowEntry",
-			new Class[] { IOFSwitch.class, IFlowPath.class, IFlowEntry.class });
-		method.setAccessible(true);
-		Boolean result = (Boolean)method.invoke(fm,
-			new Object[] { iofSwitch, iFlowPath, iFlowEntry });
-
-		
-		// verify the test
-		verifyAll();
-		assertTrue(result);
-		// TODO: write more asserts
-	}
-
-	/**
-	 * Test method for {@link FlowManager#installFlowEntry(net.floodlightcontroller.core.IOFSwitch, FlowPath, FlowEntry)}.
-	 * The method seems to be not used for now.
-	 */
-	@Ignore @Test
-	public final void testInstallFlowEntryWithFlowPathSuccessNormally() {
-		fail("not yet implemented");
-	}
-
-	/**
-	 * Test method for {@link FlowManager#removeFlowEntry(net.floodlightcontroller.core.IOFSwitch, FlowPath, FlowEntry)}.
-	 * The method seems to be not implemented and not used for now.
-	 */
-	@Ignore @Test
-	public final void testRemoveFlowEntrySuccessNormally() {
-		fail("not yet implemented");
-	}
-}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizerTest.java b/src/test/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizerTest.java
deleted file mode 100644
index 68b4f1f..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizerTest.java
+++ /dev/null
@@ -1,313 +0,0 @@
-package net.onrc.onos.ofcontroller.flowprogrammer;
-
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-
-import net.floodlightcontroller.core.IOFSwitch;
-import net.onrc.onos.graph.GraphDBOperation;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
-import net.onrc.onos.ofcontroller.flowmanager.FlowDatabaseOperation;
-import net.onrc.onos.ofcontroller.flowprogrammer.IFlowSyncService.SyncResult;
-import net.onrc.onos.ofcontroller.util.FlowEntry;
-import net.onrc.onos.ofcontroller.util.FlowEntryId;
-
-import org.easymock.EasyMock;
-import org.easymock.IAnswer;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.openflow.protocol.OFFlowMod;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFStatisticsRequest;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.statistics.OFFlowStatisticsReply;
-import org.openflow.protocol.statistics.OFStatistics;
-import org.powermock.api.easymock.PowerMock;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({FlowSynchronizer.class, GraphDBOperation.class, FlowDatabaseOperation.class})
-public class FlowSynchronizerTest {
-	private FlowPusher pusher;
-	private FlowSynchronizer sync;
-	private List<Long> idAdded;
-	private List<Long> idRemoved;
-
-	@Before
-	public void setUp() throws Exception {
-		idAdded = new ArrayList<Long>();
-		idRemoved = new ArrayList<Long>();
-		
-		pusher = EasyMock.createMock(FlowPusher.class);
-		pusher.add(EasyMock.anyObject(IOFSwitch.class), EasyMock.anyObject(OFMessage.class));
-		EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
-				@Override
-				public Object answer() throws Throwable {
-					OFMessage msg = (OFMessage)EasyMock.getCurrentArguments()[1];
-					if (msg.getType().equals(OFType.FLOW_MOD)) {
-						OFFlowMod fm = (OFFlowMod)msg;
-						if (fm.getCommand() == OFFlowMod.OFPFC_DELETE_STRICT) {
-							idRemoved.add(fm.getCookie());
-						}
-					}
-					return null;
-				}
-			}).anyTimes();
-		pusher.pushFlowEntry(EasyMock.anyObject(IOFSwitch.class), EasyMock.anyObject(FlowEntry.class));
-		EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
-			@Override
-			public Object answer() throws Throwable {
-				FlowEntry flow = (FlowEntry)EasyMock.getCurrentArguments()[1];
-				idAdded.add(flow.flowEntryId().value());
-				return null;
-			}
-		}).anyTimes();
-		EasyMock.replay(pusher);
-	}
-
-	@After
-	public void tearDown() throws Exception {
-	}
-
-	/**
-	 * Test that synchronization doesn't affect anything in case either DB and
-	 * flow table has the same entries.
-	 */
-	@Test
-	public void testStable() {
-		// Create mock of flow table : flow 1
-		IOFSwitch sw = createMockSwitch(new long[] {1});
-		
-		// Create mock of flow entries : flow 1
-		initMockGraph(new long[] {1});
-		
-		// synchronize
-		doSynchronization(sw);
-		
-		// check if flow is not changed
-		assertEquals(0, idAdded.size());
-		assertEquals(0, idRemoved.size());
-	}
-
-	/**
-	 * Test that an flow is added in case DB has an extra FlowEntry.
-	 */
-	@Test
-	public void testSingleAdd() {
-		// Create mock of flow table : null
-		IOFSwitch sw = createMockSwitch(new long[] {});
-		
-		// Create mock of flow entries : flow 1
-		initMockGraph(new long[] {1});
-		
-		// synchronize
-		doSynchronization(sw);
-		
-		// check if single flow is installed
-		assertEquals(1, idAdded.size());
-		assertTrue(idAdded.contains((long)1));
-		assertEquals(0, idRemoved.size());
-	}
-
-	/**
-	 * Test that an flow is deleted in case switch has an extra FlowEntry.
-	 */
-	@Test
-	public void testSingleDelete() {
-		// Create mock of flow table : flow 1
-		IOFSwitch sw = createMockSwitch(new long[] {1});
-		
-		// Create mock of flow entries : null
-		initMockGraph(new long[] {});
-		
-		// synchronize
-		doSynchronization(sw);
-		
-		// check if single flow is deleted
-		assertEquals(0, idAdded.size());
-		assertEquals(1, idRemoved.size());
-		assertTrue(idRemoved.contains((long)1));
-	}
-	
-	/**
-	 * Test that appropriate flows are added and other appropriate flows are deleted
-	 * in case flows in DB are overlapping flows in switch.
-	 */
-	@Test
-	public void testMixed() {
-		// Create mock of flow table : flow 1,2,3
-		IOFSwitch sw = createMockSwitch(new long[] {1,2,3});
-		
-		// Create mock of flow entries : flow 2,3,4,5
-		initMockGraph(new long[] {2,3,4,5});
-		
-		// synchronize
-		doSynchronization(sw);
-		
-		// check if two flows {4,5} is installed and one flow {1} is deleted
-		assertEquals(2, idAdded.size());
-		assertTrue(idAdded.contains((long)4));
-		assertTrue(idAdded.contains((long)5));
-		assertEquals(1, idRemoved.size());
-		assertTrue(idRemoved.contains((long)1));
-	}
-	
-
-	@Test
-	public void testMassive() {
-		// Create mock of flow table : flow 0-1999
-		long [] swIdList = new long [2000];
-		for (long i = 0; i < 2000; ++i) {
-			swIdList[(int)i] = i;
-		}
-		IOFSwitch sw = createMockSwitch(swIdList);
-		
-		// Create mock of flow entries : flow 1500-3499
-		long [] dbIdList = new long [2000];
-		for (long i = 0; i < 2000; ++i) {
-			dbIdList[(int)i] = 1500 + i;
-		}
-		initMockGraph(dbIdList);
-
-		// synchronize
-		doSynchronization(sw);
-		
-		// check if 1500 flows {2000-3499} is installed and 1500 flows {0,...,1499} is deleted
-		assertEquals(1500, idAdded.size());
-		for (long i = 2000; i < 3500; ++i) {
-			assertTrue(idAdded.contains(i));
-		}
-		assertEquals(1500, idRemoved.size());
-		for (long i = 0; i < 1500; ++i) {
-			assertTrue(idRemoved.contains(i));
-		}
-	}
-
-	/**
-	 * Create mock IOFSwitch with flow table which has arbitrary flows.
-	 * @param cookieList List of FlowEntry IDs switch has.
-	 * @return Mock object.
-	 */
-	private IOFSwitch createMockSwitch(long[] cookieList) {
-		IOFSwitch sw = EasyMock.createMock(IOFSwitch.class);
-		EasyMock.expect(sw.getId()).andReturn((long)1).anyTimes();
-		
-		List<OFStatistics> stats = new ArrayList<OFStatistics>();
-		for (long cookie : cookieList) {
-			stats.add(createReply(cookie));
-		}
-		
-		@SuppressWarnings("unchecked")
-		Future<List<OFStatistics>> future = EasyMock.createMock(Future.class);
-		try {
-			EasyMock.expect(future.get()).andReturn(stats).once();
-		} catch (InterruptedException e1) {
-			fail("Failed in Future#get()");
-		} catch (ExecutionException e1) {
-			fail("Failed in Future#get()");
-		}
-		EasyMock.replay(future);
-		
-		try {
-			EasyMock.expect(sw.getStatistics(EasyMock.anyObject(OFStatisticsRequest.class)))
-				.andReturn(future).once();
-		} catch (IOException e) {
-			fail("Failed in IOFSwitch#getStatistics()");
-		}
-		
-		EasyMock.replay(sw);
-		return sw;
-	}
-	
-	/**
-	 * Create single OFFlowStatisticsReply object which is actually obtained from switch.
-	 * @param cookie Cookie value, which indicates ID of FlowEntry installed to switch.
-	 * @return Created object.
-	 */
-	private OFFlowStatisticsReply createReply(long cookie) {
-		OFFlowStatisticsReply stat = new OFFlowStatisticsReply();
-		OFMatch match = new OFMatch();
-		
-		stat.setCookie(cookie);
-		stat.setMatch(match);
-		stat.setPriority((short)1);
-
-		return stat;
-	}
-	
-	/**
-	 * Create mock GraphDBOperation and FlowDatabaseOperation to mock DB.
-	 * @param idList List of FlowEntry IDs stored in DB.
-	 */
-	private void initMockGraph(long[] idList) {
-		List<IFlowEntry> flowEntryList = new ArrayList<IFlowEntry>();
-		
-		for (long id : idList) {
-			IFlowEntry entry = EasyMock.createMock(IFlowEntry.class);
-			EasyMock.expect(entry.getFlowEntryId()).andReturn(String.valueOf(id)).anyTimes();
-			EasyMock.replay(entry);
-			flowEntryList.add(entry);
-		}
-		
-		ISwitchObject swObj = EasyMock.createMock(ISwitchObject.class);
-		EasyMock.expect(swObj.getFlowEntries()).andReturn(flowEntryList).once();
-		EasyMock.replay(swObj);
-		
-		GraphDBOperation mockOp = PowerMock.createMock(GraphDBOperation.class);
-		EasyMock.expect(mockOp.searchSwitch(EasyMock.anyObject(String.class))).andReturn(swObj).once();
-		
-		PowerMock.mockStatic(FlowDatabaseOperation.class);
-		for (IFlowEntry entry : flowEntryList) {
-			EasyMock.expect(FlowDatabaseOperation.extractFlowEntry(EasyMock.eq(entry)))
-				.andAnswer(new IAnswer<FlowEntry>() {
-					@Override
-					public FlowEntry answer() throws Throwable {
-						IFlowEntry iflow = (IFlowEntry)EasyMock.getCurrentArguments()[0];
-						long flowEntryId = Long.valueOf(iflow.getFlowEntryId());
-						
-						FlowEntry flow = EasyMock.createMock(FlowEntry.class);
-						EasyMock.expect(flow.flowEntryId()).andReturn(new FlowEntryId(flowEntryId)).anyTimes();
-						EasyMock.replay(flow);
-						return flow;
-					}
-					
-				}).anyTimes();
-			EasyMock.expect(mockOp.searchFlowEntry(EasyMock.eq(new FlowEntryId(entry.getFlowEntryId()))))
-				.andReturn(entry);
-		}
-		PowerMock.replay(FlowDatabaseOperation.class);
-		EasyMock.replay(mockOp);
-		
-		try {
-			PowerMock.expectNew(GraphDBOperation.class, "").andReturn(mockOp);
-		} catch (Exception e) {
-			fail("Failed to create GraphDBOperation");
-		}
-		PowerMock.replay(GraphDBOperation.class);
-	}
-	
-	/**
-	 * Instantiate FlowSynchronizer and sync flows.
-	 * @param sw Target IOFSwitch object
-	 */
-	private void doSynchronization(IOFSwitch sw) {
-		sync = new FlowSynchronizer();
-		sync.init(pusher);
-		Future<SyncResult> future = sync.synchronize(sw);
-		try {
-			future.get();
-		} catch (Exception e) {
-			fail("Failed to Future#get()");
-		}
-	}
-}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/topology/TopologyManagerTest.java b/src/test/java/net/onrc/onos/ofcontroller/topology/TopologyManagerTest.java
deleted file mode 100644
index 4983541..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/topology/TopologyManagerTest.java
+++ /dev/null
@@ -1,246 +0,0 @@
-package net.onrc.onos.ofcontroller.topology;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import org.easymock.EasyMock;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import org.powermock.api.easymock.PowerMock;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-import com.thinkaurelius.titan.core.TitanGraph;
-import com.thinkaurelius.titan.core.TitanFactory;
-import net.onrc.onos.graph.DBConnection;
-import net.onrc.onos.graph.DBOperation;
-import net.onrc.onos.graph.GraphDBConnection;
-import net.onrc.onos.graph.GraphDBManager;
-import net.onrc.onos.graph.GraphDBOperation;
-import net.onrc.onos.ofcontroller.core.internal.TestDatabaseManager;
-import net.onrc.onos.ofcontroller.topology.TopologyManager;
-import net.onrc.onos.ofcontroller.util.DataPath;
-import net.onrc.onos.ofcontroller.util.Dpid;
-import net.onrc.onos.ofcontroller.util.FlowPathFlags;
-import net.onrc.onos.ofcontroller.util.Port;
-import net.onrc.onos.ofcontroller.util.SwitchPort;
-
-/**
- * A class for testing the TopologyManager class.
- * @see net.onrc.onos.ofcontroller.topology.TopologyManager
- */
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({TitanFactory.class, GraphDBConnection.class, GraphDBOperation.class, TopologyManager.class})
-public class TopologyManagerTest {
-    String conf;
-    String dbStore;
-    private DBConnection conn = null;
-    private DBOperation oper = null;
-    private TitanGraph titanGraph = null;
-    private TopologyManager topologyManager = null;
-
-    /**
-     * Setup the tests.
-     */
-    @Before
-    public void setUp() throws Exception {
-        dbStore = "dummyStore";
-	conf = "/dummy/path/to/db";
-
-	//
-	// Make mock database.
-	// Replace TitanFactory.open() to return the mock database.
-	//
-	titanGraph = TestDatabaseManager.getTestDatabase();
-	PowerMock.mockStatic(TitanFactory.class);
-	EasyMock.expect(TitanFactory.open((String)EasyMock.anyObject())).andReturn(titanGraph);
-	PowerMock.replay(TitanFactory.class);
-
-        oper = GraphDBManager.getDBOperation("ramcloud", "/tmp/ramcloud.conf");
-	// Create the connection to the database
-	conn = GraphDBManager.getConnection("ramcloud", "/tmp/ramcloud.conf");
-
-	// Populate the database
-	TestDatabaseManager.populateTestData(titanGraph);
-
-	// Prepare the TopologyManager instance
-	topologyManager = new TopologyManager(oper);
-    }
-
-    /**
-     * Cleanup after the tests.
-     */
-    @After
-    public void tearDown() throws Exception {
-	titanGraph.shutdown();
-	TestDatabaseManager.deleteTestDatabase();
-    }
-
-    /**
-     * Test method TopologyManager.getTopologyShortestPath()
-     *
-     * @see net.onrc.onos.ofcontroller.topology.TopologyManager#getTopologyShortestPath
-     */
-    @Test
-    public void test_getTopologyShortestPath() {
-	DataPath dataPath = null;
-	String srcDpidStr = "00:00:00:00:00:00:0a:01";
-	String dstDpidStr = "00:00:00:00:00:00:0a:06";
-	short srcPortShort = 1;
-	short dstPortShort = 1;
-
-	//
-	// Initialize the source and destination points
-	//
-	Dpid srcDpid = new Dpid(srcDpidStr);
-	Port srcPort = new Port(srcPortShort);
-	Dpid dstDpid = new Dpid(dstDpidStr);
-	Port dstPort = new Port(dstPortShort);
-	SwitchPort srcSwitchPort = new SwitchPort(srcDpid, srcPort);
-	SwitchPort dstSwitchPort = new SwitchPort(dstDpid, dstPort);
-
-	//
-	// Test a valid Shortest-Path computation
-	//
-	Topology topology = topologyManager.newDatabaseTopology();
-	dataPath = topologyManager.getTopologyShortestPath(topology,
-							   srcSwitchPort,
-							   dstSwitchPort);
-	assertTrue(dataPath != null);
-	String dataPathSummaryStr = dataPath.dataPathSummary();
-	// System.out.println(dataPathSummaryStr);
-	String expectedResult = "1/00:00:00:00:00:00:0a:01/2;1/00:00:00:00:00:00:0a:03/2;2/00:00:00:00:00:00:0a:04/3;1/00:00:00:00:00:00:0a:06/1;";
-	assertEquals(dataPathSummaryStr, expectedResult);
-
-	// Test if we apply various Flow Path Flags
-	String expectedResult2 = "1/00:00:00:00:00:00:0a:03/2;2/00:00:00:00:00:00:0a:04/3;1/00:00:00:00:00:00:0a:06/1;";
-	String expectedResult3 = "1/00:00:00:00:00:00:0a:03/2;";
-	FlowPathFlags flowPathFlags2 = new FlowPathFlags("DISCARD_FIRST_HOP_ENTRY");
-	FlowPathFlags flowPathFlags3 = new FlowPathFlags("KEEP_ONLY_FIRST_HOP_ENTRY");
-	//
-	dataPath.applyFlowPathFlags(flowPathFlags2);
-	dataPathSummaryStr = dataPath.dataPathSummary();
-	assertEquals(dataPathSummaryStr, expectedResult2);
-	//
-	dataPath.applyFlowPathFlags(flowPathFlags3);
-	dataPathSummaryStr = dataPath.dataPathSummary();
-	assertEquals(dataPathSummaryStr, expectedResult3);
-
-	//
-	// Test Shortest-Path computation to non-existing destination
-	//
-	String noSuchDpidStr = "ff:ff:00:00:00:00:0a:06";
-	Dpid noSuchDstDpid = new Dpid(noSuchDpidStr);
-	SwitchPort noSuchDstSwitchPort = new SwitchPort(noSuchDstDpid, dstPort);
-	dataPath = topologyManager.getTopologyShortestPath(topology,
-							   srcSwitchPort,
-							   noSuchDstSwitchPort);
-	assertTrue(dataPath == null);
-
-	topologyManager.dropTopology(topology);
-    }
-
-    /**
-     * Test method TopologyManager.getDatabaseShortestPath()
-     *
-     * @see net.onrc.onos.ofcontroller.routing.TopologyManager#getDatabaseShortestPath
-     */
-    @Test
-    public void test_getDatabaseShortestPath() {
-	DataPath dataPath = null;
-	String srcDpidStr = "00:00:00:00:00:00:0a:01";
-	String dstDpidStr = "00:00:00:00:00:00:0a:06";
-	short srcPortShort = 1;
-	short dstPortShort = 1;
-
-	//
-	// Initialize the source and destination points
-	//
-	Dpid srcDpid = new Dpid(srcDpidStr);
-	Port srcPort = new Port(srcPortShort);
-	Dpid dstDpid = new Dpid(dstDpidStr);
-	Port dstPort = new Port(dstPortShort);
-	SwitchPort srcSwitchPort = new SwitchPort(srcDpid, srcPort);
-	SwitchPort dstSwitchPort = new SwitchPort(dstDpid, dstPort);
-
-	//
-	// Test a valid Shortest-Path computation
-	//
-	dataPath = topologyManager.getDatabaseShortestPath(srcSwitchPort,
-							   dstSwitchPort);
-	assertTrue(dataPath != null);
-	String dataPathSummaryStr = dataPath.dataPathSummary();
-	// System.out.println(dataPathSummaryStr);
-	String expectedResult = "1/00:00:00:00:00:00:0a:01/2;1/00:00:00:00:00:00:0a:03/2;2/00:00:00:00:00:00:0a:04/3;1/00:00:00:00:00:00:0a:06/1;";
-	assertEquals(dataPathSummaryStr, expectedResult);
-
-	// Test if we apply various Flow Path Flags
-	String expectedResult2 = "1/00:00:00:00:00:00:0a:03/2;2/00:00:00:00:00:00:0a:04/3;1/00:00:00:00:00:00:0a:06/1;";
-	String expectedResult3 = "1/00:00:00:00:00:00:0a:03/2;";
-	FlowPathFlags flowPathFlags2 = new FlowPathFlags("DISCARD_FIRST_HOP_ENTRY");
-	FlowPathFlags flowPathFlags3 = new FlowPathFlags("KEEP_ONLY_FIRST_HOP_ENTRY");
-	//
-	dataPath.applyFlowPathFlags(flowPathFlags2);
-	dataPathSummaryStr = dataPath.dataPathSummary();
-	assertEquals(dataPathSummaryStr, expectedResult2);
-	//
-	dataPath.applyFlowPathFlags(flowPathFlags3);
-	dataPathSummaryStr = dataPath.dataPathSummary();
-	assertEquals(dataPathSummaryStr, expectedResult3);
-
-	//
-	// Test Shortest-Path computation to non-existing destination
-	//
-	String noSuchDpidStr = "ff:ff:00:00:00:00:0a:06";
-	Dpid noSuchDstDpid = new Dpid(noSuchDpidStr);
-	SwitchPort noSuchDstSwitchPort = new SwitchPort(noSuchDstDpid, dstPort);
-
-	dataPath = topologyManager.getDatabaseShortestPath(srcSwitchPort,
-							   noSuchDstSwitchPort);
-	assertTrue(dataPath == null);
-    }
-
-    /**
-     * Test method TopologyManager.routeExists()
-     *
-     * @see net.onrc.onos.ofcontroller.routing.TopologyManager#routeExists
-     */
-    @Test
-    public void test_routeExists() {
-	Boolean result;
-	String srcDpidStr = "00:00:00:00:00:00:0a:01";
-	String dstDpidStr = "00:00:00:00:00:00:0a:06";
-	short srcPortShort = 1;
-	short dstPortShort = 1;
-
-	//
-	// Initialize the source and destination points
-	//
-	Dpid srcDpid = new Dpid(srcDpidStr);
-	Port srcPort = new Port(srcPortShort);
-	Dpid dstDpid = new Dpid(dstDpidStr);
-	Port dstPort = new Port(dstPortShort);
-	SwitchPort srcSwitchPort = new SwitchPort(srcDpid, srcPort);
-	SwitchPort dstSwitchPort = new SwitchPort(dstDpid, dstPort);
-
-	//
-	// Test a valid route
-	//
-	result = topologyManager.routeExists(srcSwitchPort, dstSwitchPort);
-	assertTrue(result == true);
-
-	//
-	// Test a non-existing route
-	//
-	String noSuchDpidStr = "ff:ff:00:00:00:00:0a:06";
-	Dpid noSuchDstDpid = new Dpid(noSuchDpidStr);
-	SwitchPort noSuchDstSwitchPort = new SwitchPort(noSuchDstDpid, dstPort);
-	result = topologyManager.routeExists(srcSwitchPort,
-					     noSuchDstSwitchPort);
-	assertTrue(result != true);
-    }
-}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/util/FlowPathTest.java b/src/test/java/net/onrc/onos/ofcontroller/util/FlowPathTest.java
deleted file mode 100644
index 76ccf9f..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/util/FlowPathTest.java
+++ /dev/null
@@ -1,231 +0,0 @@
-package net.onrc.onos.ofcontroller.util;
-
-import static org.junit.Assert.*;
-import net.onrc.onos.ofcontroller.core.internal.TestableGraphDBOperation.TestFlowEntry;
-import net.onrc.onos.ofcontroller.core.internal.TestableGraphDBOperation.TestFlowPath;
-
-import org.junit.Before;
-import org.junit.Test;
-
-public class FlowPathTest {
-
-	FlowPath flowPath;
-	
-	@Before
-	public void setUp() throws Exception{
-		TestFlowPath iFlowPath = new TestFlowPath();
-		iFlowPath.setFlowIdForTest("0x1234");
-		iFlowPath.setInstallerIdForTest("installerId");
-		iFlowPath.setFlowPathTypeForTest("FP_TYPE_SHORTEST_PATH");
-		iFlowPath.setFlowPathUserStateForTest("FP_USER_ADD");
-		iFlowPath.setFlowPathFlagsForTest(0L);
-		iFlowPath.setIdleTimeoutForTest(5);
-		iFlowPath.setHardTimeoutForTest(10);
-		iFlowPath.setSrcSwForTest("CA:FE");
-		iFlowPath.setSrcPortForTest((short)1);
-		iFlowPath.setDstSwForTest("BA:BE");
-		iFlowPath.setDstPortForTest((short)2);
-		
-		iFlowPath.setActionsForTest("[[type=ACTION_OUTPUT action=[port=10 maxLen=11]];[type=ACTION_OUTPUT action=[port=12 maxLen=13]];]");
-		
-		TestFlowEntry iFlowEntry = new TestFlowEntry();
-		iFlowEntry.setEntryIdForTest("0x14");
-		iFlowEntry.setDpidForTest("BE:EF");
-		iFlowEntry.setActionsForTest("[[type=ACTION_OUTPUT action=[port=23 maxLen=24]];[type=ACTION_OUTPUT action=[port=25 maxLen=26]];]");
-		iFlowEntry.setUserStateForTest("FE_USER_MODIFY");
-		iFlowEntry.setSwitchStateForTest("FE_SWITCH_UPDATE_IN_PROGRESS");
-		iFlowPath.addFlowEntryForTest(iFlowEntry);
-		
-		flowPath = new FlowPath(iFlowPath);
-	}
-
-	@Test
-	public void testFlowPath(){
-		FlowPath flowPath = new FlowPath();
-		assertTrue ( flowPath.flowPathType() == FlowPathType.FP_TYPE_UNKNOWN);
-		assertTrue ( flowPath.flowPathUserState() == FlowPathUserState.FP_USER_UNKNOWN);
-		assertFalse( flowPath.flowPathFlags().isDiscardFirstHopEntry() );
-		assertFalse( flowPath.flowPathFlags().isKeepOnlyFirstHopEntry() );
-		assertTrue (flowPath.idleTimeout() == 0);
-		assertTrue (flowPath.hardTimeout() == 0);
-		assertTrue( flowPath.flowEntryActions().isEmpty() );
-	}
-
-	@Test
-	public void testFlowPathIFlowPath(){
-		TestFlowPath iFlowPath = new TestFlowPath();
-		iFlowPath.setFlowIdForTest("0x1234");
-		iFlowPath.setInstallerIdForTest("installerId");
-		iFlowPath.setFlowPathTypeForTest("FP_TYPE_SHORTEST_PATH");
-		iFlowPath.setFlowPathUserStateForTest("FP_USER_ADD");
-		iFlowPath.setFlowPathFlagsForTest(0L);
-		iFlowPath.setIdleTimeoutForTest(5);
-		iFlowPath.setHardTimeoutForTest(10);
-		iFlowPath.setSrcSwForTest("CA:FE");
-		iFlowPath.setSrcPortForTest((short)1);
-		iFlowPath.setDstSwForTest("BA:BE");
-		iFlowPath.setDstPortForTest((short)2);
-		
-		iFlowPath.setMatchSrcMacForTest("01:02:03:04:05:06");
-		iFlowPath.setMatchDstMacForTest("06:05:04:03:02:01");
-		iFlowPath.setMatchEthernetFrameTypeForTest((short)3);
-		iFlowPath.setMatchVlanIdForTest((short)4);
-		iFlowPath.setMatchVlanPriorityForTest((byte)5);
-		iFlowPath.setMatchSrcIpaddrForTest("127.0.0.1/32");
-		iFlowPath.setMatchDstIpaddrForTest("127.0.0.2/32");
-		iFlowPath.setMatchIpProtoForTest((byte)6);
-		iFlowPath.setMatchIpToSForTest((byte)7);
-		iFlowPath.setMatchSrcTcpUdpPortForTest((short)8);
-		iFlowPath.setMatchDstTcpUdpPortForTest((short)9);
-		
-		iFlowPath.setActionsForTest("[[type=ACTION_OUTPUT action=[port=10 maxLen=11]];[type=ACTION_OUTPUT action=[port=12 maxLen=13]];]");
-		
-		TestFlowEntry iFlowEntry = new TestFlowEntry();
-		iFlowEntry.setEntryIdForTest("0x14");
-		iFlowEntry.setDpidForTest("BE:EF");
-		iFlowEntry.setMatchInPortForTest((short)15);
-		iFlowEntry.setMatchSrcMacForTest("11:22:33:44:55:66");
-		iFlowEntry.setMatchDstMacForTest("66:55:44:33:22:11");
-		iFlowEntry.setMatchEtherFrameTypeForTest((short)16);
-		iFlowEntry.setMatchVlanIdForTest((short)17);
-		iFlowEntry.setMatchVlanPriorityForTest((byte)18);
-		iFlowEntry.setMatchSrcIpaddrForTest("127.0.0.3/32");
-		iFlowEntry.setMatchDstIpaddrForTest("127.0.0.4/32");
-		iFlowEntry.setMatchIpProtoForTest((byte)19);
-		iFlowEntry.setMatchIpToSForTest((byte)20);
-		iFlowEntry.setMatchSrcTcpUdpPortForTest((short)21);
-		iFlowEntry.setMatchDstTcpUdpPortForTest((short)22);
-		iFlowEntry.setActionsForTest("[[type=ACTION_OUTPUT action=[port=23 maxLen=24]];[type=ACTION_OUTPUT action=[port=25 maxLen=26]];]");
-		iFlowEntry.setUserStateForTest("FE_USER_MODIFY");
-		iFlowEntry.setSwitchStateForTest("FE_SWITCH_UPDATE_IN_PROGRESS");
-		iFlowPath.addFlowEntryForTest(iFlowEntry);
-		
-		FlowPath flowPath = new FlowPath(iFlowPath);
-		assertEquals(flowPath.flowId().value(), 0x1234);
-		assertEquals(flowPath.installerId().value(), "installerId");
-		assertEquals(flowPath.flowPathType(), FlowPathType.FP_TYPE_SHORTEST_PATH);
-		assertEquals(flowPath.flowPathUserState(), FlowPathUserState.FP_USER_ADD);
-		assertEquals(flowPath.flowPathFlags().flags(), 0);
-		assertEquals(flowPath.idleTimeout(), 5);
-		assertEquals(flowPath.hardTimeout(), 10);
-		assertEquals(flowPath.dataPath().srcPort().dpid().value(), 0xCAFE);
-		assertEquals(flowPath.dataPath().srcPort().port().value(), 1);
-		assertEquals(flowPath.dataPath().dstPort().dpid().value(), 0xBABE);
-		assertEquals(flowPath.dataPath().dstPort().port().value(), 2);
-		
-		assertEquals(flowPath.flowEntryMatch().srcMac().toString(), "01:02:03:04:05:06");
-		assertEquals(flowPath.flowEntryMatch().dstMac().toString(), "06:05:04:03:02:01");
-		assertEquals(flowPath.flowEntryMatch().ethernetFrameType().shortValue(), 3);
-		assertEquals(flowPath.flowEntryMatch().vlanId().shortValue(), 4);
-		assertEquals(flowPath.flowEntryMatch().vlanPriority().shortValue(), 5);
-		assertEquals(flowPath.flowEntryMatch().srcIPv4Net().address().toString(), "127.0.0.1");
-		assertEquals(flowPath.flowEntryMatch().srcIPv4Net().prefixLen() , 32);
-		assertEquals(flowPath.flowEntryMatch().dstIPv4Net().address().toString(), "127.0.0.2");
-		assertEquals(flowPath.flowEntryMatch().dstIPv4Net().prefixLen() , 32);
-		assertEquals(flowPath.flowEntryMatch().ipProto().byteValue(), 6);
-		assertEquals(flowPath.flowEntryMatch().ipToS().byteValue(), 7);
-		assertEquals(flowPath.flowEntryMatch().srcTcpUdpPort().shortValue(), 8);
-		assertEquals(flowPath.flowEntryMatch().dstTcpUdpPort().shortValue(), 9);
-		
-		assertEquals(flowPath.flowEntryActions().toString(),"[[type=ACTION_OUTPUT action=[port=10 maxLen=11]];[type=ACTION_OUTPUT action=[port=12 maxLen=13]];]");
-		
-		assertEquals(0x14, flowPath.dataPath().flowEntries().get(0).flowEntryId().value() );
-		assertEquals(0xBEEF, flowPath.dataPath().flowEntries().get(0).dpid().value() );
-		assertEquals(0, flowPath.dataPath().flowEntries().get(0).idleTimeout() );
-		assertEquals(0, flowPath.dataPath().flowEntries().get(0).hardTimeout() );
-		assertEquals(15, flowPath.dataPath().flowEntries().get(0).flowEntryMatch().inPort().value() );
-		assertEquals("11:22:33:44:55:66", flowPath.dataPath().flowEntries().get(0).flowEntryMatch().srcMac().toString());
-		assertEquals("66:55:44:33:22:11", flowPath.dataPath().flowEntries().get(0).flowEntryMatch().dstMac().toString());
-		assertEquals(16, flowPath.dataPath().flowEntries().get(0).flowEntryMatch().ethernetFrameType().shortValue());
-		assertEquals(17, flowPath.dataPath().flowEntries().get(0).flowEntryMatch().vlanId().shortValue());
-		assertEquals(18, flowPath.dataPath().flowEntries().get(0).flowEntryMatch().vlanPriority().byteValue());
-		assertEquals("127.0.0.3", flowPath.dataPath().flowEntries().get(0).flowEntryMatch().srcIPv4Net().address().toString());
-		assertEquals(32, flowPath.dataPath().flowEntries().get(0).flowEntryMatch().srcIPv4Net().prefixLen());
-		assertEquals("127.0.0.4", flowPath.dataPath().flowEntries().get(0).flowEntryMatch().dstIPv4Net().address().toString());
-		assertEquals(32, flowPath.dataPath().flowEntries().get(0).flowEntryMatch().dstIPv4Net().prefixLen());
-		assertEquals(19, flowPath.dataPath().flowEntries().get(0).flowEntryMatch().ipProto().byteValue());
-		assertEquals(20, flowPath.dataPath().flowEntries().get(0).flowEntryMatch().ipToS().byteValue());
-		assertEquals(21, flowPath.dataPath().flowEntries().get(0).flowEntryMatch().srcTcpUdpPort().shortValue());
-		assertEquals(22, flowPath.dataPath().flowEntries().get(0).flowEntryMatch().dstTcpUdpPort().shortValue());
-		assertEquals("[[type=ACTION_OUTPUT action=[port=23 maxLen=24]];[type=ACTION_OUTPUT action=[port=25 maxLen=26]];]", flowPath.dataPath().flowEntries().get(0).flowEntryActions().toString());
-		assertEquals("FE_USER_MODIFY", flowPath.dataPath().flowEntries().get(0).flowEntryUserState().toString());
-		assertEquals("FE_SWITCH_UPDATE_IN_PROGRESS", flowPath.dataPath().flowEntries().get(0).flowEntrySwitchState().toString());
-	}
-
-	@Test
-	public void testSetFlowPathType(){
-		FlowPath flowPath = new FlowPath();
-		FlowPathType type = FlowPathType.FP_TYPE_SHORTEST_PATH;
-		flowPath.setFlowPathType( type );
-		assertTrue( flowPath.flowPathType() == FlowPathType.FP_TYPE_SHORTEST_PATH );
-	}
-
-	@Test
-	public void testSetFlowPathUserState(){
-		FlowPath flowPath = new FlowPath();
-		FlowPathUserState state = FlowPathUserState.FP_USER_ADD;
-		flowPath.setFlowPathUserState( state );
-		assertTrue( flowPath.flowPathUserState() == FlowPathUserState.FP_USER_ADD );
-	}
-
-	@Test
-	public void testFlowPathFlags(){
-		FlowPath flowPath = new FlowPath();
-		FlowPathFlags flags = new FlowPathFlags();
-		flags.setFlags(0);
-		flowPath.setFlowPathFlags( flags );
-		assertFalse( flowPath.flowPathFlags().isDiscardFirstHopEntry() );
-		assertFalse( flowPath.flowPathFlags().isKeepOnlyFirstHopEntry() );
-	}
-
-	@Test
-	public void testSetFlowPathFlags(){
-		FlowPath flowPath = new FlowPath();
-		FlowPathFlags flags = new FlowPathFlags("DISCARD_FIRST_HOP_ENTRY");
-		flags.setFlagsStr("KEEP_ONLY_FIRST_HOP_ENTRY");
-		flowPath.setFlowPathFlags( flags );
-		assertFalse( flowPath.flowPathFlags().isDiscardFirstHopEntry() );
-		assertTrue( flowPath.flowPathFlags().isKeepOnlyFirstHopEntry() );
-	}
-
-	@Test
-	public void testSetIdleTimeout(){
-		FlowPath flowPath = new FlowPath();
-		int idleTimeout = 15;
-		flowPath.setIdleTimeout( idleTimeout );
-		assertTrue( flowPath.idleTimeout() == 15 );
-	}
-
-	@Test
-	public void testSetHardTimeout(){
-		FlowPath flowPath = new FlowPath();
-		int hardTimeout = 20;
-		flowPath.setHardTimeout( hardTimeout );
-		assertTrue( flowPath.hardTimeout() == 20 );
-	}
-
-	@Test
-	public void testSetDataPath(){
-		FlowPath flowPath = new FlowPath();
-		DataPath dataPath = new DataPath();
-		flowPath.setDataPath( dataPath );
-		assertEquals(flowPath.dataPath(), dataPath );
-	}
-
-	@Test
-	public void testToString(){
-
-		assertEquals("[flowId=0x1234 installerId=installerId flowPathType=FP_TYPE_SHORTEST_PATH flowPathUserState=FP_USER_ADD flowPathFlags=[flags=] idleTimeout=5 hardTimeout=10 dataPath=[src=00:00:00:00:00:00:ca:fe/1 flowEntry=[flowEntryId=0x14 idleTimeout=0 hardTimeout=0 flowEntryMatch=[] flowEntryActions=[[type=ACTION_OUTPUT action=[port=23 maxLen=24]];[type=ACTION_OUTPUT action=[port=25 maxLen=26]];] dpid=00:00:00:00:00:00:be:ef flowEntryUserState=FE_USER_MODIFY flowEntrySwitchState=FE_SWITCH_UPDATE_IN_PROGRESS] dst=00:00:00:00:00:00:ba:be/2] flowEntryMatch=[] flowEntryActions=[[type=ACTION_OUTPUT action=[port=10 maxLen=11]];[type=ACTION_OUTPUT action=[port=12 maxLen=13]];]]", flowPath.toString());
-	}
-
-	@Test
-	public void testCompareTo(){
-		FlowPath flowPath1 = new FlowPath();
-		flowPath1.setFlowId( new FlowId(1));
-		FlowPath flowPath2 = new FlowPath();
-		flowPath2.setFlowId( new FlowId(2));
-		
-		assertTrue( flowPath1.compareTo(flowPath2) < 0);
-	}
-
-}
