* Added initial support for add/get/delete Flow state to the Network MAP via the REST API
  NOTE: The "add" REST API can't be used as-is.
* Added initial support for reading the Flow state from the Network MAP by the Controller
  and sending it to the switches.
  Currently, the Controller reads periodically the Flow entries (every 3 seconds)
  NOTE: The writing of the OpenFlow state to the switches is not tested.

The Python scripts for to add/delete/get flows are intentionally omitted until
the "add" REST API issue is resolved.

NOTE: Two new keys have been added to the database: "flow_id" and "flow_entry_id".
This requires that the older database should be deleted, because Cassandra
doesn't allow adding new keys to an existing database.
diff --git a/src/main/java/net/onrc/onos/util/GraphDBConnection.java b/src/main/java/net/onrc/onos/util/GraphDBConnection.java
index a2a8689..724095b 100644
--- a/src/main/java/net/onrc/onos/util/GraphDBConnection.java
+++ b/src/main/java/net/onrc/onos/util/GraphDBConnection.java
@@ -37,6 +37,13 @@
 		        if (!s.contains("dl_address")) {
 		        	graph.createKeyIndex("dl_address", 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);
+		        }
 		   }
 		   graph.stopTransaction(Conclusion.SUCCESS);
 		   if (utils == null) {
diff --git a/src/main/java/net/onrc/onos/util/GraphDBUtils.java b/src/main/java/net/onrc/onos/util/GraphDBUtils.java
index d01de21..ebc5942 100644
--- a/src/main/java/net/onrc/onos/util/GraphDBUtils.java
+++ b/src/main/java/net/onrc/onos/util/GraphDBUtils.java
@@ -7,8 +7,12 @@
 import com.tinkerpop.gremlin.java.GremlinPipeline;
 
 import net.floodlightcontroller.core.INetMapTopologyObjects.IDeviceObject;
+import net.floodlightcontroller.core.INetMapTopologyObjects.IFlowEntry;
+import net.floodlightcontroller.core.INetMapTopologyObjects.IFlowPath;
 import net.floodlightcontroller.core.INetMapTopologyObjects.IPortObject;
 import net.floodlightcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.floodlightcontroller.util.FlowEntryId;
+import net.floodlightcontroller.util.FlowId;
 
 public class GraphDBUtils implements IDBUtils {
 
@@ -60,4 +64,69 @@
 		return fg.getVertices("type","device",IDeviceObject.class);
 	}
 
+	@Override
+	public IFlowPath searchFlowPath(GraphDBConnection conn,
+					FlowId flowId) {
+		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+		
+		return fg.getVertices("flow_id", flowId.toString()).iterator().hasNext() ? 
+		    fg.getVertices("flow_id", flowId.toString(),
+				   IFlowPath.class).iterator().next() : null;
+	}
+
+	@Override
+	public IFlowPath newFlowPath(GraphDBConnection conn) {
+		FramedGraph<TitanGraph> fg = conn.getFramedGraph();	
+		IFlowPath flowPath = fg.addVertex(null, IFlowPath.class);
+		return flowPath;
+	}
+
+	@Override
+	public void removeFlowPath(GraphDBConnection conn,
+				   IFlowPath flowPath) {
+		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+		fg.removeVertex(flowPath.asVertex());
+	}
+
+	@Override
+	public IFlowPath getFlowPathByFlowEntry(GraphDBConnection conn,
+						IFlowEntry flowEntry) {
+		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+		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;
+	}
+
+	@Override
+	public IFlowEntry searchFlowEntry(GraphDBConnection conn,
+					  FlowEntryId flowEntryId) {
+		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+		
+		return fg.getVertices("flow_entry_id", flowEntryId.toString()).iterator().hasNext() ? 
+		    fg.getVertices("flow_entry_id", flowEntryId.toString(),
+				   IFlowEntry.class).iterator().next() : null;
+	}
+
+	@Override
+	public IFlowEntry newFlowEntry(GraphDBConnection conn) {
+		FramedGraph<TitanGraph> fg = conn.getFramedGraph();	
+		IFlowEntry flowEntry = fg.addVertex(null, IFlowEntry.class);
+		return flowEntry;
+	}
+
+	@Override
+	public void removeFlowEntry(GraphDBConnection conn,
+				    IFlowEntry flowEntry) {
+		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+		fg.removeVertex(flowEntry.asVertex());
+	}
+
+	@Override
+        public Iterable<IFlowEntry> getAllFlowEntries(GraphDBConnection conn) {
+		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+		
+		return fg.getVertices("type", "flow_entry", IFlowEntry.class);
+	}
 }
diff --git a/src/main/java/net/onrc/onos/util/IDBUtils.java b/src/main/java/net/onrc/onos/util/IDBUtils.java
index a27a261..4ff70f3 100644
--- a/src/main/java/net/onrc/onos/util/IDBUtils.java
+++ b/src/main/java/net/onrc/onos/util/IDBUtils.java
@@ -1,8 +1,12 @@
 package net.onrc.onos.util;
 
 import net.floodlightcontroller.core.INetMapTopologyObjects.IDeviceObject;
+import net.floodlightcontroller.core.INetMapTopologyObjects.IFlowEntry;
+import net.floodlightcontroller.core.INetMapTopologyObjects.IFlowPath;
 import net.floodlightcontroller.core.INetMapTopologyObjects.IPortObject;
 import net.floodlightcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.floodlightcontroller.util.FlowEntryId;
+import net.floodlightcontroller.util.FlowId;
 
 public interface IDBUtils {	
 	public ISwitchObject searchSwitch(GraphDBConnection conn, String dpid);
@@ -11,4 +15,15 @@
 	public void removeDevice(GraphDBConnection conn, IDeviceObject dev);
 	public IPortObject searchPort(GraphDBConnection conn, String dpid, short number);
 	public Iterable<IDeviceObject> getDevices(GraphDBConnection conn);
+	public IFlowPath searchFlowPath(GraphDBConnection conn, FlowId flowId);
+	public IFlowPath newFlowPath(GraphDBConnection conn);
+	public void removeFlowPath(GraphDBConnection conn, IFlowPath flowPath);
+        public IFlowPath getFlowPathByFlowEntry(GraphDBConnection conn,
+						IFlowEntry flowEntry);
+	public IFlowEntry searchFlowEntry(GraphDBConnection conn,
+					  FlowEntryId flowEntryId);
+	public IFlowEntry newFlowEntry(GraphDBConnection conn);
+	public void removeFlowEntry(GraphDBConnection conn,
+				    IFlowEntry flowEntry);
+	public Iterable<IFlowEntry> getAllFlowEntries(GraphDBConnection conn);
 }