diff --git a/.gitignore b/.gitignore
index c9e6bc1..88f7bb1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,5 +8,6 @@
 target
 onos-logs
 onos.log
+repo
 logback.*.xml
 
diff --git a/conf/onos.properties b/conf/onos.properties
index e77e6e0..f1244df 100644
--- a/conf/onos.properties
+++ b/conf/onos.properties
@@ -12,5 +12,7 @@
 net.floodlightcontroller.core.FloodlightProvider.workerthreads = 16
 net.floodlightcontroller.forwarding.Forwarding.idletimeout = 5
 net.floodlightcontroller.forwarding.Forwarding.hardtimeout = 0
-net.onrc.onos.ofcontroller.floodlightlistener.NetworkGraphPublisher.dbconf = /tmp/cassandra.titan
+#net.onrc.onos.ofcontroller.floodlightlistener.NetworkGraphPublisher.dbconf = /tmp/cassandra.titan
 net.onrc.onos.datagrid.HazelcastDatagrid.datagridConfig = conf/hazelcast.xml
+net.onrc.onos.ofcontroller.floodlightlistener.NetworkGraphPublisher.dbconf = /tmp/ramcloud.conf
+net.onrc.onos.ofcontroller.floodlightlistener.NetworkGraphPublisher.graph_db_store = ramcloud
diff --git a/conf/ramcloud.conf b/conf/ramcloud.conf
new file mode 100644
index 0000000..84b4ff2
--- /dev/null
+++ b/conf/ramcloud.conf
@@ -0,0 +1 @@
+ramcloud.coordinator=fast+udp:host=10.128.100.36,port=12246
diff --git a/pom.xml b/pom.xml
index 39e9f30..c19c56f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,7 +8,7 @@
   <artifactId>onos</artifactId>
   <version>0.1.0</version>
   <packaging>jar</packaging>
-  <name>ONOS</name>
+  <name>ONOS-RAMCloud</name>
   <url>http://onlab.us/</url>
   <repositories>
     <!-- In Project repository -->
@@ -195,11 +195,13 @@
               <goal>build-classpath</goal>
             </goals>
             <configuration>
+              <!-- configure the plugin here -->
               <outputFile>${project.basedir}/.javacp</outputFile>
             </configuration>
           </execution>
         </executions>
       </plugin>
+
     </plugins>
   </build>
   <!-- for getting visualization reporting   -->
@@ -475,5 +477,10 @@
       <version>0.1.0</version>
     </dependency>
     -->
+    <dependency>
+      <groupId>com.tinkerpop.blueprints.impls.ramcloud</groupId>
+      <artifactId>blueprints-ramcloud-graph</artifactId>
+      <version>2.5.0</version>
+    </dependency>
   </dependencies>
 </project>
diff --git a/src/main/java/net/onrc/onos/graph/DBConnection.java b/src/main/java/net/onrc/onos/graph/DBConnection.java
new file mode 100644
index 0000000..dee458a
--- /dev/null
+++ b/src/main/java/net/onrc/onos/graph/DBConnection.java
@@ -0,0 +1,19 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package net.onrc.onos.graph;
+
+/**
+ *
+ * @author nickkaranatsios
+ */
+public abstract class DBConnection implements IDBConnection {
+    public enum Transaction {
+        COMMIT, ROLLBACK
+    }
+
+    public enum GenerateEvent {
+        TRUE, FALSE
+    }
+}
diff --git a/src/main/java/net/onrc/onos/graph/DBOperation.java b/src/main/java/net/onrc/onos/graph/DBOperation.java
new file mode 100644
index 0000000..6e278d9
--- /dev/null
+++ b/src/main/java/net/onrc/onos/graph/DBOperation.java
@@ -0,0 +1,450 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package net.onrc.onos.graph;
+
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.blueprints.impls.ramcloud.*;
+import com.tinkerpop.frames.FramedGraph;
+import com.tinkerpop.frames.structures.FramedVertexIterable;
+import com.tinkerpop.gremlin.java.GremlinPipeline;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IBaseObject;
+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;
+import net.onrc.onos.ofcontroller.util.FlowEntryId;
+import net.onrc.onos.ofcontroller.util.FlowId;
+
+public abstract class DBOperation implements IDBOperation {
+
+	protected DBConnection conn;
+	private final static Logger log = LoggerFactory.getLogger(DBOperation.class);
+
+
+	/**
+	 * Search and get an active switch object with DPID.
+	 * @param dpid DPID of the switch
+	 */
+	@Override
+	public ISwitchObject searchActiveSwitch(String dpid) {
+	    ISwitchObject sw = searchSwitch(dpid);
+	    if ((sw != null)
+		    && sw.getState().equals(ISwitchStorage.SwitchState.ACTIVE.toString())) {
+		return sw;
+	    }
+	    return null;
+	}
+
+	/**
+	 * Create a new switch and return the created switch object.
+	 * @param dpid DPID of the switch
+	 */
+	@Override
+	public ISwitchObject newSwitch(final String dpid) {
+	    //System.out.println("newSwitch");
+	    ISwitchObject obj = (ISwitchObject) conn.getFramedGraph().addVertex(null, ISwitchObject.class);
+	    if (obj != null) {
+		obj.setType("switch");
+		obj.setDPID(dpid);
+	    }
+	    return obj;
+	}
+
+	/**
+	 * Get all port objects.
+	 */
+	@Override
+	public Iterable<IPortObject> getAllPorts() {
+	    Iterable<IPortObject> ports = conn.getFramedGraph().getVertices("type", "port", IPortObject.class);
+	    return ports;
+	}
+
+	/**
+	 * Get all switch objects.
+	 */
+	@Override
+	public Iterable<ISwitchObject> getAllSwitches() {
+	    //System.out.println("getAllSwitches");
+	    Iterable<ISwitchObject> switches = conn.getFramedGraph().getVertices("type", "switch", ISwitchObject.class);
+	    return switches;
+	}
+
+	/**
+	 * Get all inactive switch objects.
+	 */
+	@Override
+	public Iterable<ISwitchObject> getInactiveSwitches() {
+	    //System.out.println("getInactiveSwitches");
+	    Iterable<ISwitchObject> switches = conn.getFramedGraph().getVertices("type", "switch", ISwitchObject.class);
+	    List<ISwitchObject> inactiveSwitches = new ArrayList<ISwitchObject>();
+
+	    for (ISwitchObject sw : switches) {
+		if (sw.getState().equals(ISwitchStorage.SwitchState.INACTIVE.toString())) {
+		    inactiveSwitches.add(sw);
+		}
+	    }
+	    return inactiveSwitches;
+	}
+
+	/**
+	 * Get all flow entries objects where their switches are not updated.
+	 */
+	@Override
+	public Iterable<INetMapTopologyObjects.IFlowEntry> getAllSwitchNotUpdatedFlowEntries() {
+	    //TODO: Should use an enum for flow_switch_state
+	    return conn.getFramedGraph().getVertices("switch_state", "FE_SWITCH_NOT_UPDATED", INetMapTopologyObjects.IFlowEntry.class);
+
+	}
+
+	/**
+	 * Remove specified switch.
+	 * @param sw switch object to remove
+	 */
+	@Override
+	public void removeSwitch(ISwitchObject sw) {
+	    //System.out.println("removeSwitch");
+	    conn.getFramedGraph().removeVertex(sw.asVertex());
+	}
+
+	@Override
+	public IPortObject newPort(String dpid, Short portNum) {
+	    //System.out.println("newPort");
+	    IPortObject obj = (IPortObject) conn.getFramedGraph().addVertex(null, IPortObject.class);
+	    if (obj != null) {
+		obj.setType("port");
+		String id = dpid + PORT_ID_DELIM + portNum.toString();
+		obj.setPortId(id);
+		obj.setNumber(portNum);
+	    }
+	    return obj;
+	}
+
+	/**
+	* Create a port having specified port number.
+	*
+	* @param portNumber port number
+	*/
+	@Override
+	@Deprecated
+	public IPortObject newPort(Short portNumber) {
+	    IPortObject obj = (IPortObject) conn.getFramedGraph().addVertex(null, IPortObject.class);
+	    if (obj != null) {
+		obj.setType("port");
+		obj.setNumber(portNumber);
+	    }
+	    return obj;
+	}
+
+	/**
+	 * Search and get a port object of specified switch and port number.
+	 * @param dpid DPID of a switch
+	 * @param number port number of the switch's port
+	 */
+	@Override
+	public IPortObject searchPort(String dpid, Short number) {
+	    FramedGraph fg = conn.getFramedGraph();
+	    if ( fg == null ) return null;
+	    String id = dpid + PORT_ID_DELIM + number.toString();
+	    Iterator<IPortObject> it = fg.getVertices("port_id", id, IPortObject.class).iterator();
+	    return (it.hasNext()) ? it.next() : null;
+
+	}
+
+	/**
+	 * Remove the specified switch port.
+	 * @param port switch port object to remove
+	 */
+	@Override
+	public void removePort(IPortObject port) {
+	    //System.out.println("removeProt");
+	    if (conn.getFramedGraph() != null) {
+		conn.getFramedGraph().removeVertex(port.asVertex());
+	    }
+	}
+
+	/**
+	 * Create and return a device object.
+	 */
+	@Override
+	public IDeviceObject newDevice() {
+	    //System.out.println("newDevice");
+	    IDeviceObject obj = (IDeviceObject) conn.getFramedGraph().addVertex(null, IDeviceObject.class);
+	    if (obj != null) {
+		obj.setType("device");
+	    }
+	    return obj;
+	}
+
+	/**
+	 * Get all devices.
+	 */
+	@Override
+	public Iterable<IDeviceObject> getDevices() {
+	    //System.out.println("getDeiveces");
+	    return conn.getFramedGraph() != null ? conn.getFramedGraph().getVertices("type", "device", IDeviceObject.class) : null;
+	}
+
+	/**
+	 * Remove the specified device.
+	 * @param dev a device object to remove
+	 */
+	@Override
+	public void removeDevice(IDeviceObject dev) {
+	    //System.out.println("removeDevice");
+	    if (conn.getFramedGraph() != null) {
+		conn.getFramedGraph().removeVertex(dev.asVertex());
+	    }
+	}
+
+	/**
+	* Create and return a flow path object.
+	*/
+	@Override
+	public IFlowPath newFlowPath() {
+	    //System.out.println("newFlowPath");
+	    IFlowPath flowPath = (IFlowPath)conn.getFramedGraph().addVertex(null, IFlowPath.class);
+	    //System.out.println("flowPath : " + flowPath);
+	    if (flowPath != null) {
+		flowPath.setType("flow");
+	    }
+	    return flowPath;
+	}
+
+	/**
+	 * Get a flow path object with a flow entry.
+	 * @param flowEntry flow entry object
+	 */
+	@Override
+	public IFlowPath getFlowPathByFlowEntry(INetMapTopologyObjects.IFlowEntry flowEntry) {
+	    GremlinPipeline<Vertex, IFlowPath> pipe = new GremlinPipeline<Vertex, IFlowPath>();
+	    pipe.start(flowEntry.asVertex());
+	    pipe.out("flow");
+	    FramedVertexIterable<IFlowPath> r = new FramedVertexIterable(conn.getFramedGraph(), pipe, IFlowPath.class);
+	    return r.iterator().hasNext() ? r.iterator().next() : null;
+	}
+
+
+	/**
+	* Search and get a switch object with DPID.
+	*
+	* @param dpid DPID of the switch
+	*/
+	@Override
+	public ISwitchObject searchSwitch(final String dpid) {
+	    FramedGraph fg = conn.getFramedGraph();
+	    if ( fg == null ) return null;
+	    Iterator<ISwitchObject> it = fg.getVertices("dpid", dpid, ISwitchObject.class).iterator();
+	    return (it.hasNext()) ? it.next() : null;
+	}
+
+	/**
+	 * Get all active switch objects.
+	 */
+	@Override
+	public Iterable<ISwitchObject> getActiveSwitches() {
+	    Iterable<ISwitchObject> switches = conn.getFramedGraph().getVertices("type", "switch", ISwitchObject.class);
+	    List<ISwitchObject> activeSwitches = new ArrayList<ISwitchObject>();
+
+	    for (ISwitchObject sw : switches) {
+		if (sw.getState().equals(ISwitchStorage.SwitchState.ACTIVE.toString())) {
+		    activeSwitches.add(sw);
+		}
+	    }
+	    return activeSwitches;
+	}
+
+	/**
+	 * Search and get a device object having specified MAC address.
+	 * @param macAddr MAC address to search and get
+	 */
+	@Override
+	public IDeviceObject searchDevice(String macAddr) {
+	    FramedGraph fg = conn.getFramedGraph();
+	    if ( fg == null ) return null;
+	    Iterator<IDeviceObject> it = fg.getVertices("dl_addr", macAddr, IDeviceObject.class).iterator();
+	    return (it.hasNext()) ? it.next() : null;
+	}
+
+	/**
+	 * Search and get a flow path object with specified flow ID.
+	 * @param flowId flow ID to search
+	 */
+	@Override
+	public IFlowPath searchFlowPath(final FlowId flowId) {
+	    FramedGraph fg = conn.getFramedGraph();
+	    if ( fg == null ) return null;
+	    Iterator<IFlowPath> it = fg.getVertices("flow_id", flowId.toString(), IFlowPath.class).iterator();
+	    return (it.hasNext()) ? it.next() : null;
+	}
+
+	/**
+	 * Get all flow path objects.
+	 */
+	@Override
+	public Iterable<IFlowPath> getAllFlowPaths() {
+	    //System.out.println("getAllFlowPaths");
+	    Iterable<IFlowPath> flowPaths = conn.getFramedGraph().getVertices("type", "flow", IFlowPath.class);
+
+	    List<IFlowPath> nonNullFlows = new ArrayList<IFlowPath>();
+
+	    for (IFlowPath fp : flowPaths) {
+		if (fp.getFlowId() != null) {
+		    nonNullFlows.add(fp);
+		}
+	    }
+	    return nonNullFlows;
+	}
+
+	/**
+	 * Remove the specified flow path.
+	 * @param flowPath flow path object to remove
+	 */
+	@Override
+	public void removeFlowPath(IFlowPath flowPath) {
+	    //System.out.println("removeFlowPath");
+	    conn.getFramedGraph().removeVertex(flowPath.asVertex());
+	}
+
+	/**
+	 * Search and get a flow entry object with flow entry ID.
+	 * @param flowEntryId flow entry ID to search
+	 */
+	@Override
+	public IFlowEntry searchFlowEntry(FlowEntryId flowEntryId) {
+	    FramedGraph fg = conn.getFramedGraph();
+	    if ( fg == null ) return null;
+	    Iterator<IFlowEntry> it = fg.getVertices("flow_entry_id", flowEntryId.toString(), IFlowEntry.class).iterator();
+	    return (it.hasNext()) ? it.next() : null;
+	}
+
+	/**
+	 * Get all flow entry objects.
+	 */
+	@Override
+	public Iterable<IFlowEntry> getAllFlowEntries() {
+	    return conn.getFramedGraph().getVertices("type", "flow_entry", IFlowEntry.class);
+	}
+
+	/**
+	 * Remove the specified flow entry.
+	 * @param flowEntry flow entry object to remove
+	 */
+	@Override
+	public void removeFlowEntry(IFlowEntry flowEntry) {
+	    //System.out.println("removeFlowEntry");
+	    conn.getFramedGraph().removeVertex(flowEntry.asVertex());
+	}
+
+	/**
+	 * Create and return a flow entry object.
+	 */
+	@Override
+	public IFlowEntry newFlowEntry() {
+	    //System.out.println("newFlowEntry");
+	    IFlowEntry flowEntry = (IFlowEntry) conn.getFramedGraph().addVertex(null, IFlowEntry.class);
+	    if (flowEntry != null) {
+		flowEntry.setType("flow_entry");
+	    }
+	    return flowEntry;
+	}
+
+
+	public IIpv4Address newIpv4Address() {
+		return newVertex("ipv4Address", IIpv4Address.class);
+	}
+
+	private <T extends IBaseObject> T newVertex(String type, Class<T> vertexType) {
+		T newVertex = (T) conn.getFramedGraph().addVertex(null, vertexType);
+		if (newVertex != null) {
+			newVertex.setType(type);
+		}
+		return newVertex;
+	}
+
+	public IIpv4Address searchIpv4Address(int intIpv4Address) {
+		return searchForVertex("ipv4_address", intIpv4Address, IIpv4Address.class);
+	}
+
+
+	public IIpv4Address ensureIpv4Address(int intIpv4Address) {
+		IIpv4Address ipv4Vertex = searchIpv4Address(intIpv4Address);
+		if (ipv4Vertex == null) {
+			ipv4Vertex = newIpv4Address();
+			ipv4Vertex.setIpv4Address(intIpv4Address);
+		}
+		return ipv4Vertex;
+	}
+
+
+	private <T> T searchForVertex(String propertyName, Object propertyValue, Class<T> vertexType) {
+		if (conn.getFramedGraph() != null) {
+			Iterator<T> it = conn.getFramedGraph().getVertices(propertyName, propertyValue, vertexType).iterator();
+			if (it.hasNext()) {
+				return it.next();
+			}
+		}
+		return null;
+	}
+
+	public void removeIpv4Address(IIpv4Address ipv4Address) {
+		//System.out.println("removeIpv4Address");
+		conn.getFramedGraph().removeVertex(ipv4Address.asVertex());
+	}
+
+	/**
+	 * Get the instance of GraphDBConnection assigned to this class.
+	 */
+	@Override
+	public IDBConnection getDBConnection() {
+	    return conn;
+	}
+
+	@Override
+	public void commit() {
+	    conn.commit();
+	}
+
+	@Override
+	public void rollback() {
+	    conn.rollback();
+	}
+
+	@Override
+	public void close() {
+	    conn.close();
+	}
+
+	@Override
+	public void setVertexProperties(Vertex vertex, Map<String, Object> map) {
+		log.debug("setProperties start: size {}", map.size());
+		RamCloudVertex v = (RamCloudVertex) vertex;
+		v.setProperties(map);
+		log.debug("setProperties end: size {}, id {}", map.size(), v.getId());
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		for(ISwitchObject sw: getAllSwitches()) {
+			sb.append("sw: " + sw.getDPID() + "\n");
+			for(IPortObject port: sw.getPorts()) {
+				sb.append("  port: " + port.getPortId() + "\n");
+			}
+		}
+		return sb.toString();
+	}
+}
diff --git a/src/main/java/net/onrc/onos/graph/GraphDBManager.java b/src/main/java/net/onrc/onos/graph/GraphDBManager.java
new file mode 100644
index 0000000..ec7eb7f
--- /dev/null
+++ b/src/main/java/net/onrc/onos/graph/GraphDBManager.java
@@ -0,0 +1,58 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package net.onrc.onos.graph;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ *
+ * @author nickkaranatsios
+ */
+public class GraphDBManager {
+    private static ThreadLocal<HashMap<String, DBConnection>> connections = new ThreadLocal<HashMap<String, DBConnection>>();
+    private static DBOperation operation = null;
+    
+    static Map<String, DBConnection> getConnectionMap() {
+        if (connections.get() == null) {
+            connections.set(new HashMap<String, DBConnection>());
+        }
+        return connections.get();
+    }
+
+    public static DBOperation getDBOperation(final String dbStore, final String dbConfigFile) {
+	if (dbStore.equals("ramcloud")) {
+	    operation = new RamCloudDBOperation();
+	} else if (dbStore.equals("titan")) {
+	    operation = new TitanDBOperation();
+	}
+	if (operation != null) {
+	    operation.conn = GraphDBManager.getConnection(dbStore, dbConfigFile);
+	}
+        return operation;
+    }
+
+    public static DBConnection getConnection(final String dbStore, final String dbConfigFile) {
+        DBConnection conn = getConnectionMap().get(dbStore);
+        if (conn == null) {
+            if (dbStore.equals("ramcloud")) {
+                conn = new RamCloudDBConnection(dbConfigFile);
+            } else if (dbStore.equals("titan")) {
+                conn = new TitanDBConnection(dbConfigFile);
+            }
+
+            GraphDBManager.getConnectionMap().put(dbStore, conn);
+        } else {
+            GraphDBManager.getConnectionMap().get(dbStore);
+        }
+        return conn;
+    }
+
+    static List<DBConnection> getConnections() {
+        return new ArrayList<DBConnection>(getConnectionMap().values());
+    }
+}
diff --git a/src/main/java/net/onrc/onos/graph/GraphDBOperation.java b/src/main/java/net/onrc/onos/graph/GraphDBOperation.java
deleted file mode 100644
index 26e6181..0000000
--- a/src/main/java/net/onrc/onos/graph/GraphDBOperation.java
+++ /dev/null
@@ -1,457 +0,0 @@
-package net.onrc.onos.graph;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IBaseObject;
-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.util.FlowEntryId;
-import net.onrc.onos.ofcontroller.util.FlowId;
-
-import com.thinkaurelius.titan.core.TitanGraph;
-import com.tinkerpop.blueprints.Vertex;
-import com.tinkerpop.frames.FramedGraph;
-import com.tinkerpop.frames.structures.FramedVertexIterable;
-import com.tinkerpop.gremlin.java.GremlinPipeline;
-
-public class GraphDBOperation implements IDBOperation {
-	private GraphDBConnection conn;
-
-	/**
-	 * Create a GraphDBOperation instance from specified GraphDBConnection's instance.
-	 * @param dbConnection an instance of GraphDBConnection
-	 */
-	public GraphDBOperation(GraphDBConnection dbConnection) {
-		this.conn = dbConnection;
-	}
-
-	/**
-	 * Create a GraphDBOperation instance from database configuration path.
-	 * @param dbConfPath a path for database configuration file.
-	 */
-	public GraphDBOperation(final String dbConfPath) {
-		this.conn = GraphDBConnection.getInstance(dbConfPath);
-	}
-
-	/**
-	 * Create a new switch and return the created switch object.
-	 * @param dpid DPID of the switch
-	 */
-	@Override
-	public ISwitchObject newSwitch(String dpid) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		ISwitchObject obj = fg.addVertex(null,ISwitchObject.class);
-		if (obj != null) {
-			obj.setType("switch");
-			obj.setDPID(dpid);
-		}
-		return obj;
-	}
-
-	/**
-	 * Search and get a switch object with DPID.
-	 * @param dpid DPID of the switch
-	 */
-	@Override
-	public ISwitchObject searchSwitch(String dpid) {
-
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		if ( fg == null ) return null;
-		Iterator<ISwitchObject> it = fg.getVertices("dpid",dpid,ISwitchObject.class).iterator();
-		return (it.hasNext()) ? it.next() : null;
-
-	}
-
-	/**
-	 * Search and get an active switch object with DPID.
-	 * @param dpid DPID of the switch
-	 */
-	@Override
-	public ISwitchObject searchActiveSwitch(String dpid) {
-
-	    ISwitchObject sw = searchSwitch(dpid);
-	    if ((sw != null) &&
-	        sw.getState().equals(SwitchState.ACTIVE.toString())) {
-	        return sw;
-	    }
-	    return null;
-	}
-	
-	/**
-     * Get all switch objects.
-     */
-    @Override
-    public Iterable<IPortObject> getAllPorts() {
-        FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-        Iterable<IPortObject> ports =  fg.getVertices("type","port",IPortObject.class);
-        return ports;
-    }
-    
-	/**
-	 * Get all switch objects.
-	 */
-	@Override
-	public Iterable<ISwitchObject> getAllSwitches() {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		Iterable<ISwitchObject> switches =  fg.getVertices("type","switch",ISwitchObject.class);
-		return switches;
-	}
-
-	/**
-	 * Get all active switch objects.
-	 */
-	@Override
-	public Iterable<ISwitchObject> getActiveSwitches() {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		Iterable<ISwitchObject> switches =  fg.getVertices("type","switch",ISwitchObject.class);
-		List<ISwitchObject> activeSwitches = new ArrayList<ISwitchObject>();
-
-		for (ISwitchObject sw: switches) {
-			if(sw.getState().equals(SwitchState.ACTIVE.toString())) {
-				activeSwitches.add(sw);
-			}
-		}
-		return activeSwitches;
-	}
-
-	/**
-	 * Get all inactive switch objects.
-	 */
-	@Override
-	public Iterable<ISwitchObject> getInactiveSwitches() {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		Iterable<ISwitchObject> switches =  fg.getVertices("type","switch",ISwitchObject.class);
-		List<ISwitchObject> inactiveSwitches = new ArrayList<ISwitchObject>();
-
-		for (ISwitchObject sw: switches) {
-			if(sw.getState().equals(SwitchState.INACTIVE.toString())) {
-				inactiveSwitches.add(sw);
-			}
-		}
-		return inactiveSwitches;
-	}
-
-	/**
-	 * Get all flow entries' objects where their switches are not updated.
-	 */
-	@Override
-	public Iterable<IFlowEntry> getAllSwitchNotUpdatedFlowEntries() {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		//TODO: Should use an enum for flow_switch_state
-		return fg.getVertices("switch_state", "FE_SWITCH_NOT_UPDATED", IFlowEntry.class);
-	}
-
-	/**
-	 * Remove specified switch.
-	 * @param sw switch object to remove
-	 */
-	@Override
-	public void removeSwitch(ISwitchObject sw) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		fg.removeVertex(sw.asVertex());
-	}
-
-	@Override
-	public IPortObject newPort(String dpid, Short portNumber) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		IPortObject obj = fg.addVertex(null,IPortObject.class);
-		if (obj != null) {
-			obj.setType("port");
-			String id = dpid + PORT_ID_DELIM + portNumber.toString();
-			obj.setPortId(id);
-			obj.setNumber(portNumber);
-		}
-		return obj;
-
-	}
-
-	/**
-	 * Create a port having specified port number.
-	 * @param portNumber port number
-	 */
-	@Override
-	@Deprecated
-	public IPortObject newPort(Short portNumber) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		IPortObject obj = fg.addVertex(null,IPortObject.class);
-		if (obj != null) {
-			obj.setType("port");
-			obj.setNumber(portNumber);
-		}
-		return obj;
-	}
-
-	/**
-	 * Search and get a port object of specified switch and port number.
-	 * @param dpid DPID of a switch
-	 * @param number port number of the switch's port
-	 */
-	@Override
-	public IPortObject searchPort(String dpid, Short number) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		if ( fg == null ) return null;
-		String id = dpid + IDBOperation.PORT_ID_DELIM + number.toString();
-		Iterator<IPortObject> ports =  fg.getVertices("port_id",id,IPortObject.class).iterator();
-		if ( ports.hasNext() ) {
-			return ports.next();
-		} else {
-			return null;
-		}
-	}
-
-	/**
-	 * Remove the specified switch port.
-	 * @param port switch port object to remove
-	 */
-	@Override
-	public void removePort(IPortObject port) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-//		EventGraph<TitanGraph> eg = conn.getEventGraph();
-		if (fg != null) fg.removeVertex(port.asVertex());
-	}
-
-	/**
-	 * Create and return a device object.
-	 */
-	@Override
-	public IDeviceObject newDevice() {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		IDeviceObject obj = fg.addVertex(null,IDeviceObject.class);
-		if (obj != null) obj.setType("device");
-		return obj;
-	}
-
-	/**
-	 * Search and get a device object having specified MAC address.
-	 * @param macAddr MAC address to search and get
-	 */
-	@Override
-	public IDeviceObject searchDevice(String macAddr) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		if ( fg == null ) return null;
-		Iterator<IDeviceObject> devices =  fg.getVertices("dl_addr",macAddr, IDeviceObject.class).iterator();
-		if ( devices.hasNext() ) {
-			return devices.next();
-		} else {
-			return null;
-		}
-	}
-
-	/**
-	 * Get all devices.
-	 */
-	@Override
-	public Iterable<IDeviceObject> getDevices() {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		return fg != null ? fg.getVertices("type","device",IDeviceObject.class) : null;
-	}
-
-	/**
-	 * Remove the specified device.
-	 * @param dev a device object to remove
-	 */
-	@Override
-	public void removeDevice(IDeviceObject dev) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		if (fg != null) fg.removeVertex(dev.asVertex());
-	}
-
-	public IIpv4Address newIpv4Address() {
-		return newVertex("ipv4Address", IIpv4Address.class);
-	}
-
-	private <T extends IBaseObject> T newVertex(String type, Class<T> vertexType) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		T newVertex = fg.addVertex(null, vertexType);
-		if (newVertex != null) {
-			newVertex.setType(type);
-		}
-		return newVertex;
-	}
-
-	public IIpv4Address searchIpv4Address(int intIpv4Address) {
-		return searchForVertex("ipv4_address", intIpv4Address, IIpv4Address.class);
-	}
-
-	private <T> T searchForVertex(String propertyName, Object propertyValue, Class<T> vertexType) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		if (fg != null) {
-			Iterator<T> it =
-					fg.getVertices(propertyName, propertyValue, vertexType).iterator();
-			if (it.hasNext()) {
-				return it.next();
-			}
-		}
-		return null;
-	}
-
-	public IIpv4Address ensureIpv4Address(int intIpv4Address) {
-		IIpv4Address ipv4Vertex = searchIpv4Address(intIpv4Address);
-		if (ipv4Vertex == null) {
-			ipv4Vertex = newIpv4Address();
-			ipv4Vertex.setIpv4Address(intIpv4Address);
-		}
-		return ipv4Vertex;
-	}
-
-	public void removeIpv4Address(IIpv4Address ipv4Address) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		fg.removeVertex(ipv4Address.asVertex());
-	}
-
-	/**
-	 * Create and return a flow path object.
-	 */
-	@Override
-	public IFlowPath newFlowPath() {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		IFlowPath flowPath = fg.addVertex(null, IFlowPath.class);
-		if (flowPath != null) flowPath.setType("flow");
-		return flowPath;
-	}
-
-	/**
-	 * Search and get a flow path object with specified flow ID.
-	 * @param flowId flow ID to search
-	 */
-	@Override
-	public IFlowPath searchFlowPath(FlowId flowId) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		if ( fg == null ) return null;
-		Iterator<IFlowPath> flowpaths = fg.getVertices("flow_id", flowId.toString(), IFlowPath.class).iterator();
-		if ( flowpaths.hasNext() ) {
-			return flowpaths.next();
-		} else {
-			return null;
-		}
-	}
-
-	/**
-	 * Get a flow path object with a flow entry.
-	 * @param flowEntry flow entry object
-	 */
-	@Override
-	public IFlowPath getFlowPathByFlowEntry(IFlowEntry flowEntry) {
-		GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
-		pipe.start(flowEntry.asVertex()).out("flow");
-		FramedVertexIterable<IFlowPath> r = new FramedVertexIterable<IFlowPath>(conn.getFramedGraph(),
-				pipe, IFlowPath.class);
-		return r.iterator().hasNext() ? r.iterator().next() : null;
-	}
-
-	/**
-	 * Get all flow path objects.
-	 */
-	@Override
-	public Iterable<IFlowPath> getAllFlowPaths() {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		Iterable<IFlowPath> flowPaths = fg.getVertices("type", "flow", IFlowPath.class);
-
-		List<IFlowPath> nonNullFlows = new ArrayList<IFlowPath>();
-
-		for (IFlowPath fp: flowPaths) {
-			if (fp.getFlowId() != null) {
-				nonNullFlows.add(fp);
-			}
-		}
-		return nonNullFlows;
-	}
-
-    /**
-     * Remove the specified flow path.
-     * @param flowPath flow path object to remove
-     */
-	@Override
-	public void removeFlowPath(IFlowPath flowPath) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		fg.removeVertex(flowPath.asVertex());
-	}
-
-	/**
-	 * Create and return a flow entry object.
-	 */
-	@Override
-	public IFlowEntry newFlowEntry() {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		IFlowEntry flowEntry = fg.addVertex(null, IFlowEntry.class);
-		if (flowEntry != null) flowEntry.setType("flow_entry");
-		return flowEntry;
-	}
-
-	/**
-	 * Search and get a flow entry object with flow entry ID.
-	 * @param flowEntryId flow entry ID to search
-	 */
-	@Override
-	public IFlowEntry searchFlowEntry(FlowEntryId flowEntryId) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		if ( fg == null ) return null;
-		Iterator<IFlowEntry> flowentries = fg.getVertices("flow_entry_id", flowEntryId.toString(), IFlowEntry.class).iterator();
-		if ( flowentries.hasNext() ) {
-			return flowentries.next();
-		} else {
-			return null;
-		}
-	}
-
-	/**
-	 * Get all flow entry objects.
-	 */
-	@Override
-	public Iterable<IFlowEntry> getAllFlowEntries() {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-
-		return fg.getVertices("type", "flow_entry", IFlowEntry.class);
-	}
-
-	/**
-	 * Remove the specified flow entry.
-	 * @param flowEntry flow entry object to remove
-	 */
-	@Override
-	public void removeFlowEntry(IFlowEntry flowEntry) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		fg.removeVertex(flowEntry.asVertex());
-	}
-
-	/**
-	 * Get the instance of GraphDBConnection assigned to this class.
-	 */
-	@Override
-	public IDBConnection getDBConnection() {
-		return conn;
-	}
-
-	/**
-	 * Commit changes for the graph.
-	 */
-	@Override
-	public void commit() {
-		conn.commit();
-	}
-
-	/**
-	 * Rollback changes for the graph.
-	 */
-	@Override
-	public void rollback() {
-		conn.rollback();
-	}
-
-	/**
-	 * Close the connection of the assigned GraphDBConnection.
-	 */
-	@Override
-	public void close() {
-		conn.close();
-	}
-
-
-}
diff --git a/src/main/java/net/onrc/onos/graph/IDBConnection.java b/src/main/java/net/onrc/onos/graph/IDBConnection.java
index 82ebba2..cd65ec0 100644
--- a/src/main/java/net/onrc/onos/graph/IDBConnection.java
+++ b/src/main/java/net/onrc/onos/graph/IDBConnection.java
@@ -1,13 +1,12 @@
 package net.onrc.onos.graph;
 
-import com.thinkaurelius.titan.core.TitanGraph;
 import com.tinkerpop.frames.FramedGraph;
 
 public interface IDBConnection {
-	public FramedGraph<TitanGraph> getFramedGraph();
-	public void addEventListener(final LocalGraphChangedListener listener);
-	public Boolean isValid();
-	public void commit();
-	public void rollback();
-	public void close();
+    public FramedGraph getFramedGraph();
+    public void addEventListener(final LocalGraphChangedListener listener);
+    public Boolean isValid();
+    public void commit();
+    public void rollback();
+    public void close();
 }
diff --git a/src/main/java/net/onrc/onos/graph/IDBOperation.java b/src/main/java/net/onrc/onos/graph/IDBOperation.java
index 33d01fb..d2e8109 100644
--- a/src/main/java/net/onrc/onos/graph/IDBOperation.java
+++ b/src/main/java/net/onrc/onos/graph/IDBOperation.java
@@ -1,5 +1,9 @@
 package net.onrc.onos.graph;
 
+import java.util.Map;
+
+import com.tinkerpop.blueprints.Vertex;
+
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
@@ -10,7 +14,7 @@
 
 public interface IDBOperation {
 	public static final String PORT_ID_DELIM = "@";
-	
+
 	public ISwitchObject newSwitch(String dpid);
 	public ISwitchObject searchSwitch(String dpid);
 	public ISwitchObject searchActiveSwitch(String dpid);
@@ -19,13 +23,13 @@
 	public Iterable<ISwitchObject> getInactiveSwitches();
 	public Iterable<IFlowEntry> getAllSwitchNotUpdatedFlowEntries();
 	public void removeSwitch(ISwitchObject sw);
-	
+
 	@Deprecated
 	public IPortObject newPort(Short portNumber);
 	public IPortObject newPort(String dpid, Short portNum);
 	public IPortObject searchPort(String dpid, Short number);
 	public void removePort(IPortObject port);
-	
+
 	public IDeviceObject newDevice();
 	public IDeviceObject searchDevice(String macAddr);
 	public Iterable<IDeviceObject> getDevices();
@@ -41,10 +45,13 @@
 	public IFlowEntry searchFlowEntry(FlowEntryId flowEntryId);
 	public Iterable<IFlowEntry> getAllFlowEntries();
 	public void removeFlowEntry(IFlowEntry flowEntry);
-	
-	public IDBConnection getDBConnection();	
+
+	public void setVertexProperties(Vertex vertex, Map<String, Object> map);
+
+	public IDBConnection getDBConnection();
 	public void commit();
 	public void rollback();
 	public void close();
-	Iterable<IPortObject> getAllPorts();
+
+	public Iterable<IPortObject> getAllPorts();
 }
diff --git a/src/main/java/net/onrc/onos/graph/LocalTopologyEventListener.java b/src/main/java/net/onrc/onos/graph/LocalTopologyEventListener.java
index c005304..27de2c0 100644
--- a/src/main/java/net/onrc/onos/graph/LocalTopologyEventListener.java
+++ b/src/main/java/net/onrc/onos/graph/LocalTopologyEventListener.java
@@ -11,13 +11,15 @@
 import com.tinkerpop.blueprints.Direction;
 import com.tinkerpop.blueprints.Edge;
 import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.blueprints.impls.ramcloud.*;
+import java.util.Map;
 
 public class LocalTopologyEventListener implements LocalGraphChangedListener {
 	
 	protected final static Logger log = LoggerFactory.getLogger(LocalTopologyEventListener.class);
-	protected static GraphDBConnection conn;
+	protected static DBConnection conn;
 	
-	public LocalTopologyEventListener(GraphDBConnection conn) {
+	public LocalTopologyEventListener(DBConnection conn) {
 		LocalTopologyEventListener.conn = conn;		
 	}
 
@@ -45,9 +47,9 @@
 		String label = edge.getLabel();
 		if (label.equals("link")) {
 			Vertex v = edge.getVertex(Direction.IN);
-			IPortObject src_port = conn.getFramedGraph().frame(v, IPortObject.class);
+			IPortObject src_port = (IPortObject) conn.getFramedGraph().frame(v, IPortObject.class);
 			v = edge.getVertex(Direction.OUT);
-			IPortObject dest_port = conn.getFramedGraph().frame(v, IPortObject.class);
+			IPortObject dest_port = (IPortObject) conn.getFramedGraph().frame(v, IPortObject.class);
 
 			log.debug("TopologyEvents: link broken {}", new Object []{src_port.getSwitch().getDPID(),
 																src_port.getNumber(),
@@ -84,7 +86,7 @@
 		if (type.equals("port")) {
 			// port is removed...lets fire reconcile here directly for now
 			
-			IPortObject src_port = conn.getFramedGraph().frame(vertex, IPortObject.class);
+			IPortObject src_port = (IPortObject) conn.getFramedGraph().frame(vertex, IPortObject.class);
 			log.debug("TopologyEvents: Port removed: {}:{}",src_port.getSwitch().getDPID(),src_port.getNumber());
 
 			// NOTE: Old code/logic.
@@ -109,4 +111,11 @@
 		
 	}
 
+	public void vertexRemoved(Vertex vertex, Map<String, Object> props) {
+		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+	}
+
+	public void edgeRemoved(Edge edge, Map<String, Object> props) {
+		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+	}
 }
diff --git a/src/main/java/net/onrc/onos/graph/RamCloudDBConnection.java b/src/main/java/net/onrc/onos/graph/RamCloudDBConnection.java
new file mode 100644
index 0000000..17067b4
--- /dev/null
+++ b/src/main/java/net/onrc/onos/graph/RamCloudDBConnection.java
@@ -0,0 +1,130 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package net.onrc.onos.graph;
+
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraph;
+import com.tinkerpop.frames.FramedGraph;
+import java.io.File;
+import java.util.Set;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author nickkaranatsios
+ */
+public class RamCloudDBConnection extends DBConnection {
+    private RamCloudGraph graph;
+    private FramedGraph<RamCloudGraph> fg;
+    private static Logger log = LoggerFactory.getLogger(RamCloudDBConnection.class);
+    
+    //private static final ThreadLocal<RamCloudGraph> RamCloudThreadLocal = new ThreadLocal<RamCloudGraph>();
+
+    public RamCloudDBConnection(final String dbConfigFile) {
+        //final String coordinatorURL = open(getConfiguration(new File(dbConfigFile)));
+	//System.out.println("coordinatorURL "+ coordinatorURL);
+        //graph = new RamCloudGraph(coordinatorURL);
+	//graph = RamCloudThreadLocal.get();
+	//System.out.println("ThreadId = " + Thread.currentThread().getId() + " graph = " + graph);
+	graph = new RamCloudGraph("fast+udp:host=10.0.0.144,port=12246");
+	Set<String> s = graph.getIndexedKeys(Vertex.class);
+        if (!s.contains("dpid")) {
+            graph.createKeyIndex("dpid", Vertex.class);
+        }
+        if (!s.contains("port_id")) {
+            graph.createKeyIndex("port_id", Vertex.class);
+        }
+        if (!s.contains("type")) {
+            graph.createKeyIndex("type", Vertex.class);
+        }
+        if (!s.contains("dl_addr")) {
+            graph.createKeyIndex("dl_addr", Vertex.class);
+        }
+        if (!s.contains("flow_id")) {
+            graph.createKeyIndex("flow_id", Vertex.class);
+        }
+        if (!s.contains("flow_entry_id")) {
+            graph.createKeyIndex("flow_entry_id", Vertex.class);
+        }
+        if (!s.contains("switch_state")) {
+            graph.createKeyIndex("switch_state", Vertex.class);
+	}
+	if (!s.contains("ipv4_address")) {
+	    graph.createKeyIndex("ipv4_address", Vertex.class);
+	}
+        fg = new FramedGraph<RamCloudGraph>(graph);
+    }
+    
+    @Override
+    public FramedGraph getFramedGraph() {
+        if (isValid()) {
+            return fg;
+        } else {
+            log.error("new FramedGraph failed");
+            return null;
+        }
+    }
+
+    @Override
+    public void addEventListener(LocalGraphChangedListener listener) {
+        //TO-DO
+    }
+
+    @Override
+    public Boolean isValid() {
+        return (graph != null);
+    }
+
+    @Override
+    public void commit() {
+        try {
+            graph.commit();
+        } catch (Exception e) {
+            log.error("{}", e.toString());
+        }
+    }
+
+    @Override
+    public void rollback() {
+        try {
+            graph.rollback();
+        } catch (Exception e) {
+            log.error("{}", e.toString());
+        }
+    }
+
+    @Override
+    public void close() {
+        commit();
+    }
+    
+     private static final Configuration getConfiguration(final File dirOrFile) {
+        if (dirOrFile == null) {
+            throw new IllegalArgumentException("Need to specify a configuration file or storage directory");
+        }
+
+        if (!dirOrFile.isFile()) {
+            throw new IllegalArgumentException("Location of configuration must be a file");
+        }
+
+        try {
+            return new PropertiesConfiguration(dirOrFile);
+        } catch (ConfigurationException e) {
+            throw new IllegalArgumentException("Could not load configuration at: " + dirOrFile, e);
+        }
+    }
+     
+     private String open(final Configuration configuration) {
+         final String coordinatorURL = configuration.getString("ramcloud.coordinator", null);
+         if (coordinatorURL == null) {
+             throw new RuntimeException("Configuration must contain a valid 'coordinatorURL' setting");
+         }
+         return coordinatorURL;
+     }
+}
diff --git a/src/main/java/net/onrc/onos/graph/RamCloudDBOperation.java b/src/main/java/net/onrc/onos/graph/RamCloudDBOperation.java
new file mode 100644
index 0000000..1487be7
--- /dev/null
+++ b/src/main/java/net/onrc/onos/graph/RamCloudDBOperation.java
@@ -0,0 +1,27 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package net.onrc.onos.graph;
+
+import com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraph;
+import com.tinkerpop.frames.FramedGraph;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.util.FlowEntryId;
+import net.onrc.onos.ofcontroller.util.FlowId;
+import org.apache.commons.configuration.Configuration;
+
+/**
+ *
+ * @author nickkaranatsios
+ */
+public class RamCloudDBOperation extends DBOperation {
+
+    public RamCloudDBOperation() {
+    }
+}
diff --git a/src/main/java/net/onrc/onos/graph/TitanDBConnection.java b/src/main/java/net/onrc/onos/graph/TitanDBConnection.java
new file mode 100644
index 0000000..f46e417
--- /dev/null
+++ b/src/main/java/net/onrc/onos/graph/TitanDBConnection.java
@@ -0,0 +1,122 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package net.onrc.onos.graph;
+
+import com.thinkaurelius.titan.core.TitanFactory;
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.tinkerpop.blueprints.TransactionalGraph;
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.blueprints.util.wrappers.event.EventTransactionalGraph;
+import com.tinkerpop.frames.FramedGraph;
+import java.util.Set;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author nickkaranatsios
+ */
+public class TitanDBConnection extends DBConnection {
+
+    private TitanGraph graph;
+    private static Logger log = LoggerFactory.getLogger(TitanDBConnection.class);
+    private EventTransactionalGraph<TitanGraph> eg;
+
+    public TitanDBConnection(final String dbConfigFile) {
+        graph = TitanFactory.open(dbConfigFile);
+        Set<String> s = graph.getIndexedKeys(Vertex.class);
+        if (!s.contains("dpid")) {
+            graph.createKeyIndex("dpid", Vertex.class);
+        }
+        if (!s.contains("port_id")) {
+            graph.createKeyIndex("port_id", Vertex.class);
+        }
+        if (!s.contains("type")) {
+            graph.createKeyIndex("type", Vertex.class);
+        }
+        if (!s.contains("dl_addr")) {
+            graph.createKeyIndex("dl_addr", Vertex.class);
+        }
+        if (!s.contains("flow_id")) {
+            graph.createKeyIndex("flow_id", Vertex.class);
+        }
+        if (!s.contains("flow_entry_id")) {
+            graph.createKeyIndex("flow_entry_id", Vertex.class);
+        }
+        if (!s.contains("switch_state")) {
+            graph.createKeyIndex("switch_state", Vertex.class);
+        }
+        graph.commit();
+        eg = new EventTransactionalGraph<TitanGraph>(graph);
+    }
+
+    class TransactionHandle {
+
+        protected TransactionalGraph tr;
+
+        public void create() {
+            tr = graph.newTransaction();
+        }
+    }
+
+    @Override
+    public FramedGraph getFramedGraph() {
+        if (isValid()) {
+            FramedGraph<TitanGraph> fg = new FramedGraph<TitanGraph>(graph);
+            return fg;
+        } else {
+            log.error("new FramedGraph failed");
+            return null;
+        }
+    }
+
+    @Override
+    public void addEventListener(LocalGraphChangedListener listener) {
+        EventTransactionalGraph<TitanGraph> eg = this.getEventGraph();
+        eg.addListener(listener);
+        log.debug("Registered listener {}", listener.getClass());
+    }
+
+    @Override
+    public Boolean isValid() {
+        return (graph != null || graph.isOpen());
+    }
+
+    @Override
+    public void commit() {
+        try {
+            graph.commit();
+        } catch (Exception e) {
+            log.error("{}", e.toString());
+        }
+    }
+
+    @Override
+    public void rollback() {
+        try {
+            graph.rollback();
+        } catch (Exception e) {
+            log.error("{}", e.toString());
+        }
+    }
+
+    @Override
+    public void close() {
+        commit();
+    }
+
+    /**
+     * Get EventTransactionalGraph of the titan graph.
+     *
+     * @return EventTransactionalGraph of the titan graph
+     */
+    private EventTransactionalGraph<TitanGraph> getEventGraph() {
+        if (isValid()) {
+            return eg;
+        } else {
+            return null;
+        }
+    }
+}
diff --git a/src/main/java/net/onrc/onos/graph/TitanDBOperation.java b/src/main/java/net/onrc/onos/graph/TitanDBOperation.java
new file mode 100644
index 0000000..1b211d6
--- /dev/null
+++ b/src/main/java/net/onrc/onos/graph/TitanDBOperation.java
@@ -0,0 +1,26 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package net.onrc.onos.graph;
+
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.frames.FramedGraph;
+import com.tinkerpop.frames.structures.FramedVertexIterable;
+import com.tinkerpop.gremlin.java.GremlinPipeline;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.*;
+import net.onrc.onos.ofcontroller.core.ISwitchStorage;
+import net.onrc.onos.ofcontroller.util.FlowEntryId;
+import net.onrc.onos.ofcontroller.util.FlowId;
+
+/**
+ *
+ * @author nickkaranatsios
+ */
+public class TitanDBOperation extends DBOperation {
+
+}
\ No newline at end of file
diff --git a/src/main/java/net/onrc/onos/graph/web/TopoDevicesResource.java b/src/main/java/net/onrc/onos/graph/web/TopoDevicesResource.java
index 18c1069..10e250e 100644
--- a/src/main/java/net/onrc/onos/graph/web/TopoDevicesResource.java
+++ b/src/main/java/net/onrc/onos/graph/web/TopoDevicesResource.java
@@ -2,7 +2,8 @@
 
 import java.util.Iterator;
 
-import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.graph.DBOperation;
+import net.onrc.onos.graph.GraphDBManager;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
 
 import org.restlet.resource.Get;
@@ -12,7 +13,7 @@
 	
 	@Get("json")
 	public Iterator<IDeviceObject> retrieve() {
-		GraphDBOperation op = new GraphDBOperation("");
+		DBOperation op = GraphDBManager.getDBOperation("ramcloud", "/tmp/ramcloudconf");
 		
 		return op.getDevices().iterator();
 	}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
index 33280a6..3ff6058 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
@@ -280,7 +280,7 @@
 		ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
 		topologyChangeDetectorTask = new SingletonTask(executor, new TopologyChangeDetector());
 
-		topologyNetService = new TopologyManager("");
+		topologyNetService = new TopologyManager(context);
 		
 		pathsWaitingOnArp = new HashMap<InetAddress, Path>();
 		prefixesWaitingOnArp = Multimaps.synchronizedSetMultimap(
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/ILinkStorage.java b/src/main/java/net/onrc/onos/ofcontroller/core/ILinkStorage.java
index 8889092..6b285f4 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/ILinkStorage.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/ILinkStorage.java
@@ -10,7 +10,7 @@
     /*
 	 * Init with Storage conf
 	 */
-	public void init(String conf);
+	public void init(final String dbStore, final String conf);
 	
 	/*
 	 * Generic operation method
@@ -60,7 +60,8 @@
 	 * @param dpid DPID of desired switch.
 	 * @return List of reverse links. Empty list if no port was found.
 	 */
-	public List<Link> getReverseLinks(String dpid);
+
+        public List<Link> getReverseLinks(String dpid);
 
 	public List<Link> getActiveLinks();
 
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/INetMapStorage.java b/src/main/java/net/onrc/onos/ofcontroller/core/INetMapStorage.java
index b052540..2cf0e18 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/INetMapStorage.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/INetMapStorage.java
@@ -14,6 +14,6 @@
 		DELETE, // Delete the object
 		UPDATE  // Update the object if exists or CREATE/INSERT if does not exist
 	}
-	public void init(String conf);
+	public void init(final String dbStore, final String conf);
 	public void close();
 }
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/ISwitchStorage.java b/src/main/java/net/onrc/onos/ofcontroller/core/ISwitchStorage.java
index 2cfab3f..8dd2f16 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/ISwitchStorage.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/ISwitchStorage.java
@@ -16,7 +16,8 @@
 	/*
 	 * Initialize
 	 */
-	public void init(String conf);
+	public void init(final String dbStore, final String conf);
+
 	/*
 	 * Update the switch details
 	 */
@@ -39,7 +40,7 @@
 	public boolean deactivateSwitch(String dpid);
 	/*
 	 * Update the port details
-	 */
+	 */	
 	public boolean updatePort(String dpid, short port, int state, String desc);
 	/*
 	 * Associate a port on switch
@@ -49,7 +50,6 @@
 	 * Delete a port on a switch by num
 	 */
 	public boolean deletePort(String dpid, short port);
-
 	/**
 	 * Get list of all ports on the switch specified by given DPID.
 	 *
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/internal/DeviceStorageImpl.java b/src/main/java/net/onrc/onos/ofcontroller/core/internal/DeviceStorageImpl.java
index c830d44..ddc7527 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/internal/DeviceStorageImpl.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/internal/DeviceStorageImpl.java
@@ -7,7 +7,8 @@
 
 import net.floodlightcontroller.devicemanager.IDevice;
 import net.floodlightcontroller.devicemanager.SwitchPort;
-import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.graph.DBOperation;
+import net.onrc.onos.graph.GraphDBManager;
 import net.onrc.onos.ofcontroller.core.IDeviceStorage;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IIpv4Address;
@@ -22,26 +23,26 @@
 import com.google.common.collect.Lists;
 import com.google.common.net.InetAddresses;
 import com.thinkaurelius.titan.core.TitanException;
-
 /**
  * This is the class for storing the information of devices into CassandraDB
+ *
  * @author Pankaj
  */
 public class DeviceStorageImpl implements IDeviceStorage {
 	protected final static Logger log = LoggerFactory.getLogger(DeviceStorageImpl.class);
 
-	private GraphDBOperation ope;
-
+	private DBOperation ope;
 	/***
 	 * Initialize function. Before you use this class, please call this method
 	 * @param conf configuration file for Cassandra DB
 	 */
 	@Override
-	public void init(String conf) {
+	public void init(final String dbStore, final String conf) {
 		try {
-			ope = new GraphDBOperation(conf);
-		} catch (TitanException e) {
-			log.error("Couldn't open graph operation", e);
+			ope = GraphDBManager.getDBOperation("ramcloud", "/tmp/ramcloudconf");
+			//ope = GraphDBManager.getDBOperation(dbStore, conf);
+		} catch (Exception e) {
+			log.error(e.getMessage());
 		}
 	}
 
@@ -107,7 +108,6 @@
 
 		return obj;
 	}
-
 	/***
 	 * This function is for updating the Device properties.
 	 * @param device The device you want to add into the DB.
@@ -153,7 +153,6 @@
 
 		ope.removeDevice(deviceObject);
 	}
-
 	/***
 	 * This function is for getting the Device from the DB by Mac address of the device.
 	 * @param mac The device mac address you want to get from the DB.
@@ -161,7 +160,7 @@
 	 */
 	@Override
 	public IDeviceObject getDeviceByMac(String mac) {
-		return ope.searchDevice(mac);
+	    return ope.searchDevice(mac);
 	}
 
 	/***
@@ -191,15 +190,15 @@
 	@Override
 	public void changeDeviceAttachments(IDevice device) {
 		IDeviceObject obj = null;
- 		try {
-            if ((obj = ope.searchDevice(device.getMACAddressString())) != null) {
-                log.debug("Changing device ports {}: found existing device", device.getMACAddressString());
-                changeDeviceAttachments(device, obj);
-                ope.commit();
-            } else {
-   				log.debug("failed to search device...now adding {}", device.getMACAddressString());
-   				addDevice(device);
-            }
+		try {
+			if ((obj = ope.searchDevice(device.getMACAddressString())) != null) {
+				log.debug("Changing device ports {}: found existing device", device.getMACAddressString());
+				changeDeviceAttachments(device, obj);
+				ope.commit();
+			} else {
+				log.debug("failed to search device...now adding {}", device.getMACAddressString());
+				addDevice(device);
+			}
 		} catch (TitanException e) {
 			ope.rollback();
 			log.error(":addDevice mac:{} failed", device.getMACAddressString());
@@ -260,16 +259,15 @@
 		log.debug("Changing IP address for {} to {}", device.getMACAddressString(),
 				device.getIPv4Addresses());
 		IDeviceObject obj;
-  		try {
-  			if ((obj = ope.searchDevice(device.getMACAddressString())) != null) {
-  				changeDeviceIpv4Addresses(device, obj);
-
-              	ope.commit();
-  			} else {
-            	log.error(":changeDeviceIPv4Address mac:{} failed", device.getMACAddressString());
-            }
-  		} catch (TitanException e) {
-  			ope.rollback();
+		try {
+			if ((obj = ope.searchDevice(device.getMACAddressString())) != null) {
+				changeDeviceIpv4Addresses(device, obj);
+				ope.commit();
+			} else {
+				log.error(":changeDeviceIPv4Address mac:{} failed", device.getMACAddressString());
+			}
+		} catch (TitanException e) {
+			ope.rollback();
 			log.error(":changeDeviceIPv4Address mac:{} failed due to exception {}", device.getMACAddressString(), e);
 		}
 	}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImpl.java b/src/main/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImpl.java
index 16220b9..37ab9fb 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImpl.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImpl.java
@@ -4,7 +4,7 @@
 import java.util.List;
 
 import net.floodlightcontroller.routing.Link;
-import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.graph.DBOperation;
 import net.onrc.onos.ofcontroller.core.ILinkStorage;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
@@ -15,22 +15,27 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.tinkerpop.blueprints.impls.ramcloud.PerfMon;
+import net.onrc.onos.graph.GraphDBManager;
+
 /**
  * This is the class for storing the information of links into GraphDB
  */
 public class LinkStorageImpl implements ILinkStorage {
 
 	protected final static Logger log = LoggerFactory.getLogger(LinkStorageImpl.class);
-	protected GraphDBOperation op;
-
+	protected DBOperation dbop;
+	private static PerfMon pm = PerfMon.getInstance();
 
 	/**
 	 * Initialize the object. Open LinkStorage using given configuration file.
 	 * @param conf Path (absolute path for now) to configuration file.
 	 */
 	@Override
-	public void init(String conf) {
-		this.op = new GraphDBOperation(conf);
+	public void init(final String dbStore, final String conf) {
+		//this.dbop = GraphDBManager.getDBOperation(dbStore, conf);
+		this.dbop = GraphDBManager.getDBOperation("ramcloud", "/tmp/ramcloudconf");
+
 	}
 
 	// Method designing policy:
@@ -56,11 +61,11 @@
 			if (link != null) {
 				try {
 					if (addLinkImpl(link)) {
-						op.commit();
+						dbop.commit();
 						success = true;
 					}
 				} catch (Exception e) {
-					op.rollback();
+					dbop.rollback();
 					e.printStackTrace();
 		        	log.error("LinkStorageImpl:update {} link:{} failed", dmop, link);
 				}
@@ -70,11 +75,11 @@
 			if (link != null && linkinfo != null) {
 				try {
 					if (setLinkInfoImpl(link, linkinfo)) {
-						op.commit();
+						dbop.commit();
 						success = true;
 					}
 				} catch (Exception e) {
-					op.rollback();
+					dbop.rollback();
 					e.printStackTrace();
 		        	log.error("LinkStorageImpl:update {} link:{} failed", dmop, link);
 				}
@@ -84,15 +89,15 @@
 			if (link != null) {
 				try {
 					if (deleteLinkImpl(link)) {
-						op.commit();
+						dbop.commit();
 						success = true;
 		            	log.debug("LinkStorageImpl:update {} link:{} succeeded", dmop, link);
 		            } else {
-						op.rollback();
+						dbop.rollback();
 		            	log.debug("LinkStorageImpl:update {} link:{} failed", dmop, link);
 					}
 				} catch (Exception e) {
-					op.rollback();
+					dbop.rollback();
 					e.printStackTrace();
 					log.error("LinkStorageImpl:update {} link:{} failed", dmop, link);
 				}
@@ -110,7 +115,7 @@
 
 	private void deleteDeviceOnPort(Long dpid, Short number)
 	{
-		IPortObject srcPortObject = op.searchPort(HexString.toHexString(dpid), number);
+		IPortObject srcPortObject = dbop.searchPort(HexString.toHexString(dpid), number);
 		if (srcPortObject == null)
 		    return;
 		Iterable<IDeviceObject> devices = srcPortObject.getDevices();
@@ -135,22 +140,25 @@
 			deleteDeviceOnPort(link.getSrc(),link.getSrcPort());
 			deleteDeviceOnPort(link.getDst(),link.getDstPort());
 
+			pm.addlink_start();
 			if (addLinkImpl(link)) {
 				// Set LinkInfo only if linfo is non-null.
 				if (linfo != null && (! setLinkInfoImpl(link, linfo))) {
 					log.debug("Adding linkinfo failed: {}", link);
-					op.rollback();
+					dbop.rollback();
 				}
-				op.commit();
+				dbop.commit();
+				pm.addlink_end();
 				success = true;
 			} else {
+				pm.addlink_end();
 				// If we fail here that's because the ports aren't added
 				// before we try to add the link
 				log.debug("Adding link failed: {}", link);
-				op.rollback();
+				dbop.rollback();
 			}
 		} catch (Exception e) {
-			op.rollback();
+			dbop.rollback();
 			e.printStackTrace();
 			log.error("LinkStorageImpl:addLink link:{} linfo:{} failed", link, linfo);
 		}
@@ -174,10 +182,10 @@
 		}
 
 		try {
-			op.commit();
+			dbop.commit();
 			success = true;
 		} catch (Exception e) {
-			op.rollback();
+			dbop.rollback();
 			e.printStackTrace();
 			log.error("LinkStorageImpl:addLinks link:s{} failed", links);
 		}
@@ -197,15 +205,15 @@
 
         try {
          	if (deleteLinkImpl(lt)) {
-        		op.commit();
+        		dbop.commit();
         		success = true;
             	log.debug("LinkStorageImpl:deleteLink(): deleted edges {}", lt);
             } else {
-            	op.rollback();
+            	dbop.rollback();
             	log.error("LinkStorageImpl:deleteLink(): failed invalid vertices {}", lt);
             }
         } catch (Exception e) {
-        	op.rollback();
+        	dbop.rollback();
         	log.error("LinkStorageImpl:deleteLink(): failed {} {}",
         			new Object[]{lt, e.toString()});
         	e.printStackTrace();
@@ -225,14 +233,14 @@
 		try {
 			for (Link lt : links) {
 				if (! deleteLinkImpl(lt)) {
-					op.rollback();
+					dbop.rollback();
 					return false;
 				}
 			}
-			op.commit();
+			dbop.commit();
 			success = true;
 		} catch (Exception e) {
-        	op.rollback();
+        	dbop.rollback();
 			e.printStackTrace();
         	log.error("LinkStorageImpl:deleteLinks failed invalid vertices {}", links);
 		}
@@ -249,8 +257,7 @@
 	@Override
 	public List<Link> getLinks(Long dpid, short port) {
 	    List<Link> links = new ArrayList<Link>();
-
-	    IPortObject srcPort = op.searchPort(HexString.toHexString(dpid), port);
+	    IPortObject srcPort = dbop.searchPort(HexString.toHexString(dpid), port);
 	    if (srcPort == null)
 		return links;
 	    ISwitchObject srcSw = srcPort.getSwitch();
@@ -279,7 +286,7 @@
 	public List<Link> getReverseLinks(Long dpid, short port) {
 	    List<Link> links = new ArrayList<Link>();
 
-	    IPortObject srcPort = op.searchPort(HexString.toHexString(dpid), port);
+	    IPortObject srcPort = dbop.searchPort(HexString.toHexString(dpid), port);
 	    if (srcPort == null)
 		return links;
 	    ISwitchObject srcSw = srcPort.getSwitch();
@@ -311,15 +318,15 @@
 		try {
 			for(Link l : linksToDelete) {
 				if (! deleteLinkImpl(l)) {
-					op.rollback();
+					dbop.rollback();
 					log.error("LinkStorageImpl:deleteLinksOnPort dpid:{} port:{} failed", dpid, port);
 					return false;
 				}
 			}
-			op.commit();
+			dbop.commit();
 			success = true;
 		} catch (Exception e) {
-        	op.rollback();
+        	dbop.rollback();
 			e.printStackTrace();
         	log.error("LinkStorageImpl:deleteLinksOnPort dpid:{} port:{} failed", dpid, port);
 		}
@@ -335,8 +342,7 @@
 	@Override
 	public List<Link> getLinks(String dpid) {
 		List<Link> links = new ArrayList<Link>();
-
-		ISwitchObject srcSw = op.searchSwitch(dpid);
+		ISwitchObject srcSw = dbop.searchSwitch(dpid);
 
 		if(srcSw != null) {
 			for(IPortObject srcPort : srcSw.getPorts()) {
@@ -366,7 +372,7 @@
 	public List<Link> getReverseLinks(String dpid) {
 		List<Link> links = new ArrayList<Link>();
 
-		ISwitchObject srcSw = op.searchSwitch(dpid);
+		ISwitchObject srcSw = dbop.searchSwitch(dpid);
 
 		if(srcSw != null) {
 			for(IPortObject srcPort : srcSw.getPorts()) {
@@ -394,7 +400,7 @@
 	 */
 	@Override
 	public List<Link> getActiveLinks() {
-		Iterable<ISwitchObject> switches = op.getActiveSwitches();
+		Iterable<ISwitchObject> switches = dbop.getActiveSwitches();
 
 		List<Link> links = new ArrayList<Link>();
 
@@ -458,17 +464,22 @@
 		// get source port vertex
 		String dpid = HexString.toHexString(lt.getSrc());
 		short port = lt.getSrcPort();
-		vportSrc = op.searchPort(dpid, port);
+		log.debug("addLinkImpl Src dpid : {} port : {}", dpid, port);
+		vportSrc = dbop.searchPort(dpid, port);
 
 		// get dest port vertex
 		dpid = HexString.toHexString(lt.getDst());
 		port = lt.getDstPort();
-		vportDst = op.searchPort(dpid, port);
+		log.debug("addLinkImpl Dst dpid : {} port : {}", dpid, port);
+		vportDst = dbop.searchPort(dpid, port);
+
+		log.debug("addLinkImpl vportSrc : {} vportDst : {}", vportSrc, vportDst);
 
 		if (vportSrc != null && vportDst != null) {
 			IPortObject portExist = null;
 			// check if the link exists
 			for (IPortObject V : vportSrc.getLinkedPorts()) {
+			        log.debug("vportSrc.getLinkedPorts() :{}", V);
 				if (V.equals(vportDst)) {
 					portExist = V;
 					break;
@@ -479,8 +490,8 @@
 				vportSrc.setLinkPort(vportDst);
 				success = true;
 			} else {
-				log.debug("LinkStorageImpl:addLinkImpl failed link exists {} {} src {} dst {}",
-						new Object[]{op, lt, vportSrc, vportDst});
+				log.error("LinkStorageImpl:addLinkImpl failed link exists {} {} src {} dst {}",
+						new Object[]{dbop, lt, vportSrc, vportDst});
 			}
 		} else {
 			log.error("Ports not found : {}", lt);
@@ -496,12 +507,12 @@
 	    // get source port vertex
 	 	String dpid = HexString.toHexString(lt.getSrc());
 	 	short port = lt.getSrcPort();
-	 	vportSrc = op.searchPort(dpid, port);
+	 	vportSrc = dbop.searchPort(dpid, port);
 
 	    // get dst port vertex
 	 	dpid = HexString.toHexString(lt.getDst());
 	 	port = lt.getDstPort();
-	 	vportDst = op.searchPort(dpid, port);
+	 	vportDst = dbop.searchPort(dpid, port);
 
 		// FIXME: This needs to remove all edges
 		if (vportSrc != null && vportDst != null) {
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImpl.java b/src/main/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImpl.java
index 9963887..0dcf4297 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImpl.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImpl.java
@@ -3,9 +3,12 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import com.tinkerpop.blueprints.impls.ramcloud.PerfMon;
+
 import net.floodlightcontroller.core.IOFSwitch;
-import net.onrc.onos.graph.GraphDBConnection;
-import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.graph.DBOperation;
+import net.onrc.onos.graph.GraphDBManager;
+import net.onrc.onos.ofcontroller.core.ISwitchStorage;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
@@ -21,19 +24,25 @@
  * This is the class for storing the information of switches into GraphDB
  */
 public class SwitchStorageImpl implements ISwitchStorage {
-	protected GraphDBOperation op;
+
+	protected DBOperation op;
 	protected final static Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
+	public final long measureONOSTimeProp = Long.valueOf(System.getProperty("benchmark.measureONOS", "0"));
+	public final long measureAllTimeProp = Long.valueOf(System.getProperty("benchmark.measureAll", "0"));
+
+	private static PerfMon pm = PerfMon.getInstance();
 
 	/***
 	 * Initialize function. Before you use this class, please call this method
 	 * @param conf configuration file for Cassandra DB
 	 */
 	@Override
-	public void init(String conf) {
-		GraphDBConnection conn = GraphDBConnection.getInstance(conf);
-		op = new GraphDBOperation(conn);
+	public void init(final String dbStore, final String conf) {
+		op = GraphDBManager.getDBOperation("ramcloud", "/tmp/ramcloudconf");
+		//op = GraphDBManager.getDBOperation(dbStore, conf);
 	}
 
+
 	/***
 	 * Finalize/close function. After you use this class, please call this method.
 	 * It will close the DB connection.
@@ -136,27 +145,65 @@
 
 		String dpid = sw.getStringId();
 		log.info("SwitchStorage:addSwitch(): dpid {} ", dpid);
-
+                long startSwitchTime = 0, endSwitchTime = 0;
+                long startUpdSwitchTime = 0, endUpdSwitchTime=0;
+                long startPortTime = 0, endPortTime=0;
+                long totalStartTime =0, totalEndTime=0;
+                long Tstamp1=0;
+		
 		try {
+			if (measureONOSTimeProp == 1) {
+		            log.error("Performance: addSwitch dpid= {} Start", dpid);
+			    totalStartTime = System.nanoTime();
+			}
+			pm.addswitch_start();
 			ISwitchObject curr = op.searchSwitch(dpid);
+			if (measureONOSTimeProp == 1) {
+			    Tstamp1 = System.nanoTime();
+		            log.error("Performance: addSwitch dpid= {} searchSwitch done at {} took {}", dpid, Tstamp1, Tstamp1-totalStartTime);
+			}
+
 			if (curr != null) {
 				//If existing the switch. set The SW state ACTIVE.
 				log.info("SwitchStorage:addSwitch dpid:{} already exists", dpid);
+				if (measureONOSTimeProp == 1) {
+				    startUpdSwitchTime = System.nanoTime();
+				}
 				setSwitchStateImpl(curr, SwitchState.ACTIVE);
+				if (measureONOSTimeProp == 1) {
+				    endUpdSwitchTime = System.nanoTime();
+				}
 			} else {
+				if (measureONOSTimeProp == 1) {
+				    startSwitchTime = System.nanoTime();
+				}
 				curr = addSwitchImpl(dpid);
+			        pm.addswitch_end();
+				if (measureONOSTimeProp == 1) {
+				    endSwitchTime = System.nanoTime();
+		                    //log.error("Performance: addSwitch dpid= {} addSwitchImpl done at {} took {}", dpid, endSwitchTime, endSwitchTime-startSwitchTime);
+		                    log.error("Performance: addSwitch dpid= {} End searchSwitch {} addSwitchImpl {} total {} diff {}", dpid, Tstamp1-totalStartTime, endSwitchTime-startSwitchTime, endSwitchTime-totalStartTime,endSwitchTime-totalStartTime-(Tstamp1-totalStartTime)-(endSwitchTime-startSwitchTime)); 
+				}
 			}
-
+			if (measureONOSTimeProp == 1) {
+			    startPortTime = System.nanoTime();
+			}
+                        long noOfPorts = 0;
+			pm.addport_start();
 			for (OFPhysicalPort port: sw.getPorts()) {
 				//addPort(dpid, port);
 				addPortImpl(curr, port);
-
+                                noOfPorts++;
+			    	pm.addport_incr();
 			}
-
+			pm.addport_end();
+			if (measureONOSTimeProp == 1) {
+			    endPortTime = System.nanoTime();
+			}
 			// XXX for now delete devices when we change a port to prevent
 			// having stale devices.
 			DeviceStorageImpl deviceStorage = new DeviceStorageImpl();
-			deviceStorage.init("");
+			deviceStorage.init("","");
 			for (IPortObject portObject : curr.getPorts()) {
 				for (IDeviceObject deviceObject : portObject.getDevices()) {
 					// The deviceStorage has to remove on the object gained by its own
@@ -166,6 +213,22 @@
 			}
 
 			op.commit();
+			if (measureONOSTimeProp == 1) {
+			    totalEndTime = System.nanoTime();
+			}
+                        if (startSwitchTime != 0) {
+                            //log.error("Performance -- switch add total time {}", endSwitchTime - startSwitchTime);
+                            log.error("Performance -- switch add total time {} including_search {}", endSwitchTime - startSwitchTime, endSwitchTime - totalStartTime);
+                        }
+                        if (startUpdSwitchTime != 0) {
+                            log.error("Performance -- switch update total time {} including_search {}", endUpdSwitchTime - startUpdSwitchTime, endUpdSwitchTime - totalStartTime);
+                        }
+                        if (startPortTime != 0) {
+                            log.error("Performance @@ port add total time {} no of ports written {}", endPortTime - startPortTime, noOfPorts);
+                        }
+			if (totalStartTime != 0) {
+			    log.error("Performance && total time for add switch {}", totalEndTime - totalStartTime);
+			}
 			success = true;
 		} catch (Exception e) {
 			op.rollback();
@@ -312,7 +375,7 @@
 	        	// XXX for now delete devices when we change a port to prevent
 	    		// having stale devices.
 	    		DeviceStorageImpl deviceStorage = new DeviceStorageImpl();
-	    		deviceStorage.init("");
+	    		deviceStorage.init("","");
 
 	    		for (IDeviceObject deviceObject : portObject.getDevices()) {
 	    			deviceStorage.removeDevice(deviceObject);
@@ -342,7 +405,7 @@
 		boolean success = false;
 
 		DeviceStorageImpl deviceStorage = new DeviceStorageImpl();
-		deviceStorage.init("");
+		deviceStorage.init("","");
 
 		try {
 			ISwitchObject sw = op.searchSwitch(dpid);
@@ -494,4 +557,4 @@
 	    			new Object[] {port.getPortId(), state, desc});
 		}
 	}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoLinkServiceImpl.java b/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoLinkServiceImpl.java
index 7c897d4..24392df 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoLinkServiceImpl.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoLinkServiceImpl.java
@@ -4,7 +4,7 @@
 import java.util.List;
 
 import net.floodlightcontroller.routing.Link;
-import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.graph.DBOperation;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyService.ITopoLinkService;
 
@@ -14,12 +14,13 @@
 
 import com.tinkerpop.blueprints.Vertex;
 import com.tinkerpop.gremlin.java.GremlinPipeline;
+import net.onrc.onos.graph.GraphDBManager;
 import com.tinkerpop.pipes.PipeFunction;
 import com.tinkerpop.pipes.transform.PathPipe;
 
 public class TopoLinkServiceImpl implements ITopoLinkService {
-
-	protected GraphDBOperation op;
+	
+	protected DBOperation dbop;
 	protected final static Logger log = LoggerFactory.getLogger(TopoLinkServiceImpl.class);
 
 	@Override
@@ -29,15 +30,16 @@
 
 	@Override
 	public void close() {
-		op.close();
+		dbop.close();
 	}
 
 	@Override
 	public List<Link> getActiveLinks() {
-		op = new GraphDBOperation("");
-		op.commit(); //Commit to ensure we see latest data
-		Iterable<ISwitchObject> switches = op.getActiveSwitches();
-		List<Link> links = new ArrayList<Link>();
+		dbop = GraphDBManager.getDBOperation("ramcloud", "/tmp/ramcloudconf");
+		//dbop = GraphDBManager.getDBOperation("", "");
+		//dbop.commit(); //Commit to ensure we see latest data
+		Iterable<ISwitchObject> switches = dbop.getActiveSwitches();
+		List<Link> links = new ArrayList<Link>(); 
 		for (ISwitchObject sw : switches) {
 			GremlinPipeline<Vertex, Link> pipe = new GremlinPipeline<Vertex, Link>();
 			ExtractLink extractor = new ExtractLink();
@@ -52,14 +54,14 @@
 			}
 
 		}
-		op.commit();
+		dbop.commit();
 		return links;
 	}
 
 	@Override
 	public List<Link> getLinksOnSwitch(String dpid) {
-		List<Link> links = new ArrayList<Link>();
-		ISwitchObject sw = op.searchSwitch(dpid);
+		List<Link> links = new ArrayList<Link>(); 
+		ISwitchObject sw = dbop.searchSwitch(dpid);
 		GremlinPipeline<Vertex, Link> pipe = new GremlinPipeline<Vertex, Link>();
 		ExtractLink extractor = new ExtractLink();
 
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoSwitchServiceImpl.java b/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoSwitchServiceImpl.java
index 52a5817..f417d96 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoSwitchServiceImpl.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoSwitchServiceImpl.java
@@ -1,6 +1,7 @@
 package net.onrc.onos.ofcontroller.core.internal;
 
-import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.graph.DBOperation;
+import net.onrc.onos.graph.GraphDBManager;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyService.ITopoSwitchService;
@@ -10,15 +11,16 @@
 
 public class TopoSwitchServiceImpl implements ITopoSwitchService {
 
-	private GraphDBOperation op;
+	private DBOperation op;
 	protected final static Logger log = LoggerFactory.getLogger(TopoSwitchServiceImpl.class);
 
-	public TopoSwitchServiceImpl(String conf) {
-		op = new GraphDBOperation(conf);
+	public TopoSwitchServiceImpl(final String dbStore, String conf) {
+		op = GraphDBManager.getDBOperation("ramcloud", "/tmp/ramcloudconf");
+		//op = GraphDBManager.getDBOperation(dbStore, conf);;
 	}
 
 	public TopoSwitchServiceImpl() {
-		this("");
+		this("","");
 	}
 
 	@Override
@@ -34,27 +36,27 @@
 	@Override
 	public Iterable<ISwitchObject> getActiveSwitches() {
 		// TODO Auto-generated method stub
-		op.close(); //Commit to ensure we see latest data
+		//op.close(); //Commit to ensure we see latest data
 		return op.getActiveSwitches();
 	}
 
 	@Override
 	public Iterable<ISwitchObject> getAllSwitches() {
 		// TODO Auto-generated method stub
-		op.close(); //Commit to ensure we see latest data
+		//op.close(); //Commit to ensure we see latest data
 		return op.getAllSwitches();
 	}
 
 	@Override
 	public Iterable<ISwitchObject> getInactiveSwitches() {
 		// TODO Auto-generated method stub
-		op.close(); //Commit to ensure we see latest data
+		//op.close(); //Commit to ensure we see latest data
 		return op.getInactiveSwitches();
 	}
 
 	@Override
 	public Iterable<IPortObject> getPortsOnSwitch(String dpid) {
-		op.close(); //Commit to ensure we see latest data
+		//op.close(); //Commit to ensure we see latest data
 		ISwitchObject switchObject = op.searchSwitch(dpid);
 		if (switchObject != null) {
 			return switchObject.getPorts();
diff --git a/src/main/java/net/onrc/onos/ofcontroller/devicemanager/OnosDeviceManager.java b/src/main/java/net/onrc/onos/ofcontroller/devicemanager/OnosDeviceManager.java
index f75a2b0..1b14875 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/devicemanager/OnosDeviceManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/devicemanager/OnosDeviceManager.java
@@ -179,7 +179,7 @@
 		floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
 		
 		deviceStorage = new DeviceStorageImpl();
-		deviceStorage.init("");
+		deviceStorage.init("","");
 	}
 
 	@Override
diff --git a/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/NetworkGraphPublisher.java b/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/NetworkGraphPublisher.java
index 6638ac0..0d352f8 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/NetworkGraphPublisher.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/NetworkGraphPublisher.java
@@ -20,9 +20,10 @@
 import net.floodlightcontroller.devicemanager.IDeviceListener;
 import net.floodlightcontroller.routing.Link;
 import net.floodlightcontroller.threadpool.IThreadPoolService;
+import net.onrc.onos.graph.DBOperation;
+import net.onrc.onos.graph.DBConnection;
+import net.onrc.onos.graph.GraphDBManager;
 import net.onrc.onos.datagrid.IDatagridService;
-import net.onrc.onos.graph.GraphDBConnection;
-import net.onrc.onos.graph.GraphDBOperation;
 import net.onrc.onos.graph.IDBConnection;
 import net.onrc.onos.graph.LocalTopologyEventListener;
 import net.onrc.onos.ofcontroller.core.IDeviceStorage;
@@ -65,9 +66,10 @@
 	protected final static Logger log = LoggerFactory.getLogger(NetworkGraphPublisher.class);
 	//protected IDeviceService deviceService;
 	protected IControllerRegistryService registryService;
-	protected GraphDBOperation op;
-
+	protected DBOperation op;
+	
 	protected static final String DBConfigFile = "dbconf";
+        protected static final String GraphDBStore = "graph_db_store";
 	protected static final String CleanupEnabled = "EnableCleanup";
 	protected IThreadPoolService threadPool;
 	protected IFloodlightProviderService floodlightProvider;
@@ -88,6 +90,7 @@
             Thread.currentThread().setName("SwitchCleanup@" + old);
             try {
             	log.debug("Running cleanup thread");
+		op = GraphDBManager.getDBOperation("ramcloud", "/tmp/ramcloudconf");
                 switchCleanup();
             }
             catch (Exception e) {
@@ -151,7 +154,7 @@
     }
 
     protected void switchCleanup() {
-    	op.close();
+    	//op.close();
     	Iterable<ISwitchObject> switches = op.getActiveSwitches();
 
     	log.debug("Checking for inactive switches");
@@ -454,8 +457,14 @@
 			throws FloodlightModuleException {
 		Map<String, String> configMap = context.getConfigParams(this);
 		String conf = configMap.get(DBConfigFile);
-		op = new GraphDBOperation(conf);
-
+                String dbStore = configMap.get(GraphDBStore);
+		System.out.println("conf" + conf + "dbStore" + dbStore);
+		op = GraphDBManager.getDBOperation("ramcloud", "/tmp/ramcloudconf");
+		//op = GraphDBManager.getDBOperation(dbStore, conf);
+		if (op == null) {
+		    System.out.println("publisher op is null");
+		}
+		
 		floodlightProvider =
 	            context.getServiceImpl(IFloodlightProviderService.class);
 		//deviceService = context.getServiceImpl(IDeviceService.class);
@@ -465,14 +474,14 @@
 		datagridService = context.getServiceImpl(IDatagridService.class);
 
 		devStore = new DeviceStorageImpl();
-		devStore.init(conf);
-
+		devStore.init(dbStore, conf);
+		
 		swStore = new SwitchStorageImpl();
-		swStore.init(conf);
-
+		swStore.init(dbStore, conf);
+		
 		linkStore = new LinkStorageImpl();
-		linkStore.init(conf);
-
+		linkStore.init(dbStore, conf);
+				
 		log.debug("Initializing NetworkGraphPublisher module with {}", conf);
 
 	}
@@ -487,9 +496,10 @@
 		linkDiscovery.addListener(this);
 
 		log.debug("Adding EventListener");
+		System.out.println("start Up op " + op);
 		IDBConnection conn = op.getDBConnection();
-		conn.addEventListener(new LocalTopologyEventListener((GraphDBConnection) conn));
-	       // Setup the Cleanup task.
+		conn.addEventListener(new LocalTopologyEventListener((DBConnection) conn));
+	       // Setup the Cleanup task. 
 		if (cleanupNeeded == null || !cleanupNeeded.equals("False")) {
 				ScheduledExecutorService ses = threadPool.getScheduledExecutor();
 				cleanupTask = new SingletonTask(ses, new SwitchCleanup());
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
index 1fb18db..c75657b 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
@@ -5,14 +5,12 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.LinkedList;
-import java.util.List;
 import java.util.Map;
 
 import net.floodlightcontroller.core.IOFSwitch;
 import net.floodlightcontroller.util.MACAddress;
-
-import net.onrc.onos.graph.GraphDBOperation;
-
+import net.onrc.onos.graph.DBOperation;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IBaseObject;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
@@ -22,11 +20,16 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.tinkerpop.blueprints.impls.ramcloud.PerfMon;
+import com.tinkerpop.blueprints.impls.ramcloud.RamCloudVertex;
+
 /**
  * Class for performing Flow-related operations on the Database.
  */
 public class FlowDatabaseOperation {
     private final static Logger log = LoggerFactory.getLogger(FlowDatabaseOperation.class);
+    private static final boolean measureONOSFlowTimeProp = Long.valueOf(System.getProperty("benchmark.measureONOSFlow", "0")) != 0;
+    private static final boolean measureONOSFlowEntryTimeProp = Long.valueOf(System.getProperty("benchmark.measureONOSFlowEntry", "0")) != 0;
 
     /**
      * Add a flow.
@@ -35,14 +38,45 @@
      * @param flowPath the Flow Path to install.
      * @return true on success, otherwise false.
      */
-    static boolean addFlow(GraphDBOperation dbHandler, FlowPath flowPath) {
+    static boolean addFlow(DBOperation dbHandler, FlowPath flowPath) {
 	IFlowPath flowObj = null;
 	boolean found = false;
+	long startAddFlow = 0;
+	long endAddFlow = 0;
+	long endSearchExistingFlowPathTime = 0;
+	long startCreateNewFlowPathTime = 0;
+	long endCreateNewFlowPathTime = 0;
+	long startFollowExistingFlowEntries = 0;
+	long endFollowExistingFlowEntries = 0;
+	long accTimeRemovingFlowEntriesFromFlowPath = 0;
+	long accTimeRemovingFlowEntriesFromDB = 0;
+	long startSettingFlowPathProps = 0;
+	long endSettingFlowPathProps = 0;
+	int numPropsSet = 0;
+	long accTimeAddFlowEntries = 0;
+	int numNewFlowEntries = 0;
+	LinkedList<long[]> flowEntryTimes = new LinkedList<>();
+	PerfMon pm = PerfMon.getInstance();
+
+	pm.addflowpath_start();
 	try {
-	    if ((flowObj = dbHandler.searchFlowPath(flowPath.flowId())) != null) {
+	    if ( measureONOSFlowTimeProp ) {
+		startAddFlow = System.nanoTime();
+	    }
+	    flowObj = dbHandler.searchFlowPath(flowPath.flowId());
+	    if ( measureONOSFlowTimeProp ) {
+		endSearchExistingFlowPathTime = System.nanoTime();
+	    }
+	    if (flowObj != null) {
 		found = true;
 	    } else {
+		if ( measureONOSFlowTimeProp ) {
+			startCreateNewFlowPathTime = System.nanoTime();
+		}
 		flowObj = dbHandler.newFlowPath();
+		if ( measureONOSFlowTimeProp ) {
+			endCreateNewFlowPathTime = System.nanoTime();
+		}
 	    }
 	} catch (Exception e) {
 	    dbHandler.rollback();
@@ -67,23 +101,48 @@
 	// Remove the old Flow Entries
 	//
 	if (found) {
+	    if ( measureONOSFlowTimeProp ) {
+		startFollowExistingFlowEntries = System.nanoTime();
+	    }
 	    Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
+	    if ( measureONOSFlowTimeProp ) {
+		endFollowExistingFlowEntries = System.nanoTime();
+	    }
 	    LinkedList<IFlowEntry> deleteFlowEntries =
 		new LinkedList<IFlowEntry>();
 	    for (IFlowEntry flowEntryObj : flowEntries)
 		deleteFlowEntries.add(flowEntryObj);
-	    for (IFlowEntry flowEntryObj : deleteFlowEntries) {
-		flowObj.removeFlowEntry(flowEntryObj);
-		dbHandler.removeFlowEntry(flowEntryObj);
+	    if( measureONOSFlowTimeProp ) {
+		    for (IFlowEntry flowEntryObj : deleteFlowEntries) {
+			long start = System.nanoTime();
+			flowObj.removeFlowEntry(flowEntryObj);
+			accTimeRemovingFlowEntriesFromFlowPath += System.nanoTime() - start;
+			start = System.nanoTime();
+			dbHandler.removeFlowEntry(flowEntryObj);
+			accTimeRemovingFlowEntriesFromDB += System.nanoTime() - start;
+		    }
+	    } else {
+		    for (IFlowEntry flowEntryObj : deleteFlowEntries) {
+			flowObj.removeFlowEntry(flowEntryObj);
+			dbHandler.removeFlowEntry(flowEntryObj);
+		    }
 	    }
 	}
 
+	if ( measureONOSFlowTimeProp ) {
+		startSettingFlowPathProps = System.nanoTime();
+	}
+
+	FlowPathProperty flowProp = new FlowPathProperty(dbHandler, flowObj);
+
 	//
 	// Set the Flow key:
 	// - flowId
 	//
-	flowObj.setFlowId(flowPath.flowId().toString());
-	flowObj.setType("flow");
+	flowProp.setFlowId(flowPath.flowId().toString());
+	if ( measureONOSFlowTimeProp ) {
+	    numPropsSet += 1;
+	}
 
 	//
 	// Set the Flow attributes:
@@ -108,59 +167,112 @@
 	// - flowPath.matchDstTcpUdpPort()
 	// - flowPath.flowEntryActions()
 	//
-	flowObj.setInstallerId(flowPath.installerId().toString());
-	flowObj.setFlowPathType(flowPath.flowPathType().toString());
-	flowObj.setFlowPathUserState(flowPath.flowPathUserState().toString());
-	flowObj.setFlowPathFlags(flowPath.flowPathFlags().flags());
-	flowObj.setIdleTimeout(flowPath.idleTimeout());
-	flowObj.setHardTimeout(flowPath.hardTimeout());
-	flowObj.setSrcSwitch(flowPath.dataPath().srcPort().dpid().toString());
-	flowObj.setSrcPort(flowPath.dataPath().srcPort().port().value());
-	flowObj.setDstSwitch(flowPath.dataPath().dstPort().dpid().toString());
-	flowObj.setDstPort(flowPath.dataPath().dstPort().port().value());
+	flowProp.setInstallerId(flowPath.installerId().toString());
+	flowProp.setFlowPathType(flowPath.flowPathType().toString());
+	flowProp.setFlowPathUserState(flowPath.flowPathUserState().toString());
+	flowProp.setFlowPathFlags(flowPath.flowPathFlags().flags());
+	flowProp.setIdleTimeout(flowPath.idleTimeout());
+	flowProp.setHardTimeout(flowPath.hardTimeout());
+	flowProp.setSrcSwitch(flowPath.dataPath().srcPort().dpid().toString());
+	flowProp.setSrcPort(flowPath.dataPath().srcPort().port().value());
+	flowProp.setDstSwitch(flowPath.dataPath().dstPort().dpid().toString());
+	flowProp.setDstPort(flowPath.dataPath().dstPort().port().value());
+	if ( measureONOSFlowTimeProp ) {
+	    numPropsSet += 10;
+	}
+
 	if (flowPath.flowEntryMatch().matchSrcMac()) {
-	    flowObj.setMatchSrcMac(flowPath.flowEntryMatch().srcMac().toString());
+	    flowProp.setMatchSrcMac(flowPath.flowEntryMatch().srcMac().toString());
+		if ( measureONOSFlowTimeProp ) {
+		    ++numPropsSet;
+		}
 	}
 	if (flowPath.flowEntryMatch().matchDstMac()) {
-	    flowObj.setMatchDstMac(flowPath.flowEntryMatch().dstMac().toString());
+	    flowProp.setMatchDstMac(flowPath.flowEntryMatch().dstMac().toString());
+		if ( measureONOSFlowTimeProp ) {
+		    ++numPropsSet;
+		}
 	}
 	if (flowPath.flowEntryMatch().matchEthernetFrameType()) {
-	    flowObj.setMatchEthernetFrameType(flowPath.flowEntryMatch().ethernetFrameType());
+	    flowProp.setMatchEthernetFrameType(flowPath.flowEntryMatch().ethernetFrameType());
+		if ( measureONOSFlowTimeProp ) {
+		    ++numPropsSet;
+		}
 	}
 	if (flowPath.flowEntryMatch().matchVlanId()) {
-	    flowObj.setMatchVlanId(flowPath.flowEntryMatch().vlanId());
+	    flowProp.setMatchVlanId(flowPath.flowEntryMatch().vlanId());
+		if ( measureONOSFlowTimeProp ) {
+		    ++numPropsSet;
+		}
 	}
 	if (flowPath.flowEntryMatch().matchVlanPriority()) {
-	    flowObj.setMatchVlanPriority(flowPath.flowEntryMatch().vlanPriority());
+	    flowProp.setMatchVlanPriority(flowPath.flowEntryMatch().vlanPriority());
+		if ( measureONOSFlowTimeProp ) {
+		    ++numPropsSet;
+		}
 	}
 	if (flowPath.flowEntryMatch().matchSrcIPv4Net()) {
-	    flowObj.setMatchSrcIPv4Net(flowPath.flowEntryMatch().srcIPv4Net().toString());
+	    flowProp.setMatchSrcIPv4Net(flowPath.flowEntryMatch().srcIPv4Net().toString());
+		if ( measureONOSFlowTimeProp ) {
+		    ++numPropsSet;
+		}
 	}
 	if (flowPath.flowEntryMatch().matchDstIPv4Net()) {
-	    flowObj.setMatchDstIPv4Net(flowPath.flowEntryMatch().dstIPv4Net().toString());
+	    flowProp.setMatchDstIPv4Net(flowPath.flowEntryMatch().dstIPv4Net().toString());
+		if ( measureONOSFlowTimeProp ) {
+		    ++numPropsSet;
+		}
 	}
 	if (flowPath.flowEntryMatch().matchIpProto()) {
-	    flowObj.setMatchIpProto(flowPath.flowEntryMatch().ipProto());
+	    flowProp.setMatchIpProto(flowPath.flowEntryMatch().ipProto());
+		if ( measureONOSFlowTimeProp ) {
+		    ++numPropsSet;
+		}
 	}
 	if (flowPath.flowEntryMatch().matchIpToS()) {
-	    flowObj.setMatchIpToS(flowPath.flowEntryMatch().ipToS());
+	    flowProp.setMatchIpToS(flowPath.flowEntryMatch().ipToS());
+		if ( measureONOSFlowTimeProp ) {
+		    ++numPropsSet;
+		}
 	}
 	if (flowPath.flowEntryMatch().matchSrcTcpUdpPort()) {
-	    flowObj.setMatchSrcTcpUdpPort(flowPath.flowEntryMatch().srcTcpUdpPort());
+	    flowProp.setMatchSrcTcpUdpPort(flowPath.flowEntryMatch().srcTcpUdpPort());
+		if ( measureONOSFlowTimeProp ) {
+		    ++numPropsSet;
+		}
 	}
 	if (flowPath.flowEntryMatch().matchDstTcpUdpPort()) {
-	    flowObj.setMatchDstTcpUdpPort(flowPath.flowEntryMatch().dstTcpUdpPort());
+	    flowProp.setMatchDstTcpUdpPort(flowPath.flowEntryMatch().dstTcpUdpPort());
+		if ( measureONOSFlowTimeProp ) {
+		    ++numPropsSet;
+		}
 	}
 	if (! flowPath.flowEntryActions().actions().isEmpty()) {
-	    flowObj.setActions(flowPath.flowEntryActions().toString());
+	    flowProp.setActions(flowPath.flowEntryActions().toString());
+		if ( measureONOSFlowTimeProp ) {
+		    ++numPropsSet;
+		}
 	}
-	flowObj.setDataPathSummary(flowPath.dataPath().dataPathSummary());
+	flowProp.setDataPathSummary(flowPath.dataPath().dataPathSummary());
+	if ( measureONOSFlowTimeProp ) {
+	    ++numPropsSet;
+	}
 
 	if (found)
-	    flowObj.setFlowPathUserState("FP_USER_MODIFY");
+	    flowProp.setFlowPathUserState("FP_USER_MODIFY");
 	else
-	    flowObj.setFlowPathUserState("FP_USER_ADD");
+	    flowProp.setFlowPathUserState("FP_USER_ADD");
 
+	flowProp.commitProperties();
+
+	if ( measureONOSFlowTimeProp ) {
+	    ++numPropsSet;
+	}
+
+	if ( measureONOSFlowTimeProp ) {
+		endSettingFlowPathProps = System.nanoTime();
+	}
+	pm.addflowpath_end();
 	// Flow edges:
 	//   HeadFE
 
@@ -169,17 +281,68 @@
 	// Flow Entries:
 	// flowPath.dataPath().flowEntries()
 	//
+	pm.addflowentry_start();
 	for (FlowEntry flowEntry : flowPath.dataPath().flowEntries()) {
 	    if (flowEntry.flowEntryUserState() == FlowEntryUserState.FE_USER_DELETE)
 		continue;	// Skip: all Flow Entries were deleted earlier
 
-	    if (addFlowEntry(dbHandler, flowObj, flowEntry) == null) {
+	    pm.addflowentry_incr();
+
+	    long startAddFlowEntry = 0, endAddFlowEntry;
+	    if( measureONOSFlowTimeProp ) {
+		startAddFlowEntry = System.nanoTime();
+	    }
+	    IFlowEntry iFlowEntry = addFlowEntry(dbHandler, flowObj, flowEntry);
+	    if( measureONOSFlowTimeProp ) {
+		endAddFlowEntry = System.nanoTime();
+		accTimeAddFlowEntries += endAddFlowEntry - startAddFlowEntry;
+
+		flowEntryTimes.addLast( new long[]{flowEntry.flowId().value(), endAddFlowEntry - startAddFlowEntry} );
+	    }
+	    if ( iFlowEntry == null) {
 		dbHandler.rollback();
 		return false;
 	    }
 	}
+	pm.addflowentry_end();
 	dbHandler.commit();
 
+
+	if ( measureONOSFlowTimeProp ) {
+	    endAddFlow = System.nanoTime();
+
+	    log.error("Performance addFlow(_,{}) -- "
+		    + "GrandTotal: {} "
+		    + "only FlowPathTotal: {} "
+		    + "searchExistingFlowPath: {} "
+		    + "createNewFlowPathTime: {}"
+		    + "followExistingFlowEntries: {} "
+		    + "accTimeRemovingFlowEntriesFromFlowPath: {} "
+		    + "accTimeRemovingFlowEntriesFromDB: {} "
+		    + "settingFlowPathProps: {} #Props: {} "
+		    + "accFlowEntries: {} #FEs: {}",
+		    flowPath.flowId(),
+		    (endAddFlow - startAddFlow),
+		    (endSettingFlowPathProps - startAddFlow),
+		    (endSearchExistingFlowPathTime - startAddFlow),
+		    (endCreateNewFlowPathTime - startCreateNewFlowPathTime),
+		    (endFollowExistingFlowEntries - startFollowExistingFlowEntries),
+		    (accTimeRemovingFlowEntriesFromFlowPath),
+		    (accTimeRemovingFlowEntriesFromDB),
+		    (endSettingFlowPathProps - startSettingFlowPathProps), numPropsSet,
+		    accTimeAddFlowEntries, numNewFlowEntries
+		    );
+
+	    // Each FlowEntries
+	    final String strFlowId = flowPath.flowId().toString();
+	    for ( long[] idFE_Time : flowEntryTimes ) {
+		log.error("Performance addFlowEntry(_,{},{})@addFlow -- FlowEntryTotal: {}",
+			strFlowId,
+			"0x" + Long.toHexString(idFE_Time[0]),
+			idFE_Time[1]);
+	    }
+	}
+
 	return true;
     }
 
@@ -191,20 +354,65 @@
      * @param flowEntry the Flow Entry to install.
      * @return the added Flow Entry object on success, otherwise null.
      */
-    static IFlowEntry addFlowEntry(GraphDBOperation dbHandler,
+    static IFlowEntry addFlowEntry(DBOperation dbHandler,
 				   IFlowPath flowObj,
 				   FlowEntry flowEntry) {
 	// Flow edges
 	//   HeadFE (TODO)
+	long startAddFlowEntry = 0;
+	long endAddFlowEntry = 0;
+
+	long endSearchFlowEntry = 0;
+
+	long startCreateNewFlowEntry = 0;
+	long endCreateNewFlowEntry = 0;
+
+	long startSetProperties = 0;
+	long endSetProperties = 0;
+	int numProperties = 0;
+
+	long startSearchSwitch = 0;
+	long endSearchSwitch = 0;
+
+	long startAddEdgeToSwitch =0;
+	long endAddEdgeToSwitch =0;
+
+	long startSearchInPort = 0;
+	long endSearchInPort = 0;
+
+	long startAddEdgeToInPort =0;
+	long endAddEdgeToInPort =0;
+
+	long startSearchOutPort = 0;
+	long endSearchOutPort = 0;
+
+	long startAddEdgeToOutPort =0;
+	long endAddEdgeToOutPort =0;
+
+	long startAddEdgeBetweenFlowPath = 0;
+	long endAddEdgeBetweenFlowPath = 0;
+
+	if (measureONOSFlowEntryTimeProp) {
+		startAddFlowEntry = System.nanoTime();
+	}
 
 	IFlowEntry flowEntryObj = null;
 	boolean found = false;
 	try {
-	    if ((flowEntryObj =
-		 dbHandler.searchFlowEntry(flowEntry.flowEntryId())) != null) {
+	    flowEntryObj = dbHandler.searchFlowEntry(flowEntry.flowEntryId());
+	    if (measureONOSFlowEntryTimeProp) {
+		endSearchFlowEntry = System.nanoTime();
+	    }
+	    if (flowEntryObj != null) {
 		found = true;
 	    } else {
+		if (measureONOSFlowEntryTimeProp) {
+		    startCreateNewFlowEntry = System.nanoTime();
+		}
 		flowEntryObj = dbHandler.newFlowEntry();
+		if (measureONOSFlowEntryTimeProp) {
+		    endCreateNewFlowEntry = System.nanoTime();
+		}
 	    }
 	} catch (Exception e) {
 	    log.error(":addFlow FlowEntryId:{} failed",
@@ -217,14 +425,23 @@
 	    return null;
 	}
 
+	if (measureONOSFlowEntryTimeProp) {
+	    startSetProperties = System.nanoTime();
+	}
+
+	FlowEntryProperty flowProp = new FlowEntryProperty(dbHandler, flowEntryObj);
+
 	//
 	// Set the Flow Entry key:
 	// - flowEntry.flowEntryId()
 	//
-	flowEntryObj.setFlowEntryId(flowEntry.flowEntryId().toString());
-	flowEntryObj.setType("flow_entry");
+	flowProp.setFlowEntryId(flowEntry.flowEntryId().toString());
+	flowProp.setType("flow_entry");
+	if (measureONOSFlowEntryTimeProp) {
+	    numProperties += 2;
+	}
 
-	// 
+	//
 	// Set the Flow Entry Edges and attributes:
 	// - Switch edge
 	// - InPort edge
@@ -251,77 +468,207 @@
 	// - flowEntry.actionOutputPort()
 	// - flowEntry.actions()
 	//
+	if (measureONOSFlowEntryTimeProp) {
+	    startSearchSwitch = System.nanoTime();
+	}
 	ISwitchObject sw = dbHandler.searchSwitch(flowEntry.dpid().toString());
-	flowEntryObj.setIdleTimeout(flowEntry.idleTimeout());
-	flowEntryObj.setHardTimeout(flowEntry.hardTimeout());
-	flowEntryObj.setSwitchDpid(flowEntry.dpid().toString());
+	if (measureONOSFlowEntryTimeProp) {
+	    endSearchSwitch = System.nanoTime();
+	}
+
+	flowProp.setIdleTimeout(flowEntry.idleTimeout());
+	flowProp.setHardTimeout(flowEntry.hardTimeout());
+	flowProp.setSwitchDpid(flowEntry.dpid().toString());
+	if (measureONOSFlowEntryTimeProp) {
+	    numProperties += 3;
+	}
+
+	if (measureONOSFlowEntryTimeProp) {
+	    startAddEdgeToSwitch = System.nanoTime();
+	}
 	flowEntryObj.setSwitch(sw);
+	if (measureONOSFlowEntryTimeProp) {
+	    endAddEdgeToSwitch = System.nanoTime();
+	}
 	if (flowEntry.flowEntryMatch().matchInPort()) {
+	    if (measureONOSFlowEntryTimeProp) {
+		startSearchInPort = System.nanoTime();
+	    }
 	    IPortObject inport =
-		dbHandler.searchPort(flowEntry.dpid().toString(),
-					flowEntry.flowEntryMatch().inPort().value());
-	    flowEntryObj.setMatchInPort(flowEntry.flowEntryMatch().inPort().value());
+		    dbHandler.searchPort(flowEntry.dpid().toString(),
+			    flowEntry.flowEntryMatch().inPort().value());
+	    if (measureONOSFlowEntryTimeProp) {
+		endSearchInPort = System.nanoTime();
+	    }
+
+	    flowProp.setMatchInPort(flowEntry.flowEntryMatch().inPort().value());
+	    if (measureONOSFlowEntryTimeProp) {
+		++numProperties;
+	    }
+
+	    if (measureONOSFlowEntryTimeProp) {
+		startAddEdgeToInPort = System.nanoTime();
+	    }
 	    flowEntryObj.setInPort(inport);
+	    if (measureONOSFlowEntryTimeProp) {
+		endAddEdgeToInPort = System.nanoTime();
+	    }
 	}
 	if (flowEntry.flowEntryMatch().matchSrcMac()) {
-	    flowEntryObj.setMatchSrcMac(flowEntry.flowEntryMatch().srcMac().toString());
+		flowProp.setMatchSrcMac(flowEntry.flowEntryMatch().srcMac().toString());
+	    if (measureONOSFlowEntryTimeProp) {
+		++numProperties;
+	    }
 	}
 	if (flowEntry.flowEntryMatch().matchDstMac()) {
-	    flowEntryObj.setMatchDstMac(flowEntry.flowEntryMatch().dstMac().toString());
+		flowProp.setMatchDstMac(flowEntry.flowEntryMatch().dstMac().toString());
+	    if (measureONOSFlowEntryTimeProp) {
+		++numProperties;
+	    }
 	}
 	if (flowEntry.flowEntryMatch().matchEthernetFrameType()) {
-	    flowEntryObj.setMatchEthernetFrameType(flowEntry.flowEntryMatch().ethernetFrameType());
+		flowProp.setMatchEthernetFrameType(flowEntry.flowEntryMatch().ethernetFrameType());
+	    if (measureONOSFlowEntryTimeProp) {
+		++numProperties;
+	    }
 	}
 	if (flowEntry.flowEntryMatch().matchVlanId()) {
-	    flowEntryObj.setMatchVlanId(flowEntry.flowEntryMatch().vlanId());
+		flowProp.setMatchVlanId(flowEntry.flowEntryMatch().vlanId());
+	    if (measureONOSFlowEntryTimeProp) {
+		++numProperties;
+	    }
 	}
 	if (flowEntry.flowEntryMatch().matchVlanPriority()) {
-	    flowEntryObj.setMatchVlanPriority(flowEntry.flowEntryMatch().vlanPriority());
+		flowProp.setMatchVlanPriority(flowEntry.flowEntryMatch().vlanPriority());
+	    if (measureONOSFlowEntryTimeProp) {
+		++numProperties;
+	    }
 	}
 	if (flowEntry.flowEntryMatch().matchSrcIPv4Net()) {
-	    flowEntryObj.setMatchSrcIPv4Net(flowEntry.flowEntryMatch().srcIPv4Net().toString());
+		flowProp.setMatchSrcIPv4Net(flowEntry.flowEntryMatch().srcIPv4Net().toString());
+	    if (measureONOSFlowEntryTimeProp) {
+		++numProperties;
+	    }
 	}
 	if (flowEntry.flowEntryMatch().matchDstIPv4Net()) {
-	    flowEntryObj.setMatchDstIPv4Net(flowEntry.flowEntryMatch().dstIPv4Net().toString());
+		flowProp.setMatchDstIPv4Net(flowEntry.flowEntryMatch().dstIPv4Net().toString());
+	    if (measureONOSFlowEntryTimeProp) {
+		++numProperties;
+	    }
 	}
 	if (flowEntry.flowEntryMatch().matchIpProto()) {
-	    flowEntryObj.setMatchIpProto(flowEntry.flowEntryMatch().ipProto());
+		flowProp.setMatchIpProto(flowEntry.flowEntryMatch().ipProto());
+	    if (measureONOSFlowEntryTimeProp) {
+		++numProperties;
+	    }
 	}
 	if (flowEntry.flowEntryMatch().matchIpToS()) {
-	    flowEntryObj.setMatchIpToS(flowEntry.flowEntryMatch().ipToS());
+		flowProp.setMatchIpToS(flowEntry.flowEntryMatch().ipToS());
+	    if (measureONOSFlowEntryTimeProp) {
+		++numProperties;
+	    }
 	}
 	if (flowEntry.flowEntryMatch().matchSrcTcpUdpPort()) {
-	    flowEntryObj.setMatchSrcTcpUdpPort(flowEntry.flowEntryMatch().srcTcpUdpPort());
+		flowProp.setMatchSrcTcpUdpPort(flowEntry.flowEntryMatch().srcTcpUdpPort());
+	    if (measureONOSFlowEntryTimeProp) {
+		++numProperties;
+	    }
 	}
 	if (flowEntry.flowEntryMatch().matchDstTcpUdpPort()) {
-	    flowEntryObj.setMatchDstTcpUdpPort(flowEntry.flowEntryMatch().dstTcpUdpPort());
+		flowProp.setMatchDstTcpUdpPort(flowEntry.flowEntryMatch().dstTcpUdpPort());
+	    if (measureONOSFlowEntryTimeProp) {
+		++numProperties;
+	    }
 	}
 
 	for (FlowEntryAction fa : flowEntry.flowEntryActions().actions()) {
 	    if (fa.actionOutput() != null) {
+		if (measureONOSFlowEntryTimeProp) {
+		    if ( startSearchOutPort != 0 ) log.error("Performance addFlowEntry(_,{},{}) -- Multiple output port action unexpected.", flowEntry.flowId(), flowEntry.flowEntryId());
+		    startSearchOutPort = System.nanoTime();
+		}
 		IPortObject outport =
-		    dbHandler.searchPort(flowEntry.dpid().toString(),
-					      fa.actionOutput().port().value());
-		flowEntryObj.setActionOutputPort(fa.actionOutput().port().value());
+			dbHandler.searchPort(flowEntry.dpid().toString(),
+				fa.actionOutput().port().value());
+		if (measureONOSFlowEntryTimeProp) {
+		    endSearchOutPort = System.nanoTime();
+		}
+
+		flowProp.setActionOutputPort(fa.actionOutput().port().value());
+		if (measureONOSFlowEntryTimeProp) {
+		    ++numProperties;
+		}
+
+		if (measureONOSFlowEntryTimeProp) {
+		    startAddEdgeToOutPort = System.nanoTime();
+		}
 		flowEntryObj.setOutPort(outport);
+		if (measureONOSFlowEntryTimeProp) {
+		    endAddEdgeToOutPort = System.nanoTime();
+		}
 	    }
 	}
 	if (! flowEntry.flowEntryActions().isEmpty()) {
-	    flowEntryObj.setActions(flowEntry.flowEntryActions().toString());
+		flowProp.setActions(flowEntry.flowEntryActions().toString());
+	    if (measureONOSFlowEntryTimeProp) {
+		++numProperties;
+	    }
 	}
 
-	flowEntryObj.setUserState(flowEntry.flowEntryUserState().toString());
-	flowEntryObj.setSwitchState(flowEntry.flowEntrySwitchState().toString());
+	flowProp.setUserState(flowEntry.flowEntryUserState().toString());
+	flowProp.setSwitchState(flowEntry.flowEntrySwitchState().toString());
+	if (measureONOSFlowEntryTimeProp) {
+	    numProperties += 2;
+	}
+	flowProp.commitProperties();
 	//
 	// TODO: Take care of the FlowEntryErrorState.
 	//
+	if (measureONOSFlowEntryTimeProp) {
+	    endSetProperties = System.nanoTime();
+	}
 
 	// Flow Entries edges:
 	//   Flow
 	//   NextFE (TODO)
 	if (! found) {
+	    if (measureONOSFlowEntryTimeProp) {
+		startAddEdgeBetweenFlowPath = System.nanoTime();
+	    }
 	    flowObj.addFlowEntry(flowEntryObj);
 	    flowEntryObj.setFlow(flowObj);
+	    if (measureONOSFlowEntryTimeProp) {
+		endAddEdgeBetweenFlowPath = System.nanoTime();
+	    }
+	}
+	if (measureONOSFlowEntryTimeProp) {
+	    endAddFlowEntry = System.nanoTime();
+
+	    log.error("Performance addFlowEntry(_,{},{}) -- "
+		    + "GrandTotal: {} "
+		    + "SearchExistingFE: {} "
+		    + "CreateNewFE: {} "
+		    + "SetProp+Edge: {} #Props: {} "
+		    + "SearchSwitch: {} "
+		    + "AddEdgeToSwitch: {} "
+		    + "SearchInPort: {} "
+		    + "AddEdgeToInPort: {} "
+		    + "SearchOutPort: {} "
+		    + "AddEdgeToOutPort: {} "
+		    + "AddEdgeBetweenFlowPath: {} "
+		    , flowEntry.flowId(), flowEntry.flowEntryId()
+		    , endAddFlowEntry - startAddFlowEntry
+		    , endSearchFlowEntry - startAddFlowEntry
+		    , endCreateNewFlowEntry - startCreateNewFlowEntry
+		    , endSetProperties - startSetProperties, numProperties
+		    , endSearchSwitch - startSearchSwitch
+		    , endAddEdgeToSwitch - startAddEdgeToSwitch
+		    , endSearchInPort - startSearchInPort
+		    , endAddEdgeToInPort - startAddEdgeToInPort
+		    , endSearchOutPort - startSearchOutPort
+		    , endAddEdgeToOutPort - startAddEdgeToOutPort
+		    , endAddEdgeBetweenFlowPath - startAddEdgeBetweenFlowPath
+		    );
 	}
 
 	return flowEntryObj;
@@ -335,7 +682,7 @@
      * @param flowEntry the Flow Entry to delete.
      * @return true on success, otherwise false.
      */
-    static boolean deleteFlowEntry(GraphDBOperation dbHandler,
+    static boolean deleteFlowEntry(DBOperation dbHandler,
 				   IFlowPath flowObj,
 				   FlowEntry flowEntry) {
 	IFlowEntry flowEntryObj = null;
@@ -371,25 +718,14 @@
      * @param dbHandler the Graph Database handler to use.
      * @return true on success, otherwise false.
      */
-    static boolean deleteAllFlows(GraphDBOperation dbHandler) {
-	List<FlowId> allFlowIds = new LinkedList<FlowId>();
-
-	// Get all Flow IDs
+    static boolean deleteAllFlows(DBOperation dbHandler) {
 	Iterable<IFlowPath> allFlowPaths = dbHandler.getAllFlowPaths();
 	for (IFlowPath flowPathObj : allFlowPaths) {
 	    if (flowPathObj == null)
 		continue;
-	    String flowIdStr = flowPathObj.getFlowId();
-	    if (flowIdStr == null)
-		continue;
-	    FlowId flowId = new FlowId(flowIdStr);
-	    allFlowIds.add(flowId);
+	    deleteIFlowPath(dbHandler, flowPathObj);
 	}
-
-	// Delete all flows one-by-one
-	for (FlowId flowId : allFlowIds) {
-	    deleteFlow(dbHandler, flowId);
-	}
+	dbHandler.commit();
 
 	return true;
     }
@@ -401,7 +737,7 @@
      * @param flowId the Flow ID of the flow to delete.
      * @return true on success, otherwise false.
      */
-    static boolean deleteFlow(GraphDBOperation dbHandler, FlowId flowId) {
+    static boolean deleteFlow(DBOperation dbHandler, FlowId flowId) {
 	IFlowPath flowObj = null;
 	try {
 	    flowObj = dbHandler.searchFlowPath(flowId);
@@ -416,6 +752,13 @@
 	    return true;		// OK: No such flow
 	}
 
+	deleteIFlowPath(dbHandler, flowObj);
+	dbHandler.commit();
+
+	return true;
+    }
+
+    private static void deleteIFlowPath(DBOperation dbHandler, IFlowPath flowObj) {
 	//
 	// Remove all Flow Entries
 	//
@@ -426,9 +769,6 @@
 	}
 	// Remove the Flow itself
 	dbHandler.removeFlowPath(flowObj);
-	dbHandler.commit();
-
-	return true;
     }
 
     /**
@@ -438,7 +778,7 @@
      * @param flowId the Flow ID of the flow to get.
      * @return the Flow Path if found, otherwise null.
      */
-    static FlowPath getFlow(GraphDBOperation dbHandler, FlowId flowId) {
+    static FlowPath getFlow(DBOperation dbHandler, FlowId flowId) {
 	IFlowPath flowObj = null;
 	try {
 	    flowObj = dbHandler.searchFlowPath(flowId);
@@ -469,7 +809,7 @@
      * @param flowEntryId the Flow Entry ID of the flow entry to get.
      * @return the Flow Entry if found, otherwise null.
      */
-    static FlowEntry getFlowEntry(GraphDBOperation dbHandler,
+    static FlowEntry getFlowEntry(DBOperation dbHandler,
 				  FlowEntryId flowEntryId) {
 	IFlowEntry flowEntryObj = null;
 	try {
@@ -501,7 +841,7 @@
      * @param flowId the Flow ID of the flow to get.
      * @return the source switch DPID if found, otherwise null.
      */
-    static Dpid getFlowSourceDpid(GraphDBOperation dbHandler, FlowId flowId) {
+    static Dpid getFlowSourceDpid(DBOperation dbHandler, FlowId flowId) {
 	IFlowPath flowObj = null;
 	try {
 	    flowObj = dbHandler.searchFlowPath(flowId);
@@ -539,7 +879,7 @@
      * @param dbHandler the Graph Database handler to use.
      * @return the Flow Paths if found, otherwise null.
      */
-    static ArrayList<FlowPath> getAllFlows(GraphDBOperation dbHandler) {
+    static ArrayList<FlowPath> getAllFlows(DBOperation dbHandler) {
 	Iterable<IFlowPath> flowPathsObj = null;
 	ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
 
@@ -579,7 +919,7 @@
      * instance.
      * @return the Flow Paths if found, otherwise null.
      */
-    static ArrayList<FlowPath> getAllMyFlows(GraphDBOperation dbHandler,
+    static ArrayList<FlowPath> getAllMyFlows(DBOperation dbHandler,
 					     Map<Long, IOFSwitch> mySwitches) {
 	Iterable<IFlowPath> flowPathsObj = null;
 	ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
@@ -631,7 +971,7 @@
      * @param flowIds the collection of Flow IDs to get.
      * @return the Flow Paths if found, otherwise null.
      */
-    static ArrayList<FlowPath> getFlows(GraphDBOperation dbHandler,
+    static ArrayList<FlowPath> getFlows(DBOperation dbHandler,
 					Collection<FlowId> flowIds) {
 	ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
 
@@ -656,17 +996,47 @@
 	//
 	// Extract the Flow state
 	//
-	String flowIdStr = flowObj.getFlowId();
-	String installerIdStr = flowObj.getInstallerId();
-	String flowPathType = flowObj.getFlowPathType();
-	String flowPathUserState = flowObj.getFlowPathUserState();
-	Long flowPathFlags = flowObj.getFlowPathFlags();
-	Integer idleTimeout = flowObj.getIdleTimeout();
-	Integer hardTimeout = flowObj.getHardTimeout();
-	String srcSwitchStr = flowObj.getSrcSwitch();
-	Short srcPortShort = flowObj.getSrcPort();
-	String dstSwitchStr = flowObj.getDstSwitch();
-	Short dstPortShort = flowObj.getDstPort();
+    log.info("extractFlowPath: start");
+	String flowIdStr;
+	String installerIdStr;
+	String flowPathType;
+	String flowPathUserState;
+	Long flowPathFlags;
+	Integer idleTimeout;
+	Integer hardTimeout;
+	String srcSwitchStr;
+	Short srcPortShort;
+	String dstSwitchStr;
+	Short dstPortShort;
+
+	if ( flowObj.asVertex() instanceof RamCloudVertex ) {
+	    RamCloudVertex v = (RamCloudVertex)flowObj.asVertex();
+	    Map<String,Object> propMap = v.getProperties();
+
+	    flowIdStr = (String) propMap.get("flow_id");
+	    installerIdStr = (String) propMap.get("installer_id");
+	    flowPathType = (String) propMap.get("flow_path_type");
+	    flowPathUserState = (String) propMap.get("user_state");
+	    flowPathFlags = (Long)propMap.get("flow_path_flags");
+	    idleTimeout = (Integer) propMap.get("idle_timeout");
+	    hardTimeout = (Integer) propMap.get("hard_timeout");
+	    srcSwitchStr = (String) propMap.get("src_switch");
+	    srcPortShort = (Short)propMap.get("src_port");
+	    dstSwitchStr = (String) propMap.get("dst_switch");
+	    dstPortShort = (Short)propMap.get("dst_port");
+	} else {
+	    flowIdStr = flowObj.getFlowId();
+	    installerIdStr = flowObj.getInstallerId();
+	    flowPathType = flowObj.getFlowPathType();
+	    flowPathUserState = flowObj.getFlowPathUserState();
+	    flowPathFlags = flowObj.getFlowPathFlags();
+	    idleTimeout = flowObj.getIdleTimeout();
+	    hardTimeout = flowObj.getHardTimeout();
+	    srcSwitchStr = flowObj.getSrcSwitch();
+	    srcPortShort = flowObj.getSrcPort();
+	    dstSwitchStr = flowObj.getDstSwitch();
+	    dstPortShort = flowObj.getDstPort();
+	}
 
 	if ((flowIdStr == null) ||
 	    (installerIdStr == null) ||
@@ -679,7 +1049,8 @@
 	    (srcPortShort == null) ||
 	    (dstSwitchStr == null) ||
 	    (dstPortShort == null)) {
-	    // TODO: A work-around, becauuse of some bogus database objects
+	    // TODO: A work-around, because of some bogus database objects
+	    log.error("extractFlowPath: wrong properties");
 	    return null;
 	}
 
@@ -699,40 +1070,7 @@
 	// Extract the match conditions common for all Flow Entries
 	//
 	{
-	    FlowEntryMatch match = new FlowEntryMatch();
-	    String matchSrcMac = flowObj.getMatchSrcMac();
-	    if (matchSrcMac != null)
-		match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
-	    String matchDstMac = flowObj.getMatchDstMac();
-	    if (matchDstMac != null)
-		match.enableDstMac(MACAddress.valueOf(matchDstMac));
-	    Short matchEthernetFrameType = flowObj.getMatchEthernetFrameType();
-	    if (matchEthernetFrameType != null)
-		match.enableEthernetFrameType(matchEthernetFrameType);
-	    Short matchVlanId = flowObj.getMatchVlanId();
-	    if (matchVlanId != null)
-		match.enableVlanId(matchVlanId);
-	    Byte matchVlanPriority = flowObj.getMatchVlanPriority();
-	    if (matchVlanPriority != null)
-		match.enableVlanPriority(matchVlanPriority);
-	    String matchSrcIPv4Net = flowObj.getMatchSrcIPv4Net();
-	    if (matchSrcIPv4Net != null)
-		match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
-	    String matchDstIPv4Net = flowObj.getMatchDstIPv4Net();
-	    if (matchDstIPv4Net != null)
-		match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
-	    Byte matchIpProto = flowObj.getMatchIpProto();
-	    if (matchIpProto != null)
-		match.enableIpProto(matchIpProto);
-	    Byte matchIpToS = flowObj.getMatchIpToS();
-	    if (matchIpToS != null)
-		match.enableIpToS(matchIpToS);
-	    Short matchSrcTcpUdpPort = flowObj.getMatchSrcTcpUdpPort();
-	    if (matchSrcTcpUdpPort != null)
-		match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
-	    Short matchDstTcpUdpPort = flowObj.getMatchDstTcpUdpPort();
-	    if (matchDstTcpUdpPort != null)
-		match.enableDstTcpUdpPort(matchDstTcpUdpPort);
+	    FlowEntryMatch match = extractMatch(flowObj);
 
 	    flowPath.setFlowEntryMatch(match);
 	}
@@ -758,6 +1096,7 @@
 	    flowPath.dataPath().flowEntries().add(flowEntry);
 	}
 
+    log.info("extractFlowPath: end");
 	return flowPath;
     }
 
@@ -768,18 +1107,39 @@
      * @return the extracted Flow Entry State.
      */
     public static FlowEntry extractFlowEntry(IFlowEntry flowEntryObj) {
+	log.info("extractFlowEntry: start");
 	IFlowPath flowObj = flowEntryObj.getFlow();
-	if (flowObj == null)
+	if (flowObj == null) {
+		log.error("extractFlowEntry: no flowPath exists");
 	    return null;
+	}
 
 	String flowIdStr = flowObj.getFlowId();
 	//
-	String flowEntryIdStr = flowEntryObj.getFlowEntryId();
-	Integer idleTimeout = flowEntryObj.getIdleTimeout();
-	Integer hardTimeout = flowEntryObj.getHardTimeout();
-	String switchDpidStr = flowEntryObj.getSwitchDpid();
-	String userState = flowEntryObj.getUserState();
-	String switchState = flowEntryObj.getSwitchState();
+	String flowEntryIdStr;
+	Integer idleTimeout;
+	Integer hardTimeout;
+	String switchDpidStr;
+	String userState;
+	String switchState;
+	if ( flowEntryObj.asVertex() instanceof RamCloudVertex ) {
+	    RamCloudVertex v = (RamCloudVertex)flowEntryObj.asVertex();
+	    Map<String,Object> propMap = v.getProperties();
+
+	    flowEntryIdStr = (String) propMap.get("flow_entry_id");
+	    idleTimeout = (Integer) propMap.get("idle_timeout");
+	    hardTimeout = (Integer) propMap.get("hard_timeout");
+	    switchDpidStr = (String) propMap.get("switch_dpid");
+	    userState = (String) propMap.get("user_state");
+	    switchState = (String) propMap.get("switch_state");
+	} else {
+	    flowEntryIdStr = flowEntryObj.getFlowEntryId();
+	    idleTimeout = flowEntryObj.getIdleTimeout();
+	    hardTimeout = flowEntryObj.getHardTimeout();
+	    switchDpidStr = flowEntryObj.getSwitchDpid();
+	    userState = flowEntryObj.getUserState();
+	    switchState = flowEntryObj.getSwitchState();
+	}
 
 	if ((flowIdStr == null) ||
 	    (flowEntryIdStr == null) ||
@@ -789,6 +1149,7 @@
 	    (userState == null) ||
 	    (switchState == null)) {
 	    // TODO: A work-around, because of some bogus database objects
+		log.error("extractFlowEntry: wrong properties");
 	    return null;
 	}
 
@@ -802,43 +1163,7 @@
 	//
 	// Extract the match conditions
 	//
-	FlowEntryMatch match = new FlowEntryMatch();
-	Short matchInPort = flowEntryObj.getMatchInPort();
-	if (matchInPort != null)
-	    match.enableInPort(new Port(matchInPort));
-	String matchSrcMac = flowEntryObj.getMatchSrcMac();
-	if (matchSrcMac != null)
-	    match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
-	String matchDstMac = flowEntryObj.getMatchDstMac();
-	if (matchDstMac != null)
-	    match.enableDstMac(MACAddress.valueOf(matchDstMac));
-	Short matchEthernetFrameType = flowEntryObj.getMatchEthernetFrameType();
-	if (matchEthernetFrameType != null)
-	    match.enableEthernetFrameType(matchEthernetFrameType);
-	Short matchVlanId = flowEntryObj.getMatchVlanId();
-	if (matchVlanId != null)
-	    match.enableVlanId(matchVlanId);
-	Byte matchVlanPriority = flowEntryObj.getMatchVlanPriority();
-	if (matchVlanPriority != null)
-	    match.enableVlanPriority(matchVlanPriority);
-	String matchSrcIPv4Net = flowEntryObj.getMatchSrcIPv4Net();
-	if (matchSrcIPv4Net != null)
-	    match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
-	String matchDstIPv4Net = flowEntryObj.getMatchDstIPv4Net();
-	if (matchDstIPv4Net != null)
-	    match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
-	Byte matchIpProto = flowEntryObj.getMatchIpProto();
-	if (matchIpProto != null)
-	    match.enableIpProto(matchIpProto);
-	Byte matchIpToS = flowEntryObj.getMatchIpToS();
-	if (matchIpToS != null)
-	    match.enableIpToS(matchIpToS);
-	Short matchSrcTcpUdpPort = flowEntryObj.getMatchSrcTcpUdpPort();
-	if (matchSrcTcpUdpPort != null)
-	    match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
-	Short matchDstTcpUdpPort = flowEntryObj.getMatchDstTcpUdpPort();
-	if (matchDstTcpUdpPort != null)
-	    match.enableDstTcpUdpPort(matchDstTcpUdpPort);
+	FlowEntryMatch match = extractMatch(flowEntryObj);
 	flowEntry.setFlowEntryMatch(match);
 
 	//
@@ -854,6 +1179,101 @@
 	//
 	// TODO: Take care of FlowEntryErrorState.
 	//
+	log.info("extractFlowEntry: end");
 	return flowEntry;
     }
+
+    /**
+     * Extract FlowEntryMatch from IFlowPath or IFlowEntry
+     * @param flowObj : either IFlowPath or IFlowEntry
+     * @return extracted Match info
+     */
+    private static FlowEntryMatch extractMatch(IBaseObject flowObj) {
+	FlowEntryMatch match = new FlowEntryMatch();
+
+	Short matchInPort = null; // Only for IFlowEntry
+	String matchSrcMac = null;
+	String matchDstMac = null;
+	Short matchEthernetFrameType = null;
+	Short matchVlanId = null;
+	Byte matchVlanPriority = null;
+	String matchSrcIPv4Net = null;
+	String matchDstIPv4Net = null;
+	Byte matchIpProto = null;
+	Byte matchIpToS = null;
+	Short matchSrcTcpUdpPort = null;
+	Short matchDstTcpUdpPort = null;
+
+	if ( flowObj.asVertex() instanceof RamCloudVertex ) {
+	    RamCloudVertex v = (RamCloudVertex)flowObj.asVertex();
+	    Map<String,Object> propMap = v.getProperties();
+	    matchInPort = (Short) propMap.get("matchInPort");
+	    matchSrcMac = (String) propMap.get("matchSrcMac");
+	    matchDstMac = (String) propMap.get("matchDstMac");
+	    matchEthernetFrameType = (Short) propMap.get("matchEthernetFrameType");
+	    matchVlanId = (Short) propMap.get("matchVlanId");
+	    matchVlanPriority = (Byte) propMap.get("matchVlanPriority");
+	    matchSrcIPv4Net = (String) propMap.get("matchSrcIPv4Net");
+	    matchDstIPv4Net = (String) propMap.get("matchDstIPv4Net");
+	    matchIpProto = (Byte) propMap.get("matchIpProto");
+	    matchIpToS = (Byte) propMap.get("matchIpToS");
+	    matchSrcTcpUdpPort = (Short) propMap.get("matchSrcTcpUdpPort");
+	    matchDstTcpUdpPort = (Short) propMap.get("matchDstTcpUdpPort");
+	} else {
+	    if (flowObj instanceof IFlowEntry ){
+		IFlowEntry flowEntry = (IFlowEntry) flowObj;
+		matchInPort = flowEntry.getMatchInPort();
+		matchSrcMac = flowEntry.getMatchSrcMac();
+		matchDstMac = flowEntry.getMatchDstMac();
+		matchEthernetFrameType = flowEntry.getMatchEthernetFrameType();
+		matchVlanId = flowEntry.getMatchVlanId();
+		matchVlanPriority = flowEntry.getMatchVlanPriority();
+		matchSrcIPv4Net = flowEntry.getMatchSrcIPv4Net();
+		matchDstIPv4Net = flowEntry.getMatchDstIPv4Net();
+		matchIpProto = flowEntry.getMatchIpProto();
+		matchIpToS = flowEntry.getMatchIpToS();
+		matchSrcTcpUdpPort = flowEntry.getMatchSrcTcpUdpPort();
+		matchDstTcpUdpPort = flowEntry.getMatchDstTcpUdpPort();
+	    } else if(flowObj instanceof IFlowPath) {
+		IFlowPath flowPath = (IFlowPath) flowObj;
+		matchSrcMac = flowPath.getMatchSrcMac();
+		matchDstMac = flowPath.getMatchDstMac();
+		matchEthernetFrameType = flowPath.getMatchEthernetFrameType();
+		matchVlanId = flowPath.getMatchVlanId();
+		matchVlanPriority = flowPath.getMatchVlanPriority();
+		matchSrcIPv4Net = flowPath.getMatchSrcIPv4Net();
+		matchDstIPv4Net = flowPath.getMatchDstIPv4Net();
+		matchIpProto = flowPath.getMatchIpProto();
+		matchIpToS = flowPath.getMatchIpToS();
+		matchSrcTcpUdpPort = flowPath.getMatchSrcTcpUdpPort();
+		matchDstTcpUdpPort = flowPath.getMatchDstTcpUdpPort();
+	    }
+	}
+
+	if (matchInPort != null)
+	    match.enableInPort(new Port(matchInPort));
+	if (matchSrcMac != null)
+	    match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
+	if (matchDstMac != null)
+	    match.enableDstMac(MACAddress.valueOf(matchDstMac));
+	if (matchEthernetFrameType != null)
+	    match.enableEthernetFrameType(matchEthernetFrameType);
+	if (matchVlanId != null)
+	    match.enableVlanId(matchVlanId);
+	if (matchVlanPriority != null)
+	    match.enableVlanPriority(matchVlanPriority);
+	if (matchSrcIPv4Net != null)
+	    match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
+	if (matchDstIPv4Net != null)
+	    match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
+	if (matchIpProto != null)
+	    match.enableIpProto(matchIpProto);
+	if (matchIpToS != null)
+	    match.enableIpToS(matchIpToS);
+	if (matchSrcTcpUdpPort != null)
+	    match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
+	if (matchDstTcpUdpPort != null)
+	    match.enableDstTcpUdpPort(matchDstTcpUdpPort);
+	return match;
+    }
 }
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEntryProperty.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEntryProperty.java
new file mode 100644
index 0000000..7b17aaa
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEntryProperty.java
@@ -0,0 +1,150 @@
+package net.onrc.onos.ofcontroller.flowmanager;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import net.onrc.onos.graph.DBOperation;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
+
+public class FlowEntryProperty {
+    private Map<String, Object> map = new HashMap<>();
+    private DBOperation dbhandler;
+    private IFlowEntry flowEntry;
+    
+    public FlowEntryProperty(DBOperation dbHandler, IFlowEntry flowEntry) {
+        this.dbhandler = dbHandler;
+        this.flowEntry = flowEntry;
+    }
+    
+    public void setFlowId(String value) {
+        map.put("flow_id", value);
+    }
+    
+    public void setUserState(String value) {
+        map.put("user_state", value);
+    }
+    
+    public void setFlowEntryId(String value) {
+        map.put("flow_entry_id", value);
+    }
+    
+    public void setType(String value) {
+        map.put("type", value);
+    }
+    
+    public void setInstallerId(String value) {
+        map.put("installer_id", value);
+    }
+    
+    public void setFlowPathType(String value) {
+        map.put("flow_path_type", value);
+    }
+    
+    public void setFlowPathUserState(String value) {
+        map.put("user_state", value);
+    }
+    
+    public void flow_path_flags(Long value) {
+        map.put("flow_path_flags", value);
+    }
+    
+    public void setIdleTimeout(Integer value) {
+        map.put("idle_timeout", value);
+    }
+    
+    public void setHardTimeout(Integer value) {
+        map.put("hard_timeout", value);
+    }
+    
+    public void setSwitchDpid(String value) {
+        map.put("switch_dpid", value);
+    }
+    
+    public void setSwitchState(String value) {
+        map.put("switch_state", value);
+    }
+    
+    public void setSrcSwitch(String value) {
+        map.put("src_switch", value);
+    }
+    
+    public void setSrcPort(Short value) {
+        map.put("src_port", value);
+    }
+    
+    public void setDstSwitch(String value) {
+        map.put("dst_switch", value);
+    }
+    
+    public void setDstPort(Short value) {
+        map.put("dst_port", value);
+    }
+    
+    public void setMatchSrcMac(String value) {
+        map.put("matchSrcMac", value);
+    }
+    
+    public void setMatchDstMac(String value) {
+        map.put("matchDstMac", value);
+    }
+    
+    public void setMatchEthernetFrameType(Short value) {
+        map.put("matchEthernetFrameType", value);
+    }
+    
+    public void setMatchVlanId(Short value) {
+        map.put("matchVlanId", value);
+    }
+    
+    public void setMatchVlanPriority(Byte value) {
+        map.put("matchVlanPriority", value);
+    }
+    
+    public void setMatchSrcIPv4Net(String value) {
+        map.put("matchSrcIPv4Net", value);
+    }
+    
+    public void setMatchDstIPv4Net(String value) {
+        map.put("matchDstIPv4Net", value);
+    }
+    
+    public void setMatchIpProto(Byte value) {
+        map.put("matchIpProto", value);
+    }
+    
+    public void setMatchIpToS(Byte value) {
+        map.put("matchIpToS", value);
+    }
+    
+    public void setMatchInPort(Short value) {
+        map.put("matchInPort", value);
+    }
+    
+    public void setMatchSrcTcpUdpPort(Short value) {
+        map.put("matchSrcTcpUdpPort", value);
+    }
+    
+    public void setMatchDstTcpUdpPort(Short value) {
+        map.put("matchDstTcpUdpPort", value);
+    }
+    
+    public void setActions(String value) {
+        map.put("actions", value);
+    }
+    
+    public void setActionOutputPort(Short value) {
+        map.put("actionOutputPort", value);
+    }
+    
+    public void setDataPathSummary(String value) {
+        map.put("data_path_summary", value);
+    }
+    
+    /**
+     *
+     * @param dbhandler
+     */
+    public void commitProperties() {
+        dbhandler.setVertexProperties(flowEntry.asVertex() ,map);
+    }
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java
index 662e81b..ba1e448 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java
@@ -8,15 +8,17 @@
 import java.util.List;
 import java.util.Map;
 import java.util.SortedMap;
+import java.util.Timer;
+import java.util.TimerTask;
 import java.util.TreeMap;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.LinkedBlockingQueue;
 
 import net.floodlightcontroller.core.IOFSwitch;
 import net.floodlightcontroller.core.IOFSwitchListener;
-
 import net.onrc.onos.datagrid.IDatagridService;
-import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.graph.DBOperation;
+import net.onrc.onos.graph.GraphDBManager;
 import net.onrc.onos.ofcontroller.topology.Topology;
 import net.onrc.onos.ofcontroller.topology.TopologyElement;
 import net.onrc.onos.ofcontroller.topology.TopologyManager;
@@ -38,6 +40,7 @@
 import net.onrc.onos.ofcontroller.util.serializers.KryoFactory;
 
 import com.esotericsoftware.kryo2.Kryo;
+import com.tinkerpop.blueprints.impls.ramcloud.PerfMon;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -58,7 +61,7 @@
     /** The logger. */
     private final static Logger log = LoggerFactory.getLogger(FlowEventHandler.class);
 
-    private GraphDBOperation dbHandler;
+    private DBOperation dbHandler;
 
     private FlowManager flowManager;		// The Flow Manager to use
     private IDatagridService datagridService;	// The Datagrid Service to use
@@ -127,7 +130,7 @@
      * Startup processing.
      */
     private void startup() {
-	this.dbHandler = new GraphDBOperation("");
+	this.dbHandler = GraphDBManager.getDBOperation("ramcloud", "/tmp/ramcloudconf");
 
 	//
 	// Obtain the initial Topology state
@@ -184,6 +187,7 @@
 	synchronized (allFlowPaths) {
 	    processEvents();
 	}
+
     }
 
     /**
@@ -900,10 +904,14 @@
 
 	    switch (eventEntry.eventType()) {
 	    case ENTRY_ADD:
-		isTopologyModified |= topology.addTopologyElement(topologyElement);
+    	synchronized (topology) {
+    		isTopologyModified |= topology.addTopologyElement(topologyElement);
+    	}
 		break;
 	    case ENTRY_REMOVE:
-		isTopologyModified |= topology.removeTopologyElement(topologyElement);
+    	synchronized (topology) {
+    		isTopologyModified |= topology.removeTopologyElement(topologyElement);
+    	}
 		break;
 	    }
 	}
@@ -1200,9 +1208,11 @@
 	DataPath oldDataPath = flowPath.dataPath();
 
 	// Compute the new path
-	DataPath newDataPath = TopologyManager.computeNetworkPath(topology,
+	DataPath newDataPath;
+	synchronized (topology) {
+	newDataPath = TopologyManager.computeNetworkPath(topology,
 								  flowPath);
-	
+	}
 	if (newDataPath == null) {
 	    // We need the DataPath to compare the paths
 	    newDataPath = new DataPath();
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
index 5651f73..791008d 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
@@ -19,8 +19,10 @@
 import net.floodlightcontroller.core.module.IFloodlightModule;
 import net.floodlightcontroller.core.module.IFloodlightService;
 import net.floodlightcontroller.restserver.IRestApiService;
+import net.floodlightcontroller.util.OFMessageDamper;
+import net.onrc.onos.graph.DBOperation;
+import net.onrc.onos.graph.GraphDBManager;
 import net.onrc.onos.datagrid.IDatagridService;
-import net.onrc.onos.graph.GraphDBOperation;
 import net.onrc.onos.ofcontroller.core.INetMapStorage;
 import net.onrc.onos.ofcontroller.floodlightlistener.INetworkGraphService;
 import net.onrc.onos.ofcontroller.flowmanager.web.FlowWebRoutable;
@@ -51,8 +53,8 @@
 
     private boolean enableOnrc2014MeasurementsFlows = true;
 
-    protected GraphDBOperation dbHandlerApi;
-    protected GraphDBOperation dbHandlerInner;
+    protected DBOperation dbHandlerApi;
+    protected DBOperation dbHandlerInner;
 
     protected volatile IFloodlightProviderService floodlightProvider;
     protected volatile IDatagridService datagridService;
@@ -84,9 +86,13 @@
      * @param conf the Graph Database configuration string.
      */
     @Override
-    public void init(String conf) {
-    	dbHandlerApi = new GraphDBOperation(conf);
-    	dbHandlerInner = new GraphDBOperation(conf);
+    public void init(final String dbStore, final String conf) {
+	dbHandlerApi = GraphDBManager.getDBOperation("ramcloud", "/tmp/ramcloudconf");
+	dbHandlerInner = GraphDBManager.getDBOperation("ramcloud", "/tmp/ramcloudconf");
+
+	//dbHandlerApi = GraphDBManager.getDBOperation(dbStore, conf);
+	//dbHandlerInner = GraphDBManager.getDBOperation(dbStore, conf);
+	
     }
 
     /**
@@ -176,7 +182,7 @@
 	pusher = context.getServiceImpl(IFlowPusherService.class);
 	forwardingService = context.getServiceImpl(IForwardingService.class);
 
-	this.init("");
+	this.init("","");
     }
 
     /**
@@ -828,15 +834,25 @@
 	    do {
 		retry = false;
 		try {
+                    long startTime = System.nanoTime();
 		    if (! FlowDatabaseOperation.addFlow(dbHandlerInner, flowPath)) {
 			log.error("Cannot write to Network Map Flow Path {}", flowPath.flowId());
 			retry = true;
 		    }
+ 		    // FIXME Flag to turn ON logging
+                    //long endTime = System.nanoTime();
+                    //log.error("Performance %% Flow path total time {} : {}", endTime - startTime, flowPath.toString());
 		} catch (TitanException te) {
 		    log.error("Titan Exception writing Flow Path to Network MAP: ", te);
 		    retry = true;
+ 		    // FIXME Flag to turn ON logging
+                    //long endTime = System.nanoTime();
+                    //log.error("Performance %% Flow path total time {} : {}", endTime - startTime, flowPath.toString());
 		} catch (Exception e) {
 		    log.error("Exception writing Flow Path to Network MAP: ", e);
+ 		    // FIXME Flag to turn ON logging
+                    //long endTime = System.nanoTime();
+                    //log.error("Performance %% Flow path total time {} : {}", endTime - startTime, flowPath.toString());
 		}
 	    } while (retry);
 
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowPathProperty.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowPathProperty.java
new file mode 100644
index 0000000..c6a2b98
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowPathProperty.java
@@ -0,0 +1,126 @@
+package net.onrc.onos.ofcontroller.flowmanager;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import net.onrc.onos.graph.DBOperation;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
+
+public class FlowPathProperty {
+	private Map<String, Object> map = new HashMap<>();
+	private DBOperation dbhandler;
+	private IFlowPath flowPath;
+
+	public FlowPathProperty(DBOperation dbHandler, IFlowPath flowPath) {
+		this.dbhandler = dbHandler;
+		this.flowPath = flowPath;
+	}
+
+	public void setType(String typeStr) {
+		map.put("type", typeStr);
+	}
+
+	public void setFlowId(String flowId) {
+		map.put("flow_id", flowId);
+	}
+
+	public void setInstallerId(String installerId) {
+		map.put("installer_id", installerId);
+	}
+
+	public void setFlowPathType(String flowPathType) {
+		map.put("flow_path_type", flowPathType);
+	}
+
+	public void setFlowPathUserState(String userState) {
+		map.put("user_state", userState);
+	}
+
+	public void setFlowPathFlags(Long flowPathFlags) {
+		map.put("flow_path_flags", flowPathFlags);
+	}
+
+	public void setIdleTimeout(Integer idleTimeout) {
+		map.put("idle_timeout", idleTimeout);
+	}
+
+	public void setHardTimeout(Integer hardTimeout) {
+		map.put("hard_timeout", hardTimeout);
+	}
+
+	public void setSrcSwitch(String srcSwitch) {
+		map.put("src_switch", srcSwitch);
+	}
+
+	public void setSrcPort(Short srcPort) {
+		map.put("src_port", srcPort);
+	}
+
+	public void setDstSwitch(String dstSwitch) {
+		map.put("dst_switch", dstSwitch);
+	}
+
+	public void setDstPort(Short dstPort) {
+		map.put("dst_port", dstPort);
+	}
+
+	public void setDataPathSummary(String dataPathSummary) {
+		map.put("data_path_summary", dataPathSummary);
+	}
+
+	public void setMatchSrcMac(String matchSrcMac) {
+		map.put("matchSrcMac", matchSrcMac);
+	}
+
+	public void setMatchDstMac(String matchDstMac) {
+		map.put("matchDstMac", matchDstMac);
+	}
+
+	public void setMatchEthernetFrameType(Short matchEthernetFrameType) {
+		map.put("matchEthernetFrameType", matchEthernetFrameType);
+	}
+
+	public void setMatchVlanId(Short matchVlanId) {
+		map.put("matchVlanId", matchVlanId);
+	}
+
+	public void setMatchVlanPriority(Byte matchVlanPriority) {
+		map.put("matchVlanPriority", matchVlanPriority);
+	}
+
+	public void setMatchSrcIPv4Net(String matchSrcIPv4Net) {
+		map.put("matchSrcIPv4Net", matchSrcIPv4Net);
+	}
+
+	public void setMatchDstIPv4Net(String matchDstIPv4Net) {
+		map.put("matchDstIPv4Net", matchDstIPv4Net);
+	}
+
+	public void setMatchIpProto(Byte matchIpProto) {
+		map.put("matchIpProto", matchIpProto);
+	}
+
+	public void setMatchIpToS(Byte matchIpToS) {
+		map.put("matchIpToS", matchIpToS);
+	}
+
+	public void setMatchSrcTcpUdpPort(Short matchSrcTcpUdpPort) {
+		map.put("matchSrcTcpUdpPort", matchSrcTcpUdpPort);
+	}
+
+	public void setMatchDstTcpUdpPort(Short matchDstTcpUdpPort) {
+		map.put("matchDstTcpUdpPort", matchDstTcpUdpPort);
+	}
+
+	public void setActions(String actionsStr) {
+		map.put("actions", actionsStr);
+	}
+    
+    /**
+     *
+     * @param dbhandler
+     */
+    public void commitProperties() {
+        dbhandler.setVertexProperties(flowPath.asVertex() ,map);
+    }
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/ParallelFlowDatabaseOperation.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/ParallelFlowDatabaseOperation.java
index 50834d2..5d9af5a 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/ParallelFlowDatabaseOperation.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/ParallelFlowDatabaseOperation.java
@@ -16,7 +16,7 @@
 import org.slf4j.LoggerFactory;
 
 import net.onrc.onos.datagrid.IDatagridService;
-import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.graph.DBOperation;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
 import net.onrc.onos.ofcontroller.util.Dpid;
 import net.onrc.onos.ofcontroller.util.FlowEntry;
@@ -45,7 +45,7 @@
      * @param dbHandler the Graph Database handler to use.
      * @return the Flow Paths if found, otherwise an empty list.
      */
-    static ArrayList<FlowPath> getAllFlows(GraphDBOperation dbHandler) {
+    static ArrayList<FlowPath> getAllFlows(DBOperation dbHandler) {
 	Iterable<IFlowPath> flowPathsObj = null;
 	ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
 
@@ -92,7 +92,7 @@
      * @param switches a collection of switches whose flow paths you want
      * @return the Flow Paths if found, otherwise an empty list.
      */
-    static ArrayList<FlowPath> getFlowsForSwitches(GraphDBOperation dbHandler, Collection<Dpid> switches) {
+    static ArrayList<FlowPath> getFlowsForSwitches(DBOperation dbHandler, Collection<Dpid> switches) {
 	Iterable<IFlowPath> flowPathsObj = null;
 	ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
 
@@ -161,7 +161,7 @@
      * @param flowIds the collection of Flow IDs to get.
      * @return the Flow Paths if found, otherwise an empty list.
      */
-    static ArrayList<FlowPath> getFlows(GraphDBOperation dbHandler,
+    static ArrayList<FlowPath> getFlows(DBOperation dbHandler,
 		  			Collection<FlowId> flowIds) {
 	ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
 
@@ -192,10 +192,10 @@
      * This is simply a wrapper for FlowDatabaseOperation.getFlow()
      */
     private final static class GetFlowTask implements Callable<FlowPath> {
-	private final GraphDBOperation dbHandler;
+	private final DBOperation dbHandler;
 	private final FlowId flowId;
-	
-	GetFlowTask(GraphDBOperation dbHandler, FlowId flowId) {
+
+	GetFlowTask(DBOperation dbHandler, FlowId flowId) {
 	    this.dbHandler = dbHandler;
 	    this.flowId = flowId;
 	}
@@ -214,7 +214,7 @@
      * @param flowPath the Flow Path to install.
      * @return true on success, otherwise false.
      */
-    static boolean addFlow(GraphDBOperation dbHandler, FlowPath flowPath) {
+    static boolean addFlow(DBOperation dbHandler, FlowPath flowPath) {
 	Future<Boolean> result = executor.submit(new AddFlowTask(dbHandler, flowPath, null));
 	// NOTE: This function is blocking
 	try {
@@ -232,7 +232,7 @@
      * @param datagridService the notification service for when the task is completed
      * @return true always
      */
-    static boolean addFlow(GraphDBOperation dbHandler, FlowPath flowPath, IDatagridService datagridService) {
+    static boolean addFlow(DBOperation dbHandler, FlowPath flowPath, IDatagridService datagridService) {
 	executor.submit(new AddFlowTask(dbHandler, flowPath, datagridService));
 	// TODO: If we need the results, submit returns a Future that contains
 	// the result. 
@@ -247,11 +247,11 @@
      * which also sends a notification if a datagrid services is provided
      */
     private final static class AddFlowTask implements Callable<Boolean> {
-	private final GraphDBOperation dbHandler;
+	private final DBOperation dbHandler;
 	private final FlowPath flowPath;
 	private final IDatagridService datagridService;
-	
-	AddFlowTask(GraphDBOperation dbHandler, 
+
+	AddFlowTask(DBOperation dbHandler,
 		    FlowPath flowPath,
 		    IDatagridService datagridService) {
 	    this.dbHandler = dbHandler;
@@ -321,7 +321,7 @@
      * @param flowId the Flow ID of the flow to delete.
      * @return true on success, otherwise false.
      */
-    static boolean deleteFlow(GraphDBOperation dbHandler, FlowId flowId) {
+    static boolean deleteFlow(DBOperation dbHandler, FlowId flowId) {
 	Future<Boolean> result = executor.submit(new DeleteFlowTask(dbHandler, flowId, null));
 	// NOTE: This function is blocking
 	try {
@@ -339,7 +339,7 @@
      * @param datagridService the notification service for when the task is completed
      * @return true always
      */
-    static boolean deleteFlow(GraphDBOperation dbHandler, FlowId flowId, IDatagridService datagridService) {
+    static boolean deleteFlow(DBOperation dbHandler, FlowId flowId, IDatagridService datagridService) {
 	executor.submit(new DeleteFlowTask(dbHandler, flowId, datagridService));
 	// TODO: If we need the results, submit returns a Future that contains
 	// the result. 
@@ -353,11 +353,11 @@
      * which also sends a notification if a datagrid services is provided
      */
     private final static class DeleteFlowTask implements Callable<Boolean> {
-	private final GraphDBOperation dbHandler;
+	private final DBOperation dbHandler;
 	private final FlowId flowId;
 	private final IDatagridService datagridService;
-	
-	DeleteFlowTask(GraphDBOperation dbHandler, FlowId flowId, IDatagridService datagridService) {
+
+	DeleteFlowTask(DBOperation dbHandler, FlowId flowId, IDatagridService datagridService) {
 	    this.dbHandler = dbHandler;
 	    this.flowId = flowId;
 	    this.datagridService = datagridService;
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizer.java b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizer.java
index ab2b31d..949cc7b 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizer.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizer.java
@@ -24,7 +24,8 @@
 import org.slf4j.LoggerFactory;
 
 import net.floodlightcontroller.core.IOFSwitch;
-import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.graph.DBOperation;
+import net.onrc.onos.graph.GraphDBManager;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
 import net.onrc.onos.ofcontroller.flowmanager.FlowDatabaseOperation;
@@ -44,14 +45,13 @@
 
     private static Logger log = LoggerFactory.getLogger(FlowSynchronizer.class);
 
-    private GraphDBOperation dbHandler;
+    private DBOperation dbHandler;
     protected IFlowPusherService pusher;
     private Map<IOFSwitch, FutureTask<SyncResult>> switchThreads; 
 
     public FlowSynchronizer() {
-	dbHandler = new GraphDBOperation("");
-	switchThreads = new HashMap<IOFSwitch, FutureTask<SyncResult>>();
-    }
+	dbHandler = GraphDBManager.getDBOperation("ramcloud", "/tmp/ramcloudconf");
+	switchThreads = new HashMap<IOFSwitch, FutureTask<SyncResult>>();    }
 
     @Override
     public Future<SyncResult> synchronize(IOFSwitch sw) {
diff --git a/src/main/java/net/onrc/onos/ofcontroller/forwarding/Forwarding.java b/src/main/java/net/onrc/onos/ofcontroller/forwarding/Forwarding.java
index 8ca3989..85d122d 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/forwarding/Forwarding.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/forwarding/Forwarding.java
@@ -196,9 +196,9 @@
 		waitingPackets = LinkedListMultimap.create();
 		
 		deviceStorage = new DeviceStorageImpl();
-		deviceStorage.init("");
+		deviceStorage.init("","");
 		topologyService = new TopologyManager();
-		topologyService.init("");
+		topologyService.init("","");
 	}
 	
 	@Override
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/BgpProxyArpManager.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/BgpProxyArpManager.java
index 801e414..3dba4f8 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/BgpProxyArpManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/BgpProxyArpManager.java
@@ -143,7 +143,7 @@
 		floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
 		
 		deviceStorage = new DeviceStorageImpl();
-		deviceStorage.init("");
+		deviceStorage.init("","");
 		
 		Timer arpTimer = new Timer("arp-processing");
 		arpTimer.scheduleAtFixedRate(new TimerTask() {
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
index 289e0e2..2b4b0b1 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
@@ -184,7 +184,7 @@
 		datagrid.registerArpEventHandler(this);
 		
 		deviceStorage = new DeviceStorageImpl();
-		deviceStorage.init("");
+		deviceStorage.init("","");
 		
 		Timer arpTimer = new Timer("arp-processing");
 		arpTimer.scheduleAtFixedRate(new TimerTask() {
diff --git a/src/main/java/net/onrc/onos/ofcontroller/topology/ShortestPath.java b/src/main/java/net/onrc/onos/ofcontroller/topology/ShortestPath.java
index 9a8345c..d9e1314 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/topology/ShortestPath.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/topology/ShortestPath.java
@@ -9,7 +9,7 @@
 import java.util.Queue;
 import java.util.Set;
 
-import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.graph.DBOperation;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
 import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
 import net.onrc.onos.ofcontroller.util.DataPath;
@@ -163,7 +163,7 @@
      * @return the data path with the computed shortest path if
      * found, otherwise null.
      */
-    public static DataPath getDatabaseShortestPath(GraphDBOperation dbHandler,
+    public static DataPath getDatabaseShortestPath(DBOperation dbHandler,
 					     SwitchPort src, SwitchPort dest) {
 	DataPath result_data_path = new DataPath();
 
@@ -326,4 +326,4 @@
 
 	return null;
     }
-}
\ No newline at end of file
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/topology/Topology.java b/src/main/java/net/onrc/onos/ofcontroller/topology/Topology.java
index d1f2af4..9fca86a 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/topology/Topology.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/topology/Topology.java
@@ -5,7 +5,7 @@
 import java.util.Map;
 import java.util.TreeMap;
 
-import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.graph.DBOperation;
 import net.onrc.onos.graph.IDBOperation;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
@@ -28,7 +28,7 @@
      * paths.
      */
     class Link {
-    	public Node me;                        // The node this link originates from
+        public Node me;                        // The node this link originates from
         public Node neighbor;                // The neighbor node on the other side
         public int myPort;                // Local port ID for the link
         public int neighborPort;        // Neighbor port ID for the link
@@ -392,7 +392,7 @@
      *
      * @param dbHandler the Graph Database handler to use.
      */
-    public void readFromDatabase(GraphDBOperation dbHandler) {
+    public void readFromDatabase(DBOperation dbHandler) {
     	if (enableOptimizedRead) {
     		readFromDatabaseBodyOptimized(dbHandler);
     	} else {
@@ -400,8 +400,8 @@
     	}
 
     }
-    
-    private void readFromDatabaseBody(GraphDBOperation dbHandler) {
+
+    private void readFromDatabaseBody(DBOperation dbHandler) {
     	//
     	// Fetch the relevant info from the Switch and Port vertices
     	// from the Titan Graph.
@@ -472,8 +472,8 @@
     	}
     	dbHandler.commit();
     }
-    
-    private void readFromDatabaseBodyOptimized(GraphDBOperation dbHandler) {
+
+    private void readFromDatabaseBodyOptimized(DBOperation dbHandler) {
 	    nodesMap.clear();
 		    
 		// Load all switches into Map
diff --git a/src/main/java/net/onrc/onos/ofcontroller/topology/TopologyManager.java b/src/main/java/net/onrc/onos/ofcontroller/topology/TopologyManager.java
index 4feaa8e..a074d19 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/topology/TopologyManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/topology/TopologyManager.java
@@ -12,7 +12,8 @@
 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.graph.DBOperation;
+import net.onrc.onos.graph.GraphDBManager;
 import net.onrc.onos.ofcontroller.floodlightlistener.INetworkGraphService;
 import net.onrc.onos.ofcontroller.topology.web.OnosTopologyWebRoutable;
 import net.onrc.onos.ofcontroller.util.DataPath;
@@ -35,7 +36,10 @@
     private final static Logger log = LoggerFactory.getLogger(TopologyManager.class);
     protected IFloodlightProviderService floodlightProvider;
 
-    protected GraphDBOperation dbHandler;
+    protected static final String DBConfigFile = "dbconf";
+    protected static final String GraphDBStore = "graph_db_store";
+
+    protected DBOperation dbHandler;
     protected IRestApiService restApi;
 
 
@@ -51,8 +55,11 @@
      * @param config the database configuration file to use for
      * the initialization.
      */
-    public TopologyManager(String config) {
-	this.init(config);
+    public TopologyManager(FloodlightModuleContext context) {
+	Map<String, String> configMap = context.getConfigParams(this);
+	String conf = configMap.get(DBConfigFile);
+        String dbStore = configMap.get(GraphDBStore);
+	this.init(dbStore,conf);
     }
 
     /**
@@ -61,19 +68,20 @@
      * @param dbHandler the database operation handler to use for the
      * initialization.
      */
-    public TopologyManager(GraphDBOperation dbHandler) {
+    public TopologyManager(DBOperation dbHandler) {
 	this.dbHandler = dbHandler;
     }
 
     /**
      * Init the module.
-     *
+     * @param 
      * @param config the database configuration file to use for
      * the initialization.
      */
-    public void init(String config) {
+    public void init(final String dbStore, String config) {
 	try {
-	    dbHandler = new GraphDBOperation(config);
+	    dbHandler = GraphDBManager.getDBOperation("ramcloud", "/tmp/ramcloudconf");
+	    //dbHandler = GraphDBManager.getDBOperation(dbStore, config);
 	} catch (Exception e) {
 	    log.error(e.getMessage());
 	}
@@ -149,9 +157,10 @@
 	throws FloodlightModuleException {
 	floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
 	restApi = context.getServiceImpl(IRestApiService.class);
-
-	String conf = "";
-	this.init(conf);
+	Map<String, String> configMap = context.getConfigParams(this);
+	String conf = configMap.get(DBConfigFile);
+        String dbStore = configMap.get(GraphDBStore);
+	this.init(dbStore, conf);
     }
 
     /**
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 8034d44..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("/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 6f4f850..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImplTest.java
+++ /dev/null
@@ -1,786 +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;
-    private GraphDBConnection mockConn = null;
-    private GraphDBOperation mockOpe = null;
-    ISwitchStorage swSt = null;
-    
-	@Before
-	public void setUp() throws Exception {
-		
-		swSt = new SwitchStorageImpl();
-		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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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 7edc1c5..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImplTestBB.java
+++ /dev/null
@@ -1,347 +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;
-    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";
-		
-		// 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(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/core/internal/TestableLinkStorageImpl.java b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableLinkStorageImpl.java
index ecba546..8411b22 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableLinkStorageImpl.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableLinkStorageImpl.java
@@ -2,7 +2,6 @@
 
 import java.util.Set;
 
-import net.onrc.onos.ofcontroller.core.internal.LinkStorageImpl;
 
 import com.thinkaurelius.titan.core.TitanGraph;
 import com.tinkerpop.blueprints.TransactionalGraph.Conclusion;
@@ -27,7 +26,7 @@
 	}
 	
 	@Override
-	public void init(String conf){
+	public void init(final String dbStore, final String conf){
         Set<String> s = graph.getIndexedKeys(Vertex.class);
         if (!s.contains("dpid")) {
            graph.createKeyIndex("dpid", Vertex.class);
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableSwitchStorageImpl.java b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableSwitchStorageImpl.java
index e0b34e1..82d1faf 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableSwitchStorageImpl.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableSwitchStorageImpl.java
@@ -18,9 +18,9 @@
 	}
 	
 	@Override
-	public void init(String conf){
+	public void init(final String dbStore, final String conf){
         
-		super.init(conf);
+		super.init(dbStore, conf);
 		
 	}
 }
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 44573bc..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/devicemanager/internal/DeviceStorageImplTest.java
+++ /dev/null
@@ -1,519 +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;
-	DeviceStorageImpl deviceImpl;
-    private GraphDBConnection mockConn;
-    private GraphDBOperation mockOpe;
-    
-	@Before
-	public void setUp() throws Exception {
-	    deviceImpl = new DeviceStorageImpl();	
-		conf = "/dummy/path/to/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.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(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 9964ec3..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/devicemanager/internal/DeviceStorageImplTestBB.java
+++ /dev/null
@@ -1,672 +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;
-    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";
-		
-		// 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(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 b43ce1c..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/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 e054e05..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/topology/TopologyManagerTest.java
+++ /dev/null
@@ -1,241 +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.GraphDBConnection;
-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;
-    private GraphDBConnection conn = null;
-    private GraphDBOperation oper = null;
-    private TitanGraph titanGraph = null;
-    private TopologyManager topologyManager = null;
-
-    /**
-     * Setup the tests.
-     */
-    @Before
-    public void setUp() throws Exception {
-	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);
-
-	// Create the connection to the database
-	conn = GraphDBConnection.getInstance(conf);
-	oper = new GraphDBOperation(conn);
-
-	// 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);
-	}
-
-}
diff --git a/start-onos.sh b/start-onos.sh
index d8df237..a1eedcd 100755
--- a/start-onos.sh
+++ b/start-onos.sh
@@ -1,4 +1,6 @@
 #!/bin/bash
+ulimit -c unlimited
+export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${HOME}/ramcloud/bindings/java/edu/stanford/ramcloud:${HOME}/ramcloud/obj.blueprint-java
 
 # Set paths
 ONOS_HOME="${ONOS_HOME:-`dirname $0`}"
@@ -19,8 +21,10 @@
 ## If you want JaCoCo Code Coverage reports... uncomment line below
 #JVM_OPTS="$JVM_OPTS -javaagent:${ONOS_HOME}/lib/jacocoagent.jar=dumponexit=true,output=file,destfile=${LOGDIR}/jacoco.exec"
 JVM_OPTS="$JVM_OPTS -server -d64"
+#JVM_OPTS="$JVM_OPTS -server -d64 -XX:+UnlockCommercialFeatures -XX:+FlightRecorder"
+JVM_OPTS="$JVM_OPTS -Xmx4g -Xms4g -Xmn800m"
 #JVM_OPTS="$JVM_OPTS -Xmx2g -Xms2g -Xmn800m"
-JVM_OPTS="$JVM_OPTS -Xmx1g -Xms1g -Xmn800m"
+#JVM_OPTS="$JVM_OPTS -Xmx1g -Xms1g -Xmn800m"
 #JVM_OPTS="$JVM_OPTS -XX:+UseParallelGC -XX:+AggressiveOpts -XX:+UseFastAccessorMethods"
 JVM_OPTS="$JVM_OPTS -XX:+UseConcMarkSweepGC -XX:+UseAdaptiveSizePolicy -XX:+AggressiveOpts -XX:+UseFastAccessorMethods"
 JVM_OPTS="$JVM_OPTS -XX:MaxInlineSize=8192 -XX:FreqInlineSize=8192"
@@ -33,6 +37,9 @@
 		-XX:+UseCompressedOops \
 		-Dcom.sun.management.jmxremote.port=$JMX_PORT \
 		-Dcom.sun.management.jmxremote.ssl=false \
+                -Dbenchmark.measureBP=0 \
+                -Dbenchmark.measureRc=0 \
+                -Dbenchmark.measureONOS=0 \
 		-Dcom.sun.management.jmxremote.authenticate=false"
 JVM_OPTS="$JVM_OPTS -Dhazelcast.logging.type=slf4j"
 
@@ -112,6 +119,9 @@
   echo $ONOS_HOME
   cd ${ONOS_HOME}
   pwd
+  echo "${MVN} exec:exec -Dexec.executable=\"java\" -Dexec.args=\"${JVM_OPTS} -Dlogback.configurationFile=${ONOS_LOGBACK} -cp %classpath ${MAIN_CLASS} -cf ${ONOS_PROPS}\""
+
+  #${MVN} exec:exec -Dexec.executable="java" -Dexec.args="${JVM_OPTS} -Dlogback.configurationFile=${ONOS_LOGBACK} -cp %classpath ${MAIN_CLASS} -cf ${ONOS_PROPS}" > ${LOGDIR}/onos.`hostname`.stdout 2>${LOGDIR}/onos.`hostname`.stderr &
   java ${JVM_OPTS} -Dlogback.configurationFile=${ONOS_LOGBACK} -cp ${JAVA_CP} ${MAIN_CLASS} -cf ${ONOS_PROPS} > ${LOGDIR}/onos.`hostname`.stdout 2>${LOGDIR}/onos.`hostname`.stderr &
 
   echo "Waiting for ONOS to start..."
@@ -163,7 +173,7 @@
 case "$1" in
   start)
     stop
-    check_db
+#    check_db
     start
     ;;
   startnokill)
diff --git a/start-ramcloud.sh b/start-ramcloud.sh
new file mode 100755
index 0000000..161dc62
--- /dev/null
+++ b/start-ramcloud.sh
@@ -0,0 +1,79 @@
+#!/bin/bash
+
+# Set paths
+ONOS_HOME=`dirname $0`
+RAMCLOUD_DIR=${HOME}/ramcloud
+LOGDIR=${ONOS_HOME}/ONOS/onos-logs
+RAMCLOUD_LOG=${LOGDIR}/ramcloud.`hostname`.log
+RAMCLOUD_COORDINATOR="fast+udp:host=10.128.4.104,port=12246"
+RAMCLOUD_SERVER="fast+udp:host=10.128.100.35,port=12242"
+
+function lotate {
+    logfile=$1
+    nr_max=${2:-10}
+    if [ -f $logfile ]; then
+	for i in `seq $(expr $nr_max - 1) -1 1`; do
+	    if [ -f ${logfile}.${i} ]; then
+		mv -f ${logfile}.${i} ${logfile}.`expr $i + 1`
+	    fi
+	done
+	mv $logfile $logfile.1
+    fi
+}
+
+function start {
+  if [ ! -d ${LOGDIR} ]; then
+    mkdir -p ${LOGDIR}
+  fi
+  echo "rotate log: $log"
+  if [ -f $RAMCLOUD_LOG ]; then
+    lotate $RAMCLOUD_LOG
+  fi
+
+  # Run ramcloud 
+  echo "Starting ramcloud"
+  export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${HOME}/ramcloud/bindings/java/edu/stanford/ramcloud:${HOME}/ramcloud/obj.blueprint-java
+  $RAMCLOUD_DIR/obj/server -M -r 0 -L $RAMCLOUD_SERVER  -C $RAMCLOUD_COORDINATOR > $RAMCLOUD_LOG 2>&1 &
+}
+
+function stop {
+  # Kill the existing processes
+  capid=`ps -edalf |grep ramcloud |grep obj/server | awk '{print $4}'`
+  pids="$capid"
+  for p in ${pids}; do
+    if [ x$p != "x" ]; then
+      kill -KILL $p
+      echo "Killed existing prosess (pid: $p)"
+    fi
+  done
+}
+
+function deldb {
+#   # Delete the berkeley db database
+   if [ -d "/tmp/ramcloud.conf" ]; then
+      echo "deleting berkeley db dir"
+      sudo rm -rf /tmp/ramcloud.conf
+   fi
+}
+
+case "$1" in
+  start)
+    deldb
+    cp $ONOS_HOME/conf/ramcloud.conf /tmp
+    stop
+    start 
+    ;;
+  stop)
+    stop
+    ;;
+#  deldb)
+#    deldb
+#    ;;
+  status)
+    n=`ps -edalf |grep ramcloud |grep obj/server | wc -l`
+    echo "$n ramcloud server running"
+    ;;
+  *)
+    echo "Usage: $0 {start|stop|restart|status}"
+    exit 1
+esac
