Merge branch 'master' of https://github.com/OPENNETWORKINGLAB/ONOS into RAMCloud

Conflicts:
	src/main/java/net/onrc/onos/ofcontroller/core/internal/DeviceStorageImpl.java
	src/main/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImpl.java
	src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoLinkServiceImpl.java
	src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoSwitchServiceImpl.java
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..ce582d0 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   -->
@@ -307,7 +309,7 @@
     <dependency>
       <groupId>com.tinkerpop.blueprints</groupId>
       <artifactId>blueprints-core</artifactId>
-      <version>2.3.0</version>
+      <version>2.4.0</version>
     </dependency>
     <dependency>
       <groupId>com.hazelcast</groupId>
@@ -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 ab775b9..0000000
--- a/src/main/java/net/onrc/onos/graph/GraphDBOperation.java
+++ /dev/null
@@ -1,447 +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<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 + 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 + 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 f873f27..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;
@@ -9,6 +13,8 @@
 import net.onrc.onos.ofcontroller.util.FlowId;
 
 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);
@@ -17,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();
@@ -39,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();
-	
+
+	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 932d422..80a6338 100644
--- a/src/main/java/net/onrc/onos/graph/LocalTopologyEventListener.java
+++ b/src/main/java/net/onrc/onos/graph/LocalTopologyEventListener.java
@@ -9,13 +9,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;		
 	}
 
@@ -33,7 +35,6 @@
 
 	}
 
-	@Override
 	public void edgeRemoved(Edge e) {
 		// TODO Auto-generated method stub
 		// Fire NetMapEvents (LinkRemoved, FlowEntryRemoved, HostRemoved, PortRemoved)
@@ -42,9 +43,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(),
@@ -71,7 +72,6 @@
 
 	}
 
-	@Override
 	public void vertexRemoved(Vertex vertex) {
 		// TODO Auto-generated method stub
 		// Generate NetMapEvents 
@@ -80,7 +80,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.
@@ -105,4 +105,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 60f8e10..aa5f073 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});
 			}
 		}
 
@@ -494,12 +505,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..3d5da10 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,24 @@
 
 	@Override
 	public void close() {
-		op.close();
+		dbop.close();
 	}
 
 	@Override
 	public List<Link> getActiveLinks() {
+<<<<<<< HEAD
+		// TODO Auto-generated method stub
+		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>(); 
+=======
 		op = new GraphDBOperation("");
 		op.commit(); //Commit to ensure we see latest data
 		Iterable<ISwitchObject> switches = op.getActiveSwitches();
 		List<Link> links = new ArrayList<Link>();
+>>>>>>> df6f52e87c8beeec9a50e4050634d70f124e9bc3
 		for (ISwitchObject sw : switches) {
 			GremlinPipeline<Vertex, Link> pipe = new GremlinPipeline<Vertex, Link>();
 			ExtractLink extractor = new ExtractLink();
@@ -52,14 +62,19 @@
 			}
 
 		}
-		op.commit();
+		dbop.commit();
 		return links;
 	}
 
 	@Override
 	public List<Link> getLinksOnSwitch(String dpid) {
+<<<<<<< HEAD
+		List<Link> links = new ArrayList<Link>(); 
+		ISwitchObject sw = dbop.searchSwitch(dpid);
+=======
 		List<Link> links = new ArrayList<Link>();
 		ISwitchObject sw = op.searchSwitch(dpid);
+>>>>>>> df6f52e87c8beeec9a50e4050634d70f124e9bc3
 		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..b5feac9 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;
@@ -9,16 +10,17 @@
 import org.slf4j.LoggerFactory;
 
 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 ea547fc..456b69c 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;
@@ -63,9 +64,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;
@@ -86,6 +88,7 @@
             Thread.currentThread().setName("SwitchCleanup@" + old);
             try {
             	log.debug("Running cleanup thread");
+		op = GraphDBManager.getDBOperation("ramcloud", "/tmp/ramcloudconf");
                 switchCleanup();
             }
             catch (Exception e) {
@@ -149,7 +152,7 @@
     }
 
     protected void switchCleanup() {
-    	op.close();
+    	//op.close();
     	Iterable<ISwitchObject> switches = op.getActiveSwitches();
 
     	log.debug("Checking for inactive switches");
@@ -445,8 +448,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);
@@ -456,14 +465,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);
 
 	}
@@ -478,9 +487,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 e075bad..af7bca8 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
@@ -4,12 +4,11 @@
 import java.io.StringWriter;
 import java.util.ArrayList;
 import java.util.LinkedList;
-import java.util.List;
+import java.util.Map;
 
 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;
@@ -19,11 +18,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.
@@ -32,14 +36,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();
@@ -64,23 +99,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 += 2;
+	}
 
 	//
 	// Set the Flow attributes:
@@ -105,59 +165,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
 
@@ -166,17 +279,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;
     }
 
@@ -188,20 +352,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",
@@ -214,14 +423,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
@@ -248,81 +466,211 @@
 	// - 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;
+	    }
 	}
 
 	// TODO: Hacks with hard-coded state names!
 	if (found)
-	    flowEntryObj.setUserState("FE_USER_MODIFY");
+		flowProp.setUserState("FE_USER_MODIFY");
 	else
-	    flowEntryObj.setUserState("FE_USER_ADD");
-	flowEntryObj.setSwitchState(flowEntry.flowEntrySwitchState().toString());
+		flowProp.setUserState("FE_USER_ADD");
+	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;
@@ -336,7 +684,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;
@@ -372,24 +720,12 @@
      * @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);
-	}
-
-	// Delete all flows one-by-one
-	for (FlowId flowId : allFlowIds) {
-	    deleteFlow(dbHandler, flowId);
+	    deleteIFlowPath(dbHandler, flowPathObj);
 	}
 
 	return true;
@@ -402,7 +738,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);
@@ -417,6 +753,12 @@
 	    return true;		// OK: No such flow
 	}
 
+	deleteIFlowPath(dbHandler, flowObj);
+
+	return true;
+    }
+
+    private static void deleteIFlowPath(DBOperation dbHandler, IFlowPath flowObj) {
 	//
 	// Remove all Flow Entries
 	//
@@ -428,8 +770,6 @@
 	// Remove the Flow itself
 	dbHandler.removeFlowPath(flowObj);
 	dbHandler.commit();
-
-	return true;
     }
 
     /**
@@ -439,7 +779,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 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>();
 
@@ -510,17 +850,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) ||
@@ -533,7 +903,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;
 	}
 
@@ -553,40 +924,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);
 	}
@@ -612,6 +950,7 @@
 	    flowPath.dataPath().flowEntries().add(flowEntry);
 	}
 
+    log.info("extractFlowPath: end");
 	return flowPath;
     }
 
@@ -622,18 +961,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) ||
@@ -643,6 +1003,7 @@
 	    (userState == null) ||
 	    (switchState == null)) {
 	    // TODO: A work-around, because of some bogus database objects
+		log.error("extractFlowEntry: wrong properties");
 	    return null;
 	}
 
@@ -656,43 +1017,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);
 
 	//
@@ -708,6 +1033,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 8b1f7c0..001fb3c 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java
@@ -8,6 +8,8 @@
 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;
@@ -32,6 +34,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;
@@ -47,6 +50,14 @@
     /** The logger. */
     private final static Logger log = LoggerFactory.getLogger(FlowEventHandler.class);
 
+    // Flag to refresh Topology object periodically
+    private final static boolean refreshTopology = false;
+    // Refresh delay(ms)
+    private final static long refreshTopologyDelay = 5000;
+    // Refresh interval(ms)
+    private final static long refreshTopologyInterval = 2000;
+    private Timer refreshTopologyTimer;
+
     private FlowManager flowManager;		// The Flow Manager to use
     private IDatagridService datagridService;	// The Datagrid Service to use
     private Topology topology;			// The network topology
@@ -141,6 +152,28 @@
 	synchronized (allFlowPaths) {
 	    processEvents();
 	}
+
+	if (refreshTopology) {
+		refreshTopologyTimer = new Timer();
+		refreshTopologyTimer.schedule(new TimerTask() {
+			@Override
+			public void run() {
+				PerfMon pm = PerfMon.getInstance();
+				log.debug("[BEFORE] {}", topology);
+				long begin, end;
+				synchronized(topology) {
+					begin = System.nanoTime();
+					pm.read_whole_topology_start();
+					topology.readFromDatabase(flowManager.dbHandlerInner);
+					pm.read_whole_topology_end();
+					end = System.nanoTime();
+				}
+				// FIXME level raised for measurement. Was debug
+				log.error("[AFTER] {}", topology);
+				log.error("refresh takes : {}[us]", (end - begin) / 1000.0);
+			}
+		}, refreshTopologyDelay, refreshTopologyInterval);
+	}
     }
 
     /**
@@ -443,10 +476,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;
 	    }
 	}
@@ -730,8 +767,12 @@
 	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 dd98f4e..de84b8e 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
@@ -18,8 +18,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;
@@ -48,8 +50,10 @@
  * Flow Manager class for handling the network flows.
  */
 public class FlowManager implements IFloodlightModule, IFlowService, INetMapStorage {
-    protected GraphDBOperation dbHandlerApi;
-    protected GraphDBOperation dbHandlerInner;
+    // flag to use FlowPusher instead of FlowSwitchOperation/MessageDamper
+    private final static boolean enableFlowPusher = false;
+    protected DBOperation dbHandlerApi;
+    protected DBOperation dbHandlerInner;
 
     protected volatile IFloodlightProviderService floodlightProvider;
     protected volatile IDatagridService datagridService;
@@ -81,9 +85,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);
+	
     }
 
     /**
@@ -172,7 +180,7 @@
 	pusher = context.getServiceImpl(IFlowPusherService.class);
 	forwardingService = context.getServiceImpl(IForwardingService.class);
 
-	this.init("");
+	this.init("","");
     }
 
     /**
@@ -748,15 +756,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/flowprogrammer/FlowSynchronizer.java b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizer.java
index 740e782..98fe262 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 4415120..65bc40b 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 fc75591..1674cf0 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/topology/Topology.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/topology/Topology.java
@@ -1,15 +1,21 @@
 package net.onrc.onos.ofcontroller.topology;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.LinkedList;
 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;
 import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
 
+import org.apache.commons.lang.StringUtils;
 import org.openflow.util.HexString;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.tinkerpop.blueprints.Direction;
 import com.tinkerpop.blueprints.Vertex;
@@ -24,36 +30,37 @@
      * paths.
      */
     class Link {
-	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
+        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
 
-	/**
-	 * Link constructor.
-	 *
-	 * @param me the node this link originates from.
-	 * @param the neighbor node on the other side of the link.
-	 * @param myPort local port ID for the link.
-	 * @param neighborPort neighbor port ID for the link.
-	 */
-	public Link(Node me, Node neighbor, int myPort, int neighborPort) {
-	    this.me = me;
-	    this.neighbor = neighbor;
-	    this.myPort = myPort;
-	    this.neighborPort = neighborPort;
-	}
+        /**
+         * Link constructor.
+         *
+         * @param me the node this link originates from.
+         * @param the neighbor node on the other side of the link.
+         * @param myPort local port ID for the link.
+         * @param neighborPort neighbor port ID for the link.
+         */
+        public Link(Node me, Node neighbor, int myPort, int neighborPort) {
+        	this.me = me;
+        	this.neighbor = neighbor;
+        	this.myPort = myPort;
+        	this.neighborPort = neighborPort;
+        }
     };
 
     public long nodeId;				// The node ID
+    // TODO Change type of PortNumber to Short
     public TreeMap<Integer, Link> links;	// The links from this node:
-						//     (src PortID -> Link)
+						//     (src PortNumber -> Link)
     private TreeMap<Integer, Link> reverseLinksMap; // The links to this node:
-						//     (dst PortID -> Link)
+						//     (dst PortNumber -> Link)
     private TreeMap<Integer, Integer> portsMap;	// The ports on this node:
-						//     (PortID -> PortID)
+						//     (PortNumber -> PortNumber)
 						// TODO: In the future will be:
-						//     (PortID -> Port)
+						//     (PortNumber -> Port)
 
     /**
      * Node constructor.
@@ -187,6 +194,8 @@
  * A class for storing topology information.
  */
 public class Topology {
+    private final static Logger log = LoggerFactory.getLogger(Topology.class);
+
     private Map<Long, Node> nodesMap;	// The dpid->Node mapping
 
     /**
@@ -382,73 +391,303 @@
      *
      * @param dbHandler the Graph Database handler to use.
      */
-    public void readFromDatabase(GraphDBOperation dbHandler) {
-	//
-	// Fetch the relevant info from the Switch and Port vertices
-	// from the Titan Graph.
-	//
-	Iterable<ISwitchObject> activeSwitches = dbHandler.getActiveSwitches();
-	for (ISwitchObject switchObj : activeSwitches) {
-	    Vertex nodeVertex = switchObj.asVertex();
-	    //
-	    // The Switch info
-	    //
-	    String nodeDpid = nodeVertex.getProperty("dpid").toString();
-	    long nodeId = HexString.toLong(nodeDpid);
-	    Node me = nodesMap.get(nodeId);
-	    if (me == null)
-		me = addNode(nodeId);
+    public void readFromDatabase(DBOperation dbHandler) {
+		//
+		// Fetch the relevant info from the Switch and Port vertices
+		// from the Titan Graph.
+		//
+    	nodesMap.clear();
 
-	    //
-	    // The local Port info
-	    //
-	    for (Vertex myPortVertex : nodeVertex.getVertices(Direction.OUT, "on")) {
-		// Ignore inactive ports
-		if (! myPortVertex.getProperty("state").toString().equals("ACTIVE"))
-		    continue;
+        // Load all switches into Map
+        Iterable<ISwitchObject> switches = dbHandler.getAllSwitches();
+        for (ISwitchObject switchObj : switches) {
+        	// Ignore inactive ports
+            if (!switchObj.getState().equals(SwitchState.ACTIVE.toString())) {
+            	continue;
+            }
+            Vertex nodeVertex = switchObj.asVertex();
+            //
+            // The Switch info
+            //
+            String nodeDpid = nodeVertex.getProperty("dpid").toString();
+            long nodeId = HexString.toLong(nodeDpid);
+            addNode(nodeId);
+        }
 
-		int myPort = 0;
-		Object obj = myPortVertex.getProperty("number");
-		if (obj instanceof Short) {
-		    myPort = (Short)obj;
-		} else if (obj instanceof Integer) {
-		    myPort = (Integer)obj;
-		}
+        //
+        // Get All Ports
+        //
+        Iterable<IPortObject> ports = dbHandler.getAllPorts(); //TODO: Add to DB operations
+        for (IPortObject myPortObj : ports) {
+            Vertex myPortVertex = myPortObj.asVertex();
+
+            // Ignore inactive ports
+            if (! myPortVertex.getProperty("state").toString().equals("ACTIVE")) {
+            	continue;
+            }
+
+            short myPort = 0;
+            String idStr = myPortObj.getPortId();
+            String[] splitter = idStr.split(IDBOperation.PORT_ID_DELIM);
+            if (splitter.length != 2) {
+            	log.error("Invalid port_id : {}", idStr);
+            	continue;
+            }
+            String myDpid = splitter[0];
+            myPort = Short.parseShort(splitter[1]);
+            long myId = HexString.toLong(myDpid);
+            Node me = nodesMap.get(myId);
+
+            if (me == null) {
+                // cannot proceed ports and switches are out of sync
+                //TODO: Restart the whole read
+                continue;
+            }
+
+            if (me.getPort(myPort) == null) {
+            	me.addPort(myPort);
+            } else if (me.getLink(myPort) != null) {
+                // Link already added..probably by neighbor
+                continue;
+            }
+
+            //
+            // The neighbor Port info
+            //
+            for (Vertex neighborPortVertex : myPortVertex.getVertices(Direction.OUT, "link")) {
+//            	log.debug("state : {}", neighborPortVertex.getProperty("state"));
+//            	log.debug("port id : {}", neighborPortVertex.getProperty("port_id"));
+                // Ignore inactive ports
+                if (! neighborPortVertex.getProperty("state").toString().equals("ACTIVE")) {
+                	continue;
+                }
+                int neighborPort = 0;
+                idStr = neighborPortVertex.getProperty("port_id").toString();
+                splitter = idStr.split(IDBOperation.PORT_ID_DELIM);
+                if (splitter.length != 2) {
+                	log.error("Invalid port_id : {}", idStr);
+                	continue;
+                }
+                String neighborDpid = splitter[0];
+                neighborPort = Short.parseShort(splitter[1]);
+                long neighborId = HexString.toLong(neighborDpid);
+                Node neighbor = nodesMap.get(neighborId);
+//                log.debug("dpid {},{}  port {}", neighborDpid, neighborId, neighborPort);
+                if (neighbor == null) {
+                	continue;
+                }
+                me.addLink(myPort, neighbor, neighborPort);
+            }
+        }
+        dbHandler.commit();
+    }
+
+
+    // Only for debug use
+    List<Long> logGetSw = new ArrayList<Long>(100);
+    List<Long> logGetPt = new ArrayList<Long>(100);
+    List<Long> logAddSw = new ArrayList<Long>(100);
+    List<Long> logAddPt = new ArrayList<Long>(100);
+    List<Long> logAddLk = new ArrayList<Long>(100);
+    List<Long> logCommit = new ArrayList<Long>(100);
+    List<Integer> logGetVertices = new ArrayList<Integer>(100);
+    List<Integer> logGetProperty = new ArrayList<Integer>(100);
+       public void readFromDatabaseBreakdown(DBOperation dbHandler) {
+    	int getVerticesCount = 0;
+    	int getPropertyCount = 0;
+    	int getVCount_sw = 0;
+    	int getVCount_pt = 0;
+    	int getVCount_lk = 0;
+    	int getPCount_sw = 0;
+    	int getPCount_pt = 0;
+    	int getPCount_lk = 0;
 
 		//
-		// The neighbor Port info
+		// Fetch the relevant info from the Switch and Port vertices
+		// from the Titan Graph.
 		//
-		for (Vertex neighborPortVertex : myPortVertex.getVertices(Direction.OUT, "link")) {
-		    // Ignore inactive ports
-		    if (! neighborPortVertex.getProperty("state").toString().equals("ACTIVE"))
-			continue;
 
-		    int neighborPort = 0;
-		    obj = neighborPortVertex.getProperty("number");
-		    if (obj instanceof Short) {
-			neighborPort = (Short)obj;
-		    } else if (obj instanceof Integer) {
-			neighborPort = (Integer)obj;
-		    }
-		    //
-		    // The neighbor Switch info
-		    //
-		    for (Vertex neighborVertex : neighborPortVertex.getVertices(Direction.IN, "on")) {
-			// Ignore inactive switches
-			String state = neighborVertex.getProperty("state").toString();
-			if (! state.equals(SwitchState.ACTIVE.toString()))
-			    continue;
+    	nodesMap.clear();
+    	long t1 = System.nanoTime();
 
-			String neighborDpid = neighborVertex.getProperty("dpid").toString();
-			long neighborId = HexString.toLong(neighborDpid);
-			Node neighbor = nodesMap.get(neighborId);
-			if (neighbor == null)
-			    neighbor = addNode(neighborId);
-			me.addLink(myPort, neighbor, neighborPort);
-		    }
-		}
-	    }
-	}
-	dbHandler.commit();
+        // Load all switches into Map
+        Iterable<ISwitchObject> switches = dbHandler.getAllSwitches();
+
+        long t2 = System.nanoTime();
+
+        long t_addSw = 0;
+        for (ISwitchObject switchObj : switches) {
+            long t3 = System.nanoTime();
+            long t4;
+
+        	// Ignore inactive ports
+            ++getPropertyCount;
+            ++getPCount_sw;
+            if (!switchObj.getState().equals(SwitchState.ACTIVE.toString())) {
+                t4 = System.nanoTime();
+                t_addSw += t4 - t3;
+            	continue;
+            }
+            Vertex nodeVertex = switchObj.asVertex();
+            //
+            // The Switch info
+            //
+            ++getPropertyCount;
+            ++getPCount_sw;
+            String nodeDpid = nodeVertex.getProperty("dpid").toString();
+            long nodeId = HexString.toLong(nodeDpid);
+            addNode(nodeId);
+            t4 = System.nanoTime();
+            t_addSw += t4 - t3;
+        }
+
+        long t5 = System.nanoTime();
+        //
+        // Get All Ports
+        //
+        Iterable<IPortObject> ports = dbHandler.getAllPorts(); //TODO: Add to DB operations
+
+        long t6 = System.nanoTime();
+        long t_addPort = 0;
+        long t_addLink = 0;
+
+        for (IPortObject myPortObj : ports) {
+            long t7 = System.nanoTime();
+            long t8;
+            Vertex myPortVertex = myPortObj.asVertex();
+
+            // Ignore inactive ports
+            ++getPropertyCount;
+            ++getPCount_pt;
+            if (! myPortVertex.getProperty("state").toString().equals("ACTIVE")) {
+                t8 = System.nanoTime();
+                t_addPort += t8 - t7;
+            	continue;
+            }
+
+            short myPort = 0;
+            ++getPropertyCount;
+            ++getPCount_pt;
+            String idStr = myPortObj.getPortId();
+            String[] splitter = idStr.split(IDBOperation.PORT_ID_DELIM);
+            if (splitter.length != 2) {
+            	log.error("Invalid port_id : {}", idStr);
+                t8 = System.nanoTime();
+                t_addPort += t8 - t7;
+            	continue;
+            }
+            String myDpid = splitter[0];
+            myPort = Short.parseShort(splitter[1]);
+            long myId = HexString.toLong(myDpid);
+            Node me = nodesMap.get(myId);
+
+            if (me == null) {
+                // cannot proceed ports and switches are out of sync
+                //TODO: Restart the whole read
+                t8 = System.nanoTime();
+                t_addPort += t8 - t7;
+                continue;
+            }
+
+            if (me.getPort(myPort) == null) {
+            	me.addPort(myPort);
+            } else if (me.getLink(myPort) != null) {
+                // Link already added..probably by neighbor
+                t8 = System.nanoTime();
+                t_addPort += t8 - t7;
+                continue;
+            }
+            t8 = System.nanoTime();
+            t_addPort += t8 - t7;
+
+            //
+            // The neighbor Port info
+            //
+            ++getVerticesCount;
+            ++getVCount_pt;
+            for (Vertex neighborPortVertex : myPortVertex.getVertices(Direction.OUT, "link")) {
+//            	log.debug("state : {}", neighborPortVertex.getProperty("state"));
+//            	log.debug("port id : {}", neighborPortVertex.getProperty("port_id"));
+
+                long t9 = System.nanoTime();
+                long t10;
+
+                // Ignore inactive ports
+                ++getPropertyCount;
+                ++getPCount_lk;
+                if (! neighborPortVertex.getProperty("state").toString().equals("ACTIVE")) {
+                    t10 = System.nanoTime();
+                    t_addLink += t10 - t9;
+                	continue;
+                }
+                int neighborPort = 0;
+                ++getPropertyCount;
+                ++getPCount_lk;
+                idStr = neighborPortVertex.getProperty("port_id").toString();
+                splitter = idStr.split(IDBOperation.PORT_ID_DELIM);
+                if (splitter.length != 2) {
+                	log.error("Invalid port_id : {}", idStr);
+                    t10 = System.nanoTime();
+                    t_addLink += t10 - t9;
+                	continue;
+                }
+                String neighborDpid = splitter[0];
+                neighborPort = Short.parseShort(splitter[1]);
+                long neighborId = HexString.toLong(neighborDpid);
+                Node neighbor = nodesMap.get(neighborId);
+//                log.debug("dpid {},{}  port {}", neighborDpid, neighborId, neighborPort);
+                if (neighbor == null) {
+                    t10 = System.nanoTime();
+                    t_addLink += t10 - t9;
+                	continue;
+                }
+                me.addLink(myPort, neighbor, neighborPort);
+
+                t10 = System.nanoTime();
+                t_addLink += t10 - t9;
+            }
+        }
+        long t11 = System.nanoTime();
+        dbHandler.commit();
+        long t12 = System.nanoTime();
+
+        logGetSw.add((t2-t1)/1000);
+        logGetPt.add((t6-t5)/1000);
+        logAddSw.add(t_addSw/1000);
+        logAddPt.add(t_addPort/1000);
+        logAddLk.add(t_addLink/1000);
+        logCommit.add((t12-t11)/1000);
+        logGetVertices.add(getVerticesCount);
+        logGetProperty.add(getPropertyCount);
+        log.debug("getVertices[N({}),P({}),L({})] getProperty[N({}),P({}),L({})]",
+        		new Object[]{getVCount_sw,getVCount_pt,getVCount_lk,
+        		getPCount_sw,getPCount_pt,getPCount_lk});
+    }
+
+    public void printMeasuredLog() {
+    	log.debug("getsw: {}", StringUtils.join(logGetSw, ","));
+    	log.debug("getpt: {}", StringUtils.join(logGetPt, ","));
+    	log.debug("addsw: {}", StringUtils.join(logAddSw, ","));
+    	log.debug("addpt: {}", StringUtils.join(logAddPt, ","));
+    	log.debug("addlk: {}", StringUtils.join(logAddLk, ","));
+    	log.debug("commit: {}", StringUtils.join(logCommit, ","));
+    	log.debug("getvertices: {}", StringUtils.join(logGetVertices, ","));
+    	log.debug("getproperty: {}", StringUtils.join(logGetProperty, ","));
+    }
+
+    // Only for debug use
+    @Override
+    public String toString() {
+    	long numNodes = nodesMap.size();
+    	long numLinks = 0;
+    	for (Map.Entry<Long, Node> entry : nodesMap.entrySet()) {
+    		Node n = entry.getValue();
+    		for (Map.Entry<Integer, Node.Link> linkEntry : n.links.entrySet()) {
+    			if (n.nodeId > linkEntry.getValue().neighbor.nodeId) {
+    				++numLinks;
+    			}
+    		}
+    	}
+    	return "Topology has " + numNodes + " Nodes and " + numLinks + " Links.";
     }
 }
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/ofcontroller/core/internal/LinkStorageImplTest.java b/src/test/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImplTest.java
index 8034d44..69c3c8a 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImplTest.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImplTest.java
@@ -119,7 +119,7 @@
 		mockToPortInfoMap = new HashMap<IPortObject,PortInfo>();
 		
 		linkStorage = new LinkStorageImpl();
-		linkStorage.init("/dummy/path/to/conf");
+		linkStorage.init("dummyStore", "/dummy/path/to/conf");
 		
 		initLinks();
 	}
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
index 6f4f850..fdc13db 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImplTest.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImplTest.java
@@ -34,6 +34,7 @@
 	protected static org.slf4j.Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
 
 	String conf;
+        String dbStore;
     private GraphDBConnection mockConn = null;
     private GraphDBOperation mockOpe = null;
     ISwitchStorage swSt = null;
@@ -42,6 +43,7 @@
 	public void setUp() throws Exception {
 		
 		swSt = new SwitchStorageImpl();
+                dbStore = "dummyStore";
 		conf = "/dummy/path/to/db";
 		
         // Make mock cassandra DB
@@ -95,7 +97,7 @@
 		mockOpe.close();
 		replay(mockOpe);
 		
-		swSt.init(conf);
+		swSt.init(dbStore, conf);
 		swSt.addSwitch(dpid);
 	}
 	
@@ -129,7 +131,7 @@
 		mockOpe.close();
 		replay(mockOpe);
 		
-		swSt.init(conf);
+		swSt.init(dbStore, conf);
 		swSt.addSwitch(dpid);
 		swSt.addSwitch(dpid);
 	}
@@ -153,7 +155,7 @@
 		mockOpe.close();
 		replay(mockOpe);
 		
-		swSt.init(conf);
+		swSt.init(dbStore, conf);
 		swSt.addSwitch(dpid);
 	}
 	
@@ -185,7 +187,7 @@
 		mockOpe.close();
 		replay(mockOpe);
 		
-		swSt.init(conf);
+		swSt.init(dbStore, conf);
 		swSt.addSwitch(dpid);
 	}
 	
@@ -217,7 +219,7 @@
 		mockOpe.close();
 		replay(mockOpe);
 		
-		swSt.init(conf);
+		swSt.init(dbStore, conf);
 		swSt.updateSwitch(dpid, stateINACTIVE, opUPDATE);
 	}
 	
@@ -250,7 +252,7 @@
 		mockOpe.close();
 		replay(mockOpe);
 		
-		swSt.init(conf);
+		swSt.init(dbStore, conf);
 		swSt.updateSwitch(dpid, stateINACTIVE, opCREATE);
 	}
 	
@@ -283,7 +285,7 @@
 		mockOpe.close();
 		replay(mockOpe);
 		
-		swSt.init(conf);
+		swSt.init(dbStore, conf);
 		swSt.updateSwitch(dpid, stateINACTIVE, opINSERT);
 	}
 	
@@ -319,7 +321,7 @@
 		mockOpe.close();
 		replay(mockOpe);
 		
-		swSt.init(conf);
+		swSt.init(dbStore, conf);
 		swSt.addSwitch(dpid);
 		swSt.updateSwitch(dpid, stateACTIVE, opDELETE);
 	}
@@ -354,7 +356,7 @@
 		mockOpe.close();
 		replay(mockOpe);
 		
-		swSt.init(conf);
+		swSt.init(dbStore, conf);
 		swSt.addSwitch(dpid);
 		swSt.deleteSwitch(dpid);
 		
@@ -393,7 +395,7 @@
 		mockOpe.close();
 		replay(mockOpe);
 		
-		swSt.init(conf);
+		swSt.init(dbStore, conf);
 		swSt.addSwitch(dpid);
 		swSt.deleteSwitch(dpid);
 	}
@@ -446,7 +448,7 @@
 		mockOpe.close();
 		replay(mockOpe);
 
-		swSt.init(conf);
+		swSt.init(dbStore, conf);
 		swSt.addSwitch(dpid);
 		swSt.addPort(dpid, portToAdd);
 	}
@@ -502,7 +504,7 @@
 		mockOpe.close();
 		replay(mockOpe);
 
-		swSt.init(conf);
+		swSt.init(dbStore, conf);
 		swSt.addSwitch(dpid);
 		swSt.addPort(dpid, portToAdd);
 	}
@@ -541,7 +543,7 @@
 		mockOpe.close();
 		replay(mockOpe);
 
-		swSt.init(conf);
+		swSt.init(dbStore, conf);
 		swSt.addPort(dpid, portToAdd);
 	}
 	
@@ -593,7 +595,7 @@
 		mockOpe.close();
 		replay(mockOpe);
 
-		swSt.init(conf);
+		swSt.init(dbStore, conf);
 		swSt.addSwitch(dpid);
 		swSt.addPort(dpid, portToAdd);
 	}
@@ -648,7 +650,7 @@
 		mockOpe.close();
 		replay(mockOpe);
 
-		swSt.init(conf);
+		swSt.init(dbStore, conf);
 		swSt.addSwitch(dpid);
 		swSt.addPort(dpid, portToAdd);
 	}
@@ -711,7 +713,7 @@
 		mockOpe.close();
 		replay(mockOpe);
 
-		swSt.init(conf);
+		swSt.init(dbStore, conf);
 		swSt.addSwitch(dpid);
 		swSt.addPort(dpid, portToAdd);
 		swSt.deletePort(dpid, portNumber);
@@ -778,7 +780,7 @@
 		mockOpe.close();
 		replay(mockOpe);
 	
-		swSt.init(conf);
+		swSt.init(dbStore, conf);
 		swSt.addSwitch(dpid);
 		swSt.addPort(dpid, portToAdd);
 		swSt.deletePort(dpid, portNumber);
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
index 7edc1c5..fe51f95 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImplTestBB.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImplTestBB.java
@@ -49,6 +49,7 @@
 	protected static org.slf4j.Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
 
 	String conf;
+        String dbStore;
     private GraphDBConnection conn = null;
     private GraphDBOperation ope = null;
     private TitanGraph titanGraph = null;
@@ -59,6 +60,7 @@
 		
 		swSt = new SwitchStorageImpl();
 		conf = "/dummy/path/to/db";
+                dbStore ="dummyStore";
 		
 		// Make mock cassandra DB
 		// Replace TitanFactory.open() to return mock DB
@@ -71,7 +73,7 @@
 		conn = GraphDBConnection.getInstance(conf);
 		ope = new GraphDBOperation(conn);
 		
-		swSt.init(conf);
+		swSt.init(dbStore, conf);
 	}
 
 	@After
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
index 44573bc..d017546 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/devicemanager/internal/DeviceStorageImplTest.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/devicemanager/internal/DeviceStorageImplTest.java
@@ -46,6 +46,7 @@
 	protected final static Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
 	
 	String conf;
+        String dbStore;
 	DeviceStorageImpl deviceImpl;
     private GraphDBConnection mockConn;
     private GraphDBOperation mockOpe;
@@ -54,6 +55,7 @@
 	public void setUp() throws Exception {
 	    deviceImpl = new DeviceStorageImpl();	
 		conf = "/dummy/path/to/db";
+                dbStore = "dummyStore";
 				
 		PowerMock.mockStatic(GraphDBConnection.class);
 		mockConn = createMock(GraphDBConnection.class);
@@ -69,7 +71,7 @@
         // Replace the conf to dummy conf
 		// String conf = "/tmp/cassandra.titan";
 
-		deviceImpl.init(conf);
+		deviceImpl.init(dbStore, conf);
 
 	}
 
@@ -241,6 +243,7 @@
 		assertNotNull(addedObject);
 		
 		verify(mockDeviceObject);
+
 	}
 
 	/**
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
index 9964ec3..c80b52a 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/devicemanager/internal/DeviceStorageImplTestBB.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/devicemanager/internal/DeviceStorageImplTestBB.java
@@ -56,6 +56,7 @@
 	protected static org.slf4j.Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
 
 	String conf;
+        String dbStore;
     private GraphDBConnection conn = null;
     private GraphDBOperation ope = null;
     private TitanGraph titanGraph = null;
@@ -66,6 +67,7 @@
 		
 		deviceImpl = new DeviceStorageImpl();
 		conf = "/dummy/path/to/db";
+                dbStore = "dummyStore";
 		
 		// Make mock cassandra DB
 		// Replace TitanFactory.open() to return mock DB
@@ -78,7 +80,7 @@
 		conn = GraphDBConnection.getInstance(conf);
 		ope = new GraphDBOperation(conn);
 		
-		deviceImpl.init(conf);
+		deviceImpl.init(dbStore, conf);
 	}
 
 	@After
diff --git a/src/test/java/net/onrc/onos/ofcontroller/flowmanager/FlowManagerTest.java b/src/test/java/net/onrc/onos/ofcontroller/flowmanager/FlowManagerTest.java
index b43ce1c..73577c1 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/flowmanager/FlowManagerTest.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/flowmanager/FlowManagerTest.java
@@ -485,7 +485,7 @@
 		// start the test
 		replayAll();
 		
-		fm.init("/dummy/path");
+		fm.init("dummy_store", "/dummy/path");
 		
 		// verify the test
 		verifyAll();
diff --git a/src/test/java/net/onrc/onos/ofcontroller/topology/TopologyManagerTest.java b/src/test/java/net/onrc/onos/ofcontroller/topology/TopologyManagerTest.java
index e054e05..8d4ccc0 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/topology/TopologyManagerTest.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/topology/TopologyManagerTest.java
@@ -16,7 +16,10 @@
 
 import com.thinkaurelius.titan.core.TitanGraph;
 import com.thinkaurelius.titan.core.TitanFactory;
+import net.onrc.onos.graph.DBConnection;
+import net.onrc.onos.graph.DBOperation;
 import net.onrc.onos.graph.GraphDBConnection;
+import net.onrc.onos.graph.GraphDBManager;
 import net.onrc.onos.graph.GraphDBOperation;
 import net.onrc.onos.ofcontroller.core.internal.TestDatabaseManager;
 import net.onrc.onos.ofcontroller.topology.TopologyManager;
@@ -34,8 +37,9 @@
 @PrepareForTest({TitanFactory.class, GraphDBConnection.class, GraphDBOperation.class, TopologyManager.class})
 public class TopologyManagerTest {
     String conf;
-    private GraphDBConnection conn = null;
-    private GraphDBOperation oper = null;
+    String dbStore;
+    private DBConnection conn = null;
+    private DBOperation oper = null;
     private TitanGraph titanGraph = null;
     private TopologyManager topologyManager = null;
 
@@ -44,6 +48,7 @@
      */
     @Before
     public void setUp() throws Exception {
+        dbStore = "dummyStore";
 	conf = "/dummy/path/to/db";
 
 	//
@@ -55,9 +60,9 @@
 	EasyMock.expect(TitanFactory.open((String)EasyMock.anyObject())).andReturn(titanGraph);
 	PowerMock.replay(TitanFactory.class);
 
+        oper = GraphDBManager.getDBOperation(dbStore, conf);
 	// Create the connection to the database
-	conn = GraphDBConnection.getInstance(conf);
-	oper = new GraphDBOperation(conn);
+	conn = GraphDBManager.getConnection(dbStore, conf);
 
 	// Populate the database
 	TestDatabaseManager.populateTestData(titanGraph);
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
diff --git a/titan/gremlin.sh b/titan/gremlin.sh
index a340dd7..b13264c 100755
--- a/titan/gremlin.sh
+++ b/titan/gremlin.sh
@@ -8,12 +8,11 @@
 ONOS_DIR="`dirname $0`/.."
 
 # Use a python script to parse the classpath out of the .classpath file
-if [ ! -f ${ONOS_DIR}/.javacp ]; then
+if [ ! -f ${BASE_DIR}/../.javacp ]; then
   echo "execute mvn compile at ONOS HOME directory."
   exit 1
 fi
-CP=`cat ${ONOS_DIR}/.javacp`
-CP="${CP}:${ONOS_DIR}/target/classes"
+CP=`cat ${BASE_DIR}/../.javacp`
 
 if [[ "$CP" == *"Error reading classpath file"* ]]; then
     echo $CP