diff --git a/conf/onos-embedded.properties b/conf/onos-embedded.properties
index 8bbf25d..777ff2b 100644
--- a/conf/onos-embedded.properties
+++ b/conf/onos-embedded.properties
@@ -9,6 +9,7 @@
 net.floodlightcontroller.ui.web.StaticWebRoutable,\
 net.onrc.onos.datagrid.HazelcastDatagrid,\
 net.onrc.onos.ofcontroller.flowmanager.FlowManager,\
+net.onrc.onos.ofcontroller.topology.TopologyManager,\
 net.onrc.onos.registry.controller.ZookeeperRegistry
 net.floodlightcontroller.restserver.RestApiServer.port = 8080
 net.floodlightcontroller.core.FloodlightProvider.openflowport = 6633
diff --git a/conf/onos.properties b/conf/onos.properties
index c67b340..e858adb 100644
--- a/conf/onos.properties
+++ b/conf/onos.properties
@@ -9,6 +9,7 @@
 net.floodlightcontroller.ui.web.StaticWebRoutable,\
 net.onrc.onos.datagrid.HazelcastDatagrid,\
 net.onrc.onos.ofcontroller.flowmanager.FlowManager,\
+net.onrc.onos.ofcontroller.topology.TopologyManager,\
 net.onrc.onos.registry.controller.ZookeeperRegistry
 net.floodlightcontroller.restserver.RestApiServer.port = 8080
 net.floodlightcontroller.core.FloodlightProvider.openflowport = 6633
diff --git a/pom.xml b/pom.xml
index 71e8192..002ba60 100644
--- a/pom.xml
+++ b/pom.xml
@@ -81,6 +81,7 @@
             <exclude>**/*TestCase.java</exclude>
           -->
           </excludes>
+          <argLine>-XX:MaxPermSize=256m</argLine>
         </configuration>
       </plugin>
       <!-- exec:java -->
@@ -165,6 +166,14 @@
           </execution>
         </executions>
       </plugin>
+      <plugin>
+	<artifactId>maven-assembly-plugin</artifactId>
+	<configuration>
+	  <descriptorRefs>
+	    <descriptorRef>jar-with-dependencies</descriptorRef>
+	  </descriptorRefs>
+	</configuration>
+      </plugin>
     </plugins>
   </build>
   <!-- for getting visualization reporting   -->
@@ -349,7 +358,7 @@
     <dependency>
       <groupId>org.easymock</groupId>
       <artifactId>easymock</artifactId>
-      <version>3.2</version>
+      <version>3.1</version>
       <scope>test</scope>
     </dependency>
     <dependency>
diff --git a/src/main/java/net/floodlightcontroller/core/internal/Controller.java b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
index 44510a7..134a3b0 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/Controller.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
@@ -2352,7 +2352,7 @@
                         // new controller node IP
                         addedControllerNodeIPs.put(controllerID, discoveredIP);
                     } 
-                    else if (curIP.equals(discoveredIP)) {
+                    else if (!curIP.equals(discoveredIP)) {
                         // IP changed                    
                         removedControllerNodeIPs.put(controllerID, curIP);
                         addedControllerNodeIPs.put(controllerID, discoveredIP);
diff --git a/src/main/java/net/onrc/onos/datagrid/HazelcastDatagrid.java b/src/main/java/net/onrc/onos/datagrid/HazelcastDatagrid.java
index 7736880..3ff773e 100644
--- a/src/main/java/net/onrc/onos/datagrid/HazelcastDatagrid.java
+++ b/src/main/java/net/onrc/onos/datagrid/HazelcastDatagrid.java
@@ -27,9 +27,7 @@
  * appropriate in a multi-node cluster.
  */
 public class HazelcastDatagrid implements IFloodlightModule, IDatagridService {
-    protected static Logger log =
-	LoggerFactory.getLogger(HazelcastDatagrid.class);
-
+    protected static Logger log = LoggerFactory.getLogger(HazelcastDatagrid.class);
     protected IFloodlightProviderService floodlightProvider;
 
     protected static final String HazelcastConfigFile = "datagridConfig";
@@ -101,7 +99,7 @@
     public Map<Class<? extends IFloodlightService>, IFloodlightService> 
 			       getServiceImpls() {
         Map<Class<? extends IFloodlightService>,
-        IFloodlightService> m = 
+	    IFloodlightService> m = 
             new HashMap<Class<? extends IFloodlightService>,
                 IFloodlightService>();
         m.put(IDatagridService.class, this);
diff --git a/src/main/java/net/onrc/onos/graph/GraphDBConnection.java b/src/main/java/net/onrc/onos/graph/GraphDBConnection.java
index f9f3b67..bebcdd2 100644
--- a/src/main/java/net/onrc/onos/graph/GraphDBConnection.java
+++ b/src/main/java/net/onrc/onos/graph/GraphDBConnection.java
@@ -87,9 +87,10 @@
 		return singleton;
 	}
 
-	/** 
+	/**
 	 * Get a FramedGraph instance of the graph.
 	 */
+	@Override
 	public FramedGraph<TitanGraph> getFramedGraph() {
 		if (isValid()) {
 			FramedGraph<TitanGraph> fg = new FramedGraph<TitanGraph>(graph);
@@ -115,6 +116,7 @@
 	/**
 	 * Add LocalGraphChangedLister for the graph.
 	 */
+	@Override
 	public void addEventListener(final LocalGraphChangedListener listener) {
 		EventTransactionalGraph<TitanGraph> eg = this.getEventGraph();
 		eg.addListener(listener);
@@ -124,13 +126,15 @@
 	/**
 	 * Return whether this connection is valid.
 	 */
+	@Override
 	public Boolean isValid() {
-		return (graph != null || graph.isOpen());
+		return (graph != null && graph.isOpen());
 	}
 
 	/**
 	 * Commit changes for the graph operations.
 	 */
+	@Override
 	public void commit() {
 		try {
 			graph.commit();
@@ -143,6 +147,7 @@
 	/**
 	 * Rollback changes for the graph operations.
 	 */
+	@Override
 	public void rollback() {
 		try {
 			graph.rollback();
@@ -155,6 +160,7 @@
 	/**
 	 * Close this database connection.
 	 */
+	@Override
 	public void close() {
 		commit();
 	}
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 9b6ac53..30b39a6 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
@@ -42,6 +42,7 @@
 import net.onrc.onos.ofcontroller.proxyarp.IProxyArpService;
 import net.onrc.onos.ofcontroller.proxyarp.ProxyArpManager;
 import net.onrc.onos.ofcontroller.topology.ITopologyNetService;
+import net.onrc.onos.ofcontroller.topology.Topology;
 import net.onrc.onos.ofcontroller.topology.TopologyManager;
 import net.onrc.onos.ofcontroller.util.DataPath;
 import net.onrc.onos.ofcontroller.util.Dpid;
@@ -79,72 +80,72 @@
 									IOFSwitchListener, ILayer3InfoService,
 									IProxyArpService {
 	
-	protected static Logger log = LoggerFactory.getLogger(BgpRoute.class);
+	private static Logger log = LoggerFactory.getLogger(BgpRoute.class);
 
-	protected IFloodlightProviderService floodlightProvider;
-	protected ITopologyService topology;
-	protected ITopologyNetService topologyNetService;
-	protected ILinkDiscoveryService linkDiscoveryService;
-	protected IRestApiService restApi;
+	private IFloodlightProviderService floodlightProvider;
+	private ITopologyService topologyService;
+	private ITopologyNetService topologyNetService;
+	private ILinkDiscoveryService linkDiscoveryService;
+	private IRestApiService restApi;
 	
-	protected ProxyArpManager proxyArp;
+	private ProxyArpManager proxyArp;
 	
-	protected IPatriciaTrie<RibEntry> ptree;
-	protected IPatriciaTrie<Interface> interfacePtrie;
-	protected BlockingQueue<RibUpdate> ribUpdates;
+	private IPatriciaTrie<RibEntry> ptree;
+	private IPatriciaTrie<Interface> interfacePtrie;
+	private BlockingQueue<RibUpdate> ribUpdates;
 	
-	protected String bgpdRestIp;
-	protected String routerId;
-	protected String configFilename = "config.json";
+	private String bgpdRestIp;
+	private String routerId;
+	private String configFilename = "config.json";
 	
 	//We need to identify our flows somehow. But like it says in LearningSwitch.java,
 	//the controller/OS should hand out cookie IDs to prevent conflicts.
-	protected final long APP_COOKIE = 0xa0000000000000L;
+	private final long APP_COOKIE = 0xa0000000000000L;
 	//Cookie for flows that do L2 forwarding within SDN domain to egress routers
-	protected final long L2_FWD_COOKIE = APP_COOKIE + 1;
+	private final long L2_FWD_COOKIE = APP_COOKIE + 1;
 	//Cookie for flows in ingress switches that rewrite the MAC address
-	protected final long MAC_RW_COOKIE = APP_COOKIE + 2;
+	private final long MAC_RW_COOKIE = APP_COOKIE + 2;
 	//Cookie for flows that setup BGP paths
-	protected final long BGP_COOKIE = APP_COOKIE + 3;
+	private final long BGP_COOKIE = APP_COOKIE + 3;
 	//Forwarding uses priority 0, and the mac rewrite entries in ingress switches
 	//need to be higher priority than this otherwise the rewrite may not get done
-	protected final short SDNIP_PRIORITY = 10;
-	protected final short ARP_PRIORITY = 20;
+	private final short SDNIP_PRIORITY = 10;
+	private final short ARP_PRIORITY = 20;
 	
-	protected final short BGP_PORT = 179;
+	private final short BGP_PORT = 179;
 	
-	protected final int TOPO_DETECTION_WAIT = 2; //seconds
+	private final int TOPO_DETECTION_WAIT = 2; //seconds
 	
 	//Configuration stuff
-	protected List<String> switches;
-	protected Map<String, Interface> interfaces;
-	protected Map<InetAddress, BgpPeer> bgpPeers;
-	protected SwitchPort bgpdAttachmentPoint;
-	protected MACAddress bgpdMacAddress;
+	private List<String> switches;
+	private Map<String, Interface> interfaces;
+	private Map<InetAddress, BgpPeer> bgpPeers;
+	private SwitchPort bgpdAttachmentPoint;
+	private MACAddress bgpdMacAddress;
 	
 	//True when all switches have connected
-	protected volatile boolean switchesConnected = false;
+	private volatile boolean switchesConnected = false;
 	//True when we have a full mesh of shortest paths between gateways
-	protected volatile boolean topologyReady = false;
+	private volatile boolean topologyReady = false;
 
-	protected ArrayList<LDUpdate> linkUpdates;
-	protected SingletonTask topologyChangeDetectorTask;
+	private ArrayList<LDUpdate> linkUpdates;
+	private SingletonTask topologyChangeDetectorTask;
 	
-	protected SetMultimap<InetAddress, RibUpdate> prefixesWaitingOnArp;
+	private SetMultimap<InetAddress, RibUpdate> prefixesWaitingOnArp;
 	
-	protected Map<InetAddress, Path> pathsWaitingOnArp;
+	private Map<InetAddress, Path> pathsWaitingOnArp;
 	
-	protected ExecutorService bgpUpdatesExecutor;
+	private ExecutorService bgpUpdatesExecutor;
 	
-	protected Map<InetAddress, Path> pushedPaths;
-	protected Map<Prefix, Path> prefixToPath;
-	protected Multimap<Prefix, PushedFlowMod> pushedFlows;
+	private Map<InetAddress, Path> pushedPaths;
+	private Map<Prefix, Path> prefixToPath;
+	private Multimap<Prefix, PushedFlowMod> pushedFlows;
 	
 	private FlowCache flowCache;
 	
-	protected volatile Map<Long, ?> shortestPathTopo = null;
+	private volatile Topology topology = null;
 		
-	protected class TopologyChangeDetector implements Runnable {
+	private class TopologyChangeDetector implements Runnable {
 		@Override
 		public void run() {
 			log.debug("Running topology change detection task");
@@ -260,13 +261,13 @@
 	    	
 		// Register floodlight provider and REST handler.
 		floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
-		topology = context.getServiceImpl(ITopologyService.class);
+		topologyService = context.getServiceImpl(ITopologyService.class);
 		linkDiscoveryService = context.getServiceImpl(ILinkDiscoveryService.class);
 		restApi = context.getServiceImpl(IRestApiService.class);
 		
 		//TODO We'll initialise this here for now, but it should really be done as
 		//part of the controller core
-		proxyArp = new ProxyArpManager(floodlightProvider, topology, this, restApi);
+		proxyArp = new ProxyArpManager(floodlightProvider, topologyService, this, restApi);
 		
 		linkUpdates = new ArrayList<LDUpdate>();
 		ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
@@ -318,7 +319,7 @@
 	@Override
 	public void startUp(FloodlightModuleContext context) {
 		restApi.addRestletRoutable(new BgpRouteWebRoutable());
-		topology.addListener(this);
+		topologyService.addListener(this);
 		floodlightProvider.addOFSwitchListener(this);
 		
 		proxyArp.startUp();
@@ -483,7 +484,7 @@
 	}
 	
 	private void addPrefixFlows(Prefix prefix, Interface egressInterface, MACAddress nextHopMacAddress) {		
-		log.debug("Adding flows for prefix {} added, next hop mac {}",
+		log.debug("Adding flows for prefix {}, next hop mac {}",
 				prefix, nextHopMacAddress);
 		
 		//We only need one flow mod per switch, so pick one interface on each switch
@@ -498,14 +499,14 @@
 		//Add a flow to rewrite mac for this prefix to all other border switches
 		for (Interface srcInterface : srcInterfaces.values()) {
 			DataPath shortestPath; 
-			if (shortestPathTopo == null) {
-				shortestPath = topologyNetService.getShortestPath(
+			if (topology == null) {
+				shortestPath = topologyNetService.getDatabaseShortestPath(
 						srcInterface.getSwitchPort(),
 						egressInterface.getSwitchPort());
 			}
 			else {
-				shortestPath = topologyNetService.getTopoShortestPath(
-						shortestPathTopo, srcInterface.getSwitchPort(),
+				shortestPath = topologyNetService.getTopologyShortestPath(
+						topology, srcInterface.getSwitchPort(),
 						egressInterface.getSwitchPort());
 			}
 			
@@ -692,17 +693,17 @@
 		List<PushedFlowMod> pushedFlows = new ArrayList<PushedFlowMod>();
 		
 		for (Interface srcInterface : interfaces.values()) {
-			if (dstInterface.equals(srcInterface.getName())){
+			if (dstInterface.getName().equals(srcInterface.getName())){
 				continue;
 			}
 			
 			DataPath shortestPath;
-			if (shortestPathTopo == null) {
-				shortestPath = topologyNetService.getShortestPath(
+			if (topology == null) {
+				shortestPath = topologyNetService.getDatabaseShortestPath(
 						srcInterface.getSwitchPort(), dstInterface.getSwitchPort());
 			}
 			else {
-				shortestPath = topologyNetService.getTopoShortestPath(shortestPathTopo, 
+				shortestPath = topologyNetService.getTopologyShortestPath(topology, 
 						srcInterface.getSwitchPort(), dstInterface.getSwitchPort());
 			}
 			
@@ -771,7 +772,7 @@
 		for (BgpPeer bgpPeer : bgpPeers.values()){
 			Interface peerInterface = interfaces.get(bgpPeer.getInterfaceName());
 			
-			DataPath path = topologyNetService.getShortestPath(
+			DataPath path = topologyNetService.getDatabaseShortestPath(
 					peerInterface.getSwitchPort(), bgpdAttachmentPoint);
 			
 			if (path == null){
@@ -1046,7 +1047,7 @@
 	
 	private void beginRouting(){
 		log.debug("Topology is now ready, beginning routing function");
-		shortestPathTopo = topologyNetService.prepareShortestPathTopo();
+		topology = topologyNetService.newDatabaseTopology();
 		
 		setupArpFlows();
 		setupDefaultDropFlows();
@@ -1086,7 +1087,7 @@
 					continue;
 				}
 				
-				DataPath shortestPath = topologyNetService.getShortestPath(
+				DataPath shortestPath = topologyNetService.getDatabaseShortestPath(
 						srcInterface.getSwitchPort(), dstInterface.getSwitchPort());
 				
 				if (shortestPath == null){
@@ -1120,10 +1121,22 @@
 					RibUpdate update = ribUpdates.take();
 					switch (update.getOperation()){
 					case UPDATE:
-						processRibAdd(update);
+						if (validateUpdate(update)) {
+							processRibAdd(update);
+						}
+						else {
+							log.debug("Rib UPDATE out of order: {} via {}",
+									update.getPrefix(), update.getRibEntry().getNextHop());
+						}
 						break;
 					case DELETE:
-						processRibDelete(update);
+						if (validateUpdate(update)) {
+							processRibDelete(update);
+						}
+						else {
+							log.debug("Rib DELETE out of order: {} via {}",
+									update.getPrefix(), update.getRibEntry().getNextHop());
+						}
 						break;
 					}
 				} catch (InterruptedException e) {
@@ -1139,6 +1152,40 @@
 			}
 		}
 	}
+	
+	private boolean validateUpdate(RibUpdate update) {
+		RibEntry newEntry = update.getRibEntry();
+		RibEntry oldEntry = ptree.lookup(update.getPrefix());
+		
+		//If there is no existing entry we must assume this is the most recent
+		//update. However this might not always be the case as we might have a
+		//POST then DELETE reordering.
+		//if (oldEntry == null || !newEntry.getNextHop().equals(oldEntry.getNextHop())) {
+		if (oldEntry == null) {
+			return true;
+		}
+		
+		// This handles the case where routes are gathered in the initial
+		// request because they don't have sequence number info
+		if (newEntry.getSysUpTime() == -1 && newEntry.getSequenceNum() == -1) {
+			return true;
+		}
+		
+		if (newEntry.getSysUpTime() > oldEntry.getSysUpTime()) {
+			return true;
+		}
+		else if (newEntry.getSysUpTime() == oldEntry.getSysUpTime()) {
+			if (newEntry.getSequenceNum() > oldEntry.getSequenceNum()) {
+				return true;
+			}
+			else {
+				return false;
+			}
+		}
+		else {
+			return false;
+		}
+	}
 
 	@Override
 	public void topologyChanged() {
@@ -1147,7 +1194,7 @@
 		}
 		
 		boolean refreshNeeded = false;
-		for (LDUpdate ldu : topology.getLastLinkUpdates()){
+		for (LDUpdate ldu : topologyService.getLastLinkUpdates()){
 			if (!ldu.getOperation().equals(ILinkDiscovery.UpdateOperation.LINK_UPDATED)){
 				//We don't need to recalculate anything for just link updates
 				//They happen very frequently
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRouteResource.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRouteResource.java
index 8403f71..c1f0cd6 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRouteResource.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRouteResource.java
@@ -68,19 +68,27 @@
 		IBgpRouteService bgpRoute = (IBgpRouteService) getContext().getAttributes().
 				get(IBgpRouteService.class.getCanonicalName());
 
+		String strSysuptime = (String) getRequestAttributes().get("sysuptime");
+		String strSequence = (String) getRequestAttributes().get("sequence");
 		String routerId = (String) getRequestAttributes().get("routerid");
 		String prefix = (String) getRequestAttributes().get("prefix");
 		String mask = (String) getRequestAttributes().get("mask");
 		String nexthop = (String) getRequestAttributes().get("nexthop");
 		String capability = (String) getRequestAttributes().get("capability");
+		
+		log.debug("sysuptime: {}", strSysuptime);
+		log.debug("sequence: {}", strSequence);
 
 		String reply = "";
 
 		if (capability == null) {
 			// this is a prefix add
 			Prefix p;
+			long sysUpTime, sequenceNum;
 			try {
 				p = new Prefix(prefix, Integer.valueOf(mask));
+				sysUpTime = Long.parseLong(strSysuptime);
+				sequenceNum = Long.parseLong(strSequence);
 			} catch (NumberFormatException e) {
 				reply = "[POST: mask format is wrong]";
 				log.info(reply);
@@ -91,7 +99,7 @@
 				return reply + "\n";
 			}
 			
-			RibEntry rib = new RibEntry(routerId, nexthop);
+			RibEntry rib = new RibEntry(routerId, nexthop, sysUpTime, sequenceNum);
 
 			bgpRoute.newRibUpdate(new RibUpdate(Operation.UPDATE, p, rib));
 			
@@ -117,19 +125,27 @@
 		IBgpRouteService bgpRoute = (IBgpRouteService)getContext().getAttributes().
 				get(IBgpRouteService.class.getCanonicalName());
 
+		String strSysuptime = (String) getRequestAttributes().get("sysuptime");
+		String strSequence = (String) getRequestAttributes().get("sequence");
 		String routerId = (String) getRequestAttributes().get("routerid");
 		String prefix = (String) getRequestAttributes().get("prefix");
 		String mask = (String) getRequestAttributes().get("mask");
 		String nextHop = (String) getRequestAttributes().get("nexthop");
 		String capability = (String) getRequestAttributes().get("capability");
 
+		log.debug("sysuptime: {}", strSysuptime);
+		log.debug("sequence: {}", strSequence);
+		
 		String reply = "";
 
 		if (capability == null) {
 			// this is a prefix delete
 			Prefix p;
+			long sysUpTime, sequenceNum;
 			try {
 				p = new Prefix(prefix, Integer.valueOf(mask));
+				sysUpTime = Long.parseLong(strSysuptime);
+				sequenceNum = Long.parseLong(strSequence);
 			} catch (NumberFormatException e) {
 				reply = "[DELE: mask format is wrong]";
 				log.info(reply);
@@ -140,7 +156,7 @@
 				return reply + "\n";
 			}
 			
-			RibEntry r = new RibEntry(routerId, nextHop);
+			RibEntry r = new RibEntry(routerId, nextHop, sysUpTime, sequenceNum);
 			
 			bgpRoute.newRibUpdate(new RibUpdate(Operation.DELETE, p, r));
 			
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRouteWebRoutable.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRouteWebRoutable.java
index 669c385..26971b0 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRouteWebRoutable.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRouteWebRoutable.java
@@ -12,7 +12,7 @@
 		Router router = new Router(context);
 		router.attach("/json", BgpRouteResource.class);
 		router.attach("/rib/{dest}", BgpRouteResource.class);
-		router.attach("/{routerid}/{prefix}/{mask}/{nexthop}", BgpRouteResource.class);		
+		router.attach("/{sysuptime}/{sequence}/{routerid}/{prefix}/{mask}/{nexthop}", BgpRouteResource.class);		
 		router.attach("/{routerid}/{prefix}/{mask}/{nexthop}/synch", BgpRouteResourceSynch.class);
 		router.attach("/{routerid}/{capability}", BgpRouteResource.class);
 		return router;
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/RibEntry.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/RibEntry.java
index 1520c60..ccf8951 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/bgproute/RibEntry.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/RibEntry.java
@@ -7,21 +7,57 @@
 public class RibEntry {
 	private final InetAddress routerId;
 	private final InetAddress nextHop;
+
+	/*
+	 * Store the sequence number information provided on the update here for
+	 * now. I think this *should* really be in the RibUpdate, and we should
+	 * store RibUpdates in the Ptrie. But, that's a bigger change to change
+	 * what the Ptrie stores.
+	 */
+	private final long sysUpTime;
+	private final long sequenceNum;
+	
+	/*
+	 * Marker for RibEntries where we don't have sequence number info.
+	 * The user of this class should make sure they don't check this data
+	 * if they don't provide it.
+	 */
+	private final static long NULL_TIME = -1;
 	
 	public RibEntry(InetAddress routerId, InetAddress nextHop) {
 		this.routerId = routerId;
 		this.nextHop = nextHop;
+		sequenceNum = NULL_TIME;
+		sysUpTime = NULL_TIME;
 	}
 	
 	public RibEntry(String routerId, String nextHop) {
 		this.routerId = InetAddresses.forString(routerId);
 		this.nextHop = InetAddresses.forString(nextHop);
+		sequenceNum = NULL_TIME;
+		sysUpTime = NULL_TIME;
+	}
+	
+	public RibEntry(String routerId, String nextHop, long sysUpTime
+			, long sequenceNum) {
+		this.routerId = InetAddresses.forString(routerId);
+		this.nextHop = InetAddresses.forString(nextHop);
+		this.sequenceNum = sequenceNum;
+		this.sysUpTime = sysUpTime;
 	}
 	
 	public InetAddress getNextHop() {
 	    return nextHop;
 	}
 	
+	public long getSysUpTime() {
+		return sysUpTime;
+	}
+	
+	public long getSequenceNum() {
+		return sequenceNum;
+	}
+	
 	@Override
 	public boolean equals(Object other) {
 		if (other == null || !(other instanceof RibEntry)) {
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 978fcde..cd3cf15 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
@@ -18,7 +18,7 @@
 	}
 
 	public TopoSwitchServiceImpl() {
-		this("/tmp/cassandra.titan");
+		this("");
 	}
 	
 	public void finalize() {
diff --git a/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/INetworkGraphService.java b/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/INetworkGraphService.java
new file mode 100644
index 0000000..121eaf9
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/INetworkGraphService.java
@@ -0,0 +1,10 @@
+package net.onrc.onos.ofcontroller.floodlightlistener;
+
+import net.floodlightcontroller.core.module.IFloodlightService;
+
+/**
+ * Interface for providing Network Graph Service to other module.
+ */
+public interface INetworkGraphService extends IFloodlightService {
+    // TODO
+}
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 046a38b..852cbb8 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/NetworkGraphPublisher.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/NetworkGraphPublisher.java
@@ -2,6 +2,7 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
@@ -45,8 +46,12 @@
 import net.onrc.onos.registry.controller.IControllerRegistryService.ControlChangeCallback;
 import net.onrc.onos.registry.controller.RegistryException;
 
-public class NetworkGraphPublisher implements IDeviceListener, IOFSwitchListener, IOFSwitchPortListener,
-		ILinkDiscoveryListener, IFloodlightModule {
+public class NetworkGraphPublisher implements IDeviceListener,
+					      IOFSwitchListener,
+					      IOFSwitchPortListener,
+					      ILinkDiscoveryListener,
+					      IFloodlightModule,
+					      INetworkGraphService {
 	
 	protected IDeviceStorage devStore;
 	protected ISwitchStorage swStore;
@@ -229,14 +234,20 @@
 
 	@Override
 	public Collection<Class<? extends IFloodlightService>> getModuleServices() {
-		// TODO Auto-generated method stub
-		return null;
+		Collection<Class<? extends IFloodlightService>> l =
+		    new ArrayList<Class<? extends IFloodlightService>>();
+		l.add(INetworkGraphService.class);
+		return l;
 	}
 
 	@Override
 	public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
-		// TODO Auto-generated method stub
-		return null;
+		Map<Class<? extends IFloodlightService>,
+		    IFloodlightService> m =
+		    new HashMap<Class<? extends IFloodlightService>,
+		    IFloodlightService>();
+		m.put(INetworkGraphService.class, this);
+		return m;
 	}
 
 	@Override
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
new file mode 100644
index 0000000..7550b37
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
@@ -0,0 +1,926 @@
+package net.onrc.onos.ofcontroller.flowmanager;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+import net.floodlightcontroller.util.MACAddress;
+
+import net.onrc.onos.graph.GraphDBOperation;
+
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.util.*;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Class for performing Flow-related operations on the Database.
+ */
+class FlowDatabaseOperation {
+    private static Logger log = LoggerFactory.getLogger(FlowDatabaseOperation.class);
+
+    /**
+     * Add a flow.
+     *
+     * @param flowManager the Flow Manager to use.
+     * @param dbHandler the Graph Database handler to use.
+     * @param flowPath the Flow Path to install.
+     * @param flowId the return-by-reference Flow ID as assigned internally.
+     * @param dataPathSummaryStr the data path summary string if the added
+     * flow will be maintained internally, otherwise null.
+     * @return true on success, otherwise false.
+     */
+    static boolean addFlow(FlowManager flowManager,
+			   GraphDBOperation dbHandler,
+			   FlowPath flowPath, FlowId flowId,
+			   String dataPathSummaryStr) {
+	IFlowPath flowObj = null;
+	boolean found = false;
+	try {
+	    if ((flowObj = dbHandler.searchFlowPath(flowPath.flowId())) != null) {
+		found = true;
+	    } else {
+		flowObj = dbHandler.newFlowPath();
+	    }
+	} catch (Exception e) {
+	    dbHandler.rollback();
+
+	    StringWriter sw = new StringWriter();
+	    e.printStackTrace(new PrintWriter(sw));
+	    String stacktrace = sw.toString();
+
+	    log.error(":addFlow FlowId:{} failed: {}",
+		      flowPath.flowId().toString(),
+		      stacktrace);
+	    return false;
+	}
+	if (flowObj == null) {
+	    log.error(":addFlow FlowId:{} failed: Flow object not created",
+		      flowPath.flowId().toString());
+	    dbHandler.rollback();
+	    return false;
+	}
+
+	//
+	// Set the Flow key:
+	// - flowId
+	//
+	flowObj.setFlowId(flowPath.flowId().toString());
+	flowObj.setType("flow");
+
+	//
+	// Set the Flow attributes:
+	// - flowPath.installerId()
+	// - flowPath.flowPathFlags()
+	// - flowPath.dataPath().srcPort()
+	// - flowPath.dataPath().dstPort()
+	// - flowPath.matchSrcMac()
+	// - flowPath.matchDstMac()
+	// - flowPath.matchEthernetFrameType()
+	// - flowPath.matchVlanId()
+	// - flowPath.matchVlanPriority()
+	// - flowPath.matchSrcIPv4Net()
+	// - flowPath.matchDstIPv4Net()
+	// - flowPath.matchIpProto()
+	// - flowPath.matchIpToS()
+	// - flowPath.matchSrcTcpUdpPort()
+	// - flowPath.matchDstTcpUdpPort()
+	// - flowPath.flowEntryActions()
+	//
+	flowObj.setInstallerId(flowPath.installerId().toString());
+	flowObj.setFlowPathFlags(flowPath.flowPathFlags().flags());
+	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());
+	if (flowPath.flowEntryMatch().matchSrcMac()) {
+	    flowObj.setMatchSrcMac(flowPath.flowEntryMatch().srcMac().toString());
+	}
+	if (flowPath.flowEntryMatch().matchDstMac()) {
+	    flowObj.setMatchDstMac(flowPath.flowEntryMatch().dstMac().toString());
+	}
+	if (flowPath.flowEntryMatch().matchEthernetFrameType()) {
+	    flowObj.setMatchEthernetFrameType(flowPath.flowEntryMatch().ethernetFrameType());
+	}
+	if (flowPath.flowEntryMatch().matchVlanId()) {
+	    flowObj.setMatchVlanId(flowPath.flowEntryMatch().vlanId());
+	}
+	if (flowPath.flowEntryMatch().matchVlanPriority()) {
+	    flowObj.setMatchVlanPriority(flowPath.flowEntryMatch().vlanPriority());
+	}
+	if (flowPath.flowEntryMatch().matchSrcIPv4Net()) {
+	    flowObj.setMatchSrcIPv4Net(flowPath.flowEntryMatch().srcIPv4Net().toString());
+	}
+	if (flowPath.flowEntryMatch().matchDstIPv4Net()) {
+	    flowObj.setMatchDstIPv4Net(flowPath.flowEntryMatch().dstIPv4Net().toString());
+	}
+	if (flowPath.flowEntryMatch().matchIpProto()) {
+	    flowObj.setMatchIpProto(flowPath.flowEntryMatch().ipProto());
+	}
+	if (flowPath.flowEntryMatch().matchIpToS()) {
+	    flowObj.setMatchIpToS(flowPath.flowEntryMatch().ipToS());
+	}
+	if (flowPath.flowEntryMatch().matchSrcTcpUdpPort()) {
+	    flowObj.setMatchSrcTcpUdpPort(flowPath.flowEntryMatch().srcTcpUdpPort());
+	}
+	if (flowPath.flowEntryMatch().matchDstTcpUdpPort()) {
+	    flowObj.setMatchDstTcpUdpPort(flowPath.flowEntryMatch().dstTcpUdpPort());
+	}
+	if (! flowPath.flowEntryActions().actions().isEmpty()) {
+	    flowObj.setActions(flowPath.flowEntryActions().toString());
+	}
+
+	if (dataPathSummaryStr != null) {
+	    flowObj.setDataPathSummary(dataPathSummaryStr);
+	} else {
+	    flowObj.setDataPathSummary("");
+	}
+
+	if (found)
+	    flowObj.setUserState("FE_USER_MODIFY");
+	else
+	    flowObj.setUserState("FE_USER_ADD");
+
+	// Flow edges:
+	//   HeadFE
+
+
+	//
+	// Flow Entries:
+	// flowPath.dataPath().flowEntries()
+	//
+	for (FlowEntry flowEntry : flowPath.dataPath().flowEntries()) {
+	    if (addFlowEntry(flowManager, dbHandler, flowObj, flowEntry) == null) {
+		dbHandler.rollback();
+		return false;
+	    }
+	}
+	dbHandler.commit();
+
+	//
+	// TODO: We need a proper Flow ID allocation mechanism.
+	//
+	flowId.setValue(flowPath.flowId().value());
+
+	return true;
+    }
+
+    /**
+     * Add a flow entry to the Network MAP.
+     *
+     * @param flowManager the Flow Manager to use.
+     * @param dbHandler the Graph Database handler to use.
+     * @param flowObj the corresponding Flow Path object for the Flow Entry.
+     * @param flowEntry the Flow Entry to install.
+     * @return the added Flow Entry object on success, otherwise null.
+     */
+    static IFlowEntry addFlowEntry(FlowManager flowManager,
+				   GraphDBOperation dbHandler,
+				   IFlowPath flowObj,
+				   FlowEntry flowEntry) {
+	// Flow edges
+	//   HeadFE (TODO)
+
+	//
+	// Assign the FlowEntry ID.
+	//
+	if ((flowEntry.flowEntryId() == null) ||
+	    (flowEntry.flowEntryId().value() == 0)) {
+	    long id = flowManager.getNextFlowEntryId();
+	    flowEntry.setFlowEntryId(new FlowEntryId(id));
+	}
+
+	IFlowEntry flowEntryObj = null;
+	boolean found = false;
+	try {
+	    if ((flowEntryObj =
+		 dbHandler.searchFlowEntry(flowEntry.flowEntryId())) != null) {
+		found = true;
+	    } else {
+		flowEntryObj = dbHandler.newFlowEntry();
+	    }
+	} catch (Exception e) {
+	    log.error(":addFlow FlowEntryId:{} failed",
+		      flowEntry.flowEntryId().toString());
+	    return null;
+	}
+	if (flowEntryObj == null) {
+	    log.error(":addFlow FlowEntryId:{} failed: FlowEntry object not created",
+		      flowEntry.flowEntryId().toString());
+	    return null;
+	}
+
+	//
+	// Set the Flow Entry key:
+	// - flowEntry.flowEntryId()
+	//
+	flowEntryObj.setFlowEntryId(flowEntry.flowEntryId().toString());
+	flowEntryObj.setType("flow_entry");
+
+	// 
+	// Set the Flow Entry Edges and attributes:
+	// - Switch edge
+	// - InPort edge
+	// - OutPort edge
+	//
+	// - flowEntry.dpid()
+	// - flowEntry.flowEntryUserState()
+	// - flowEntry.flowEntrySwitchState()
+	// - flowEntry.flowEntryErrorState()
+	// - flowEntry.matchInPort()
+	// - flowEntry.matchSrcMac()
+	// - flowEntry.matchDstMac()
+	// - flowEntry.matchEthernetFrameType()
+	// - flowEntry.matchVlanId()
+	// - flowEntry.matchVlanPriority()
+	// - flowEntry.matchSrcIPv4Net()
+	// - flowEntry.matchDstIPv4Net()
+	// - flowEntry.matchIpProto()
+	// - flowEntry.matchIpToS()
+	// - flowEntry.matchSrcTcpUdpPort()
+	// - flowEntry.matchDstTcpUdpPort()
+	// - flowEntry.actionOutputPort()
+	// - flowEntry.actions()
+	//
+	ISwitchObject sw = dbHandler.searchSwitch(flowEntry.dpid().toString());
+	flowEntryObj.setSwitchDpid(flowEntry.dpid().toString());
+	flowEntryObj.setSwitch(sw);
+	if (flowEntry.flowEntryMatch().matchInPort()) {
+	    IPortObject inport =
+		dbHandler.searchPort(flowEntry.dpid().toString(),
+					flowEntry.flowEntryMatch().inPort().value());
+	    flowEntryObj.setMatchInPort(flowEntry.flowEntryMatch().inPort().value());
+	    flowEntryObj.setInPort(inport);
+	}
+	if (flowEntry.flowEntryMatch().matchSrcMac()) {
+	    flowEntryObj.setMatchSrcMac(flowEntry.flowEntryMatch().srcMac().toString());
+	}
+	if (flowEntry.flowEntryMatch().matchDstMac()) {
+	    flowEntryObj.setMatchDstMac(flowEntry.flowEntryMatch().dstMac().toString());
+	}
+	if (flowEntry.flowEntryMatch().matchEthernetFrameType()) {
+	    flowEntryObj.setMatchEthernetFrameType(flowEntry.flowEntryMatch().ethernetFrameType());
+	}
+	if (flowEntry.flowEntryMatch().matchVlanId()) {
+	    flowEntryObj.setMatchVlanId(flowEntry.flowEntryMatch().vlanId());
+	}
+	if (flowEntry.flowEntryMatch().matchVlanPriority()) {
+	    flowEntryObj.setMatchVlanPriority(flowEntry.flowEntryMatch().vlanPriority());
+	}
+	if (flowEntry.flowEntryMatch().matchSrcIPv4Net()) {
+	    flowEntryObj.setMatchSrcIPv4Net(flowEntry.flowEntryMatch().srcIPv4Net().toString());
+	}
+	if (flowEntry.flowEntryMatch().matchDstIPv4Net()) {
+	    flowEntryObj.setMatchDstIPv4Net(flowEntry.flowEntryMatch().dstIPv4Net().toString());
+	}
+	if (flowEntry.flowEntryMatch().matchIpProto()) {
+	    flowEntryObj.setMatchIpProto(flowEntry.flowEntryMatch().ipProto());
+	}
+	if (flowEntry.flowEntryMatch().matchIpToS()) {
+	    flowEntryObj.setMatchIpToS(flowEntry.flowEntryMatch().ipToS());
+	}
+	if (flowEntry.flowEntryMatch().matchSrcTcpUdpPort()) {
+	    flowEntryObj.setMatchSrcTcpUdpPort(flowEntry.flowEntryMatch().srcTcpUdpPort());
+	}
+	if (flowEntry.flowEntryMatch().matchDstTcpUdpPort()) {
+	    flowEntryObj.setMatchDstTcpUdpPort(flowEntry.flowEntryMatch().dstTcpUdpPort());
+	}
+
+	for (FlowEntryAction fa : flowEntry.flowEntryActions().actions()) {
+	    if (fa.actionOutput() != null) {
+		IPortObject outport =
+		    dbHandler.searchPort(flowEntry.dpid().toString(),
+					      fa.actionOutput().port().value());
+		flowEntryObj.setActionOutputPort(fa.actionOutput().port().value());
+		flowEntryObj.setOutPort(outport);
+	    }
+	}
+	if (! flowEntry.flowEntryActions().isEmpty()) {
+	    flowEntryObj.setActions(flowEntry.flowEntryActions().toString());
+	}
+
+	// TODO: Hacks with hard-coded state names!
+	if (found)
+	    flowEntryObj.setUserState("FE_USER_MODIFY");
+	else
+	    flowEntryObj.setUserState("FE_USER_ADD");
+	flowEntryObj.setSwitchState("FE_SWITCH_NOT_UPDATED");
+	//
+	// TODO: Take care of the FlowEntryErrorState.
+	//
+
+	// Flow Entries edges:
+	//   Flow
+	//   NextFE (TODO)
+	if (! found) {
+	    flowObj.addFlowEntry(flowEntryObj);
+	    flowEntryObj.setFlow(flowObj);
+	}
+
+	return flowEntryObj;
+    }
+
+    /**
+     * Delete all previously added flows.
+     *
+     * @param dbHandler the Graph Database handler to use.
+     * @return true on success, otherwise false.
+     */
+    static boolean deleteAllFlows(GraphDBOperation dbHandler) {
+	final ConcurrentLinkedQueue<FlowId> concurrentAllFlowIds =
+	    new ConcurrentLinkedQueue<FlowId>();
+
+	// Get all Flow IDs
+	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);
+	    concurrentAllFlowIds.add(flowId);
+	}
+
+	// Delete all flows one-by-one
+	for (FlowId flowId : concurrentAllFlowIds)
+	    deleteFlow(dbHandler, flowId);
+
+	/*
+	 * TODO: A faster mechanism to delete the Flow Paths by using
+	 * a number of threads. Commented-out for now.
+	 */
+	/*
+	//
+	// Create the threads to delete the Flow Paths
+	//
+	List<Thread> threads = new LinkedList<Thread>();
+	for (int i = 0; i < 10; i++) {
+	    Thread thread = new Thread(new Runnable() {
+		@Override
+		public void run() {
+		    while (true) {
+			FlowId flowId = concurrentAllFlowIds.poll();
+			if (flowId == null)
+			    return;
+			deleteFlow(dbHandler, flowId);
+		    }
+		}}, "Delete All Flow Paths");
+	    threads.add(thread);
+	}
+
+	// Start processing
+	for (Thread thread : threads) {
+	    thread.start();
+	}
+
+	// Wait for all threads to complete
+	for (Thread thread : threads) {
+	    try {
+		thread.join();
+	    } catch (InterruptedException e) {
+		log.debug("Exception waiting for a thread to delete a Flow Path: ", e);
+	    }
+	}
+	*/
+
+	return true;
+    }
+
+    /**
+     * Delete a previously added flow.
+     *
+     * @param dbHandler the Graph Database handler to use.
+     * @param flowId the Flow ID of the flow to delete.
+     * @return true on success, otherwise false.
+     */
+    static boolean deleteFlow(GraphDBOperation dbHandler, FlowId flowId) {
+	IFlowPath flowObj = null;
+	//
+	// We just mark the entries for deletion,
+	// and let the switches remove each individual entry after
+	// it has been removed from the switches.
+	//
+	try {
+	    flowObj = dbHandler.searchFlowPath(flowId);
+	} catch (Exception e) {
+	    // TODO: handle exceptions
+	    dbHandler.rollback();
+	    log.error(":deleteFlow FlowId:{} failed", flowId.toString());
+	    return false;
+	}
+	if (flowObj == null) {
+	    dbHandler.commit();
+	    return true;		// OK: No such flow
+	}
+
+	//
+	// Find and mark for deletion all Flow Entries,
+	// and the Flow itself.
+	//
+	flowObj.setUserState("FE_USER_DELETE");
+	Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
+	boolean empty = true;	// TODO: an ugly hack
+	for (IFlowEntry flowEntryObj : flowEntries) {
+	    empty = false;
+	    // flowObj.removeFlowEntry(flowEntryObj);
+	    // conn.utils().removeFlowEntry(conn, flowEntryObj);
+	    flowEntryObj.setUserState("FE_USER_DELETE");
+	    flowEntryObj.setSwitchState("FE_SWITCH_NOT_UPDATED");
+	}
+	// Remove from the database empty flows
+	if (empty)
+	    dbHandler.removeFlowPath(flowObj);
+	dbHandler.commit();
+
+	return true;
+    }
+
+    /**
+     * Clear the state for all previously added flows.
+     *
+     * @param dbHandler the Graph Database handler to use.
+     * @return true on success, otherwise false.
+     */
+    static boolean clearAllFlows(GraphDBOperation dbHandler) {
+	List<FlowId> allFlowIds = new LinkedList<FlowId>();
+
+	// Get all Flow IDs
+	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);
+	}
+
+	// Clear all flows one-by-one
+	for (FlowId flowId : allFlowIds) {
+	    clearFlow(dbHandler, flowId);
+	}
+
+	return true;
+    }
+
+    /**
+     * Clear the state for a previously added flow.
+     *
+     * @param dbHandler the Graph Database handler to use.
+     * @param flowId the Flow ID of the flow to clear.
+     * @return true on success, otherwise false.
+     */
+    static boolean clearFlow(GraphDBOperation dbHandler, FlowId flowId) {
+	IFlowPath flowObj = null;
+	try {
+	    flowObj = dbHandler.searchFlowPath(flowId);
+	} catch (Exception e) {
+	    // TODO: handle exceptions
+	    dbHandler.rollback();
+	    log.error(":clearFlow FlowId:{} failed", flowId.toString());
+	    return false;
+	}
+	if (flowObj == null) {
+	    dbHandler.commit();
+	    return true;		// OK: No such flow
+	}
+
+	//
+	// Remove all Flow Entries
+	//
+	Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
+	for (IFlowEntry flowEntryObj : flowEntries) {
+	    flowObj.removeFlowEntry(flowEntryObj);
+	    dbHandler.removeFlowEntry(flowEntryObj);
+	}
+	// Remove the Flow itself
+	dbHandler.removeFlowPath(flowObj);
+	dbHandler.commit();
+
+	return true;
+    }
+
+    /**
+     * Get a previously added flow.
+     *
+     * @param dbHandler the Graph Database handler to use.
+     * @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) {
+	IFlowPath flowObj = null;
+	try {
+	    flowObj = dbHandler.searchFlowPath(flowId);
+	} catch (Exception e) {
+	    // TODO: handle exceptions
+	    dbHandler.rollback();
+	    log.error(":getFlow FlowId:{} failed", flowId.toString());
+	    return null;
+	}
+	if (flowObj == null) {
+	    dbHandler.commit();
+	    return null;		// Flow not found
+	}
+
+	//
+	// Extract the Flow state
+	//
+	FlowPath flowPath = extractFlowPath(flowObj);
+	dbHandler.commit();
+
+	return flowPath;
+    }
+
+    /**
+     * Get all installed flows by all installers.
+     *
+     * @param dbHandler the Graph Database handler to use.
+     * @return the Flow Paths if found, otherwise null.
+     */
+    static ArrayList<FlowPath> getAllFlows(GraphDBOperation dbHandler) {
+	Iterable<IFlowPath> flowPathsObj = null;
+	ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
+
+	try {
+	    flowPathsObj = dbHandler.getAllFlowPaths();
+	} catch (Exception e) {
+	    // TODO: handle exceptions
+	    dbHandler.rollback();
+	    log.error(":getAllFlowPaths failed");
+	    return flowPaths;
+	}
+	if ((flowPathsObj == null) || (flowPathsObj.iterator().hasNext() == false)) {
+	    dbHandler.commit();
+	    return flowPaths;	// No Flows found
+	}
+
+	for (IFlowPath flowObj : flowPathsObj) {
+	    //
+	    // Extract the Flow state
+	    //
+	    FlowPath flowPath = extractFlowPath(flowObj);
+	    if (flowPath != null)
+		flowPaths.add(flowPath);
+	}
+
+	dbHandler.commit();
+
+	return flowPaths;
+    }
+
+    /**
+     * Get all previously added flows by a specific installer for a given
+     * data path endpoints.
+     *
+     * @param dbHandler the Graph Database handler to use.
+     * @param installerId the Caller ID of the installer of the flow to get.
+     * @param dataPathEndpoints the data path endpoints of the flow to get.
+     * @return the Flow Paths if found, otherwise null.
+     */
+    static ArrayList<FlowPath> getAllFlows(GraphDBOperation dbHandler,
+					   CallerId installerId,
+					   DataPathEndpoints dataPathEndpoints) {
+	//
+	// TODO: The implementation below is not optimal:
+	// We fetch all flows, and then return only the subset that match
+	// the query conditions.
+	// We should use the appropriate Titan/Gremlin query to filter-out
+	// the flows as appropriate.
+	//
+	ArrayList<FlowPath> allFlows = getAllFlows(dbHandler);
+	ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
+
+	if (allFlows == null)
+	    return flowPaths;
+
+	for (FlowPath flow : allFlows) {
+	    //
+	    // TODO: String-based comparison is sub-optimal.
+	    // We are using it for now to save us the extra work of
+	    // implementing the "equals()" and "hashCode()" methods.
+	    //
+	    if (! flow.installerId().toString().equals(installerId.toString()))
+		continue;
+	    if (! flow.dataPath().srcPort().toString().equals(dataPathEndpoints.srcPort().toString())) {
+		continue;
+	    }
+	    if (! flow.dataPath().dstPort().toString().equals(dataPathEndpoints.dstPort().toString())) {
+		continue;
+	    }
+	    flowPaths.add(flow);
+	}
+
+	return flowPaths;
+    }
+
+    /**
+     * Get all installed flows by all installers for given data path endpoints.
+     *
+     * @param dbHandler the Graph Database handler to use.
+     * @param dataPathEndpoints the data path endpoints of the flows to get.
+     * @return the Flow Paths if found, otherwise null.
+     */
+    static ArrayList<FlowPath> getAllFlows(GraphDBOperation dbHandler,
+					   DataPathEndpoints dataPathEndpoints) {
+	//
+	// TODO: The implementation below is not optimal:
+	// We fetch all flows, and then return only the subset that match
+	// the query conditions.
+	// We should use the appropriate Titan/Gremlin query to filter-out
+	// the flows as appropriate.
+	//
+	ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
+	ArrayList<FlowPath> allFlows = getAllFlows(dbHandler);
+
+	if (allFlows == null)
+	    return flowPaths;
+
+	for (FlowPath flow : allFlows) {
+	    //
+	    // TODO: String-based comparison is sub-optimal.
+	    // We are using it for now to save us the extra work of
+	    // implementing the "equals()" and "hashCode()" methods.
+	    //
+	    if (! flow.dataPath().srcPort().toString().equals(dataPathEndpoints.srcPort().toString())) {
+		continue;
+	    }
+	    if (! flow.dataPath().dstPort().toString().equals(dataPathEndpoints.dstPort().toString())) {
+		continue;
+	    }
+	    flowPaths.add(flow);
+	}
+
+	return flowPaths;
+    }
+
+    /**
+     * Get summary of all installed flows by all installers in a given range.
+     *
+     * @param dbHandler the Graph Database handler to use.
+     * @param flowId the Flow ID of the first flow in the flow range to get.
+     * @param maxFlows the maximum number of flows to be returned.
+     * @return the Flow Paths if found, otherwise null.
+     */
+    static ArrayList<IFlowPath> getAllFlowsSummary(GraphDBOperation dbHandler,
+						   FlowId flowId,
+						   int maxFlows) {
+	//
+	// TODO: The implementation below is not optimal:
+	// We fetch all flows, and then return only the subset that match
+	// the query conditions.
+	// We should use the appropriate Titan/Gremlin query to filter-out
+	// the flows as appropriate.
+	//
+    	ArrayList<IFlowPath> flowPathsWithoutFlowEntries =
+	    getAllFlowsWithoutFlowEntries(dbHandler);
+
+    	Collections.sort(flowPathsWithoutFlowEntries, 
+			 new Comparator<IFlowPath>() {
+			     @Override
+			     public int compare(IFlowPath first, IFlowPath second) {
+				 long result =
+				     new FlowId(first.getFlowId()).value()
+				     - new FlowId(second.getFlowId()).value();
+				 if (result > 0) {
+				     return 1;
+				 } else if (result < 0) {
+				     return -1;
+				 } else {
+				     return 0;
+				 }
+			     }
+			 }
+			 );
+    	
+    	return flowPathsWithoutFlowEntries;
+    }
+
+    /**
+     * Get all Flows information, without the associated Flow Entries.
+     *
+     * @param dbHandler the Graph Database handler to use.
+     * @return all Flows information, without the associated Flow Entries.
+     */
+    static ArrayList<IFlowPath> getAllFlowsWithoutFlowEntries(GraphDBOperation dbHandler) {
+    	Iterable<IFlowPath> flowPathsObj = null;
+    	ArrayList<IFlowPath> flowPathsObjArray = new ArrayList<IFlowPath>();
+
+	// TODO: Remove this op.commit() flow, because it is not needed?
+    	dbHandler.commit();
+
+    	try {
+    	    flowPathsObj = dbHandler.getAllFlowPaths();
+    	} catch (Exception e) {
+    	    // TODO: handle exceptions
+    	    dbHandler.rollback();
+    	    log.error(":getAllFlowPaths failed");
+	    return flowPathsObjArray;		// No Flows found
+    	}
+    	if ((flowPathsObj == null) || (flowPathsObj.iterator().hasNext() == false)) {
+    	    return flowPathsObjArray;		// No Flows found
+    	}
+
+    	for (IFlowPath flowObj : flowPathsObj)
+	    flowPathsObjArray.add(flowObj);
+
+    	// conn.endTx(Transaction.COMMIT);
+
+    	return flowPathsObjArray;
+    }
+
+    /**
+     * Extract Flow Path State from a Titan Database Object @ref IFlowPath.
+     *
+     * @param flowObj the object to extract the Flow Path State from.
+     * @return the extracted Flow Path State.
+     */
+    private static FlowPath extractFlowPath(IFlowPath flowObj) {
+	//
+	// Extract the Flow state
+	//
+	String flowIdStr = flowObj.getFlowId();
+	String installerIdStr = flowObj.getInstallerId();
+	Long flowPathFlags = flowObj.getFlowPathFlags();
+	String srcSwitchStr = flowObj.getSrcSwitch();
+	Short srcPortShort = flowObj.getSrcPort();
+	String dstSwitchStr = flowObj.getDstSwitch();
+	Short dstPortShort = flowObj.getDstPort();
+
+	if ((flowIdStr == null) ||
+	    (installerIdStr == null) ||
+	    (flowPathFlags == null) ||
+	    (srcSwitchStr == null) ||
+	    (srcPortShort == null) ||
+	    (dstSwitchStr == null) ||
+	    (dstPortShort == null)) {
+	    // TODO: A work-around, becauuse of some bogus database objects
+	    return null;
+	}
+
+	FlowPath flowPath = new FlowPath();
+	flowPath.setFlowId(new FlowId(flowIdStr));
+	flowPath.setInstallerId(new CallerId(installerIdStr));
+	flowPath.setFlowPathFlags(new FlowPathFlags(flowPathFlags));
+	flowPath.dataPath().srcPort().setDpid(new Dpid(srcSwitchStr));
+	flowPath.dataPath().srcPort().setPort(new Port(srcPortShort));
+	flowPath.dataPath().dstPort().setDpid(new Dpid(dstSwitchStr));
+	flowPath.dataPath().dstPort().setPort(new Port(dstPortShort));
+	//
+	// 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);
+
+	    flowPath.setFlowEntryMatch(match);
+	}
+	//
+	// Extract the actions for the first Flow Entry
+	//
+	{
+	    String actionsStr = flowObj.getActions();
+	    if (actionsStr != null) {
+		FlowEntryActions flowEntryActions = new FlowEntryActions(actionsStr);
+		flowPath.setFlowEntryActions(flowEntryActions);
+	    }
+	}
+
+	//
+	// Extract all Flow Entries
+	//
+	Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
+	for (IFlowEntry flowEntryObj : flowEntries) {
+	    FlowEntry flowEntry = extractFlowEntry(flowEntryObj);
+	    if (flowEntry == null)
+		continue;
+	    flowPath.dataPath().flowEntries().add(flowEntry);
+	}
+
+	return flowPath;
+    }
+
+    /**
+     * Extract Flow Entry State from a Titan Database Object @ref IFlowEntry.
+     *
+     * @param flowEntryObj the object to extract the Flow Entry State from.
+     * @return the extracted Flow Entry State.
+     */
+    private static FlowEntry extractFlowEntry(IFlowEntry flowEntryObj) {
+	String flowEntryIdStr = flowEntryObj.getFlowEntryId();
+	String switchDpidStr = flowEntryObj.getSwitchDpid();
+	String userState = flowEntryObj.getUserState();
+	String switchState = flowEntryObj.getSwitchState();
+
+	if ((flowEntryIdStr == null) ||
+	    (switchDpidStr == null) ||
+	    (userState == null) ||
+	    (switchState == null)) {
+	    // TODO: A work-around, becauuse of some bogus database objects
+	    return null;
+	}
+
+	FlowEntry flowEntry = new FlowEntry();
+	flowEntry.setFlowEntryId(new FlowEntryId(flowEntryIdStr));
+	flowEntry.setDpid(new Dpid(switchDpidStr));
+
+	//
+	// 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);
+	flowEntry.setFlowEntryMatch(match);
+
+	//
+	// Extract the actions
+	//
+	FlowEntryActions actions = new FlowEntryActions();
+	String actionsStr = flowEntryObj.getActions();
+	if (actionsStr != null)
+	    actions = new FlowEntryActions(actionsStr);
+	flowEntry.setFlowEntryActions(actions);
+	flowEntry.setFlowEntryUserState(FlowEntryUserState.valueOf(userState));
+	flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.valueOf(switchState));
+	//
+	// TODO: Take care of FlowEntryErrorState.
+	//
+	return flowEntry;
+    }
+}
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 2c5f4ba..e11814b 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
@@ -1,19 +1,12 @@
 package net.onrc.onos.ofcontroller.flowmanager;
 
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
 import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.LinkedList;
-import java.util.List;
 import java.util.Map;
 import java.util.Random;
-import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
@@ -25,42 +18,20 @@
 import net.floodlightcontroller.core.module.IFloodlightModule;
 import net.floodlightcontroller.core.module.IFloodlightService;
 import net.floodlightcontroller.restserver.IRestApiService;
-import net.floodlightcontroller.util.MACAddress;
 import net.floodlightcontroller.util.OFMessageDamper;
+
+import net.onrc.onos.datagrid.IDatagridService;
 import net.onrc.onos.graph.GraphDBOperation;
 import net.onrc.onos.ofcontroller.core.INetMapStorage;
 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.floodlightlistener.INetworkGraphService;
 import net.onrc.onos.ofcontroller.flowmanager.web.FlowWebRoutable;
 import net.onrc.onos.ofcontroller.topology.ITopologyNetService;
-import net.onrc.onos.ofcontroller.topology.TopologyManager;
-import net.onrc.onos.ofcontroller.util.CallerId;
-import net.onrc.onos.ofcontroller.util.DataPath;
-import net.onrc.onos.ofcontroller.util.DataPathEndpoints;
-import net.onrc.onos.ofcontroller.util.Dpid;
-import net.onrc.onos.ofcontroller.util.FlowEntry;
-import net.onrc.onos.ofcontroller.util.FlowEntryAction;
-import net.onrc.onos.ofcontroller.util.FlowEntryAction.*;
-import net.onrc.onos.ofcontroller.util.FlowEntryActions;
-import net.onrc.onos.ofcontroller.util.FlowEntryId;
-import net.onrc.onos.ofcontroller.util.FlowEntryMatch;
-import net.onrc.onos.ofcontroller.util.FlowEntrySwitchState;
-import net.onrc.onos.ofcontroller.util.FlowEntryUserState;
-import net.onrc.onos.ofcontroller.util.FlowId;
-import net.onrc.onos.ofcontroller.util.FlowPath;
-import net.onrc.onos.ofcontroller.util.FlowPathFlags;
-import net.onrc.onos.ofcontroller.util.IPv4Net;
-import net.onrc.onos.ofcontroller.util.Port;
-import net.onrc.onos.ofcontroller.util.SwitchPort;
+import net.onrc.onos.ofcontroller.topology.Topology;
+import net.onrc.onos.ofcontroller.util.*;
 
-import org.openflow.protocol.OFFlowMod;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.OFPacketOut;
-import org.openflow.protocol.OFPort;
 import org.openflow.protocol.OFType;
-import org.openflow.protocol.action.*;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -69,11 +40,12 @@
  */
 public class FlowManager implements IFloodlightModule, IFlowService, INetMapStorage {
 
-    protected GraphDBOperation op;
+    protected GraphDBOperation dbHandler;
 
-    protected IRestApiService restApi;
     protected volatile IFloodlightProviderService floodlightProvider;
     protected volatile ITopologyNetService topologyNetService;
+    protected volatile IDatagridService datagridService;
+    protected IRestApiService restApi;
     protected FloodlightModuleContext context;
 
     protected OFMessageDamper messageDamper;
@@ -84,9 +56,6 @@
     //
     protected static final int OFMESSAGE_DAMPER_CAPACITY = 50000; // TODO: find sweet spot
     protected static final int OFMESSAGE_DAMPER_TIMEOUT = 250;	// ms
-    public static final short FLOWMOD_DEFAULT_IDLE_TIMEOUT = 0;	// infinity
-    public static final short FLOWMOD_DEFAULT_HARD_TIMEOUT = 0;	// infinite
-    public static final short PRIORITY_DEFAULT = 100;
 
     // Flow Entry ID generation state
     private static Random randomGenerator = new Random();
@@ -94,12 +63,6 @@
     private static int nextFlowEntryIdSuffix = 0;
     private static long nextFlowEntryId = 0;
 
-    // State for measurement purpose
-    private static long measurementFlowId = 100000;
-    private static String measurementFlowIdStr = "0x186a0";	// 100000
-    private long modifiedMeasurementFlowTime = 0;
-    //
-
     /** The logger. */
     private static Logger log = LoggerFactory.getLogger(FlowManager.class);
 
@@ -117,7 +80,7 @@
 		    runImpl();
 		} catch (Exception e) {
 		    log.debug("Exception processing All Flow Entries from the Network MAP: ", e);
-		    op.rollback();
+		    dbHandler.rollback();
 		    return;
 		}
 	    }
@@ -143,12 +106,12 @@
 		    new LinkedList<IFlowEntry>();
 
 		//
-		// Fetch all Flow Entries which need to be updated and select only my Flow Entries
-		// that need to be updated into the switches.
+		// Fetch all Flow Entries which need to be updated and select
+		// only my Flow Entries that need to be updated into the
+		// switches.
 		//
-		boolean processed_measurement_flow = false;
 		Iterable<IFlowEntry> allFlowEntries =
-		    op.getAllSwitchNotUpdatedFlowEntries();
+		    dbHandler.getAllSwitchNotUpdatedFlowEntries();
 		for (IFlowEntry flowEntryObj : allFlowEntries) {
 		    counterAllFlowEntries++;
 
@@ -161,7 +124,7 @@
 			continue;	// Ignore the entry: not my switch
 
 		    IFlowPath flowObj =
-			op.getFlowPathByFlowEntry(flowEntryObj);
+			dbHandler.getFlowPathByFlowEntry(flowEntryObj);
 		    if (flowObj == null)
 			continue;		// Should NOT happen
 		    if (flowObj.getFlowId() == null)
@@ -183,15 +146,6 @@
 			addFlowEntries.add(flowEntryObj);
 		    }
 		    counterMyNotUpdatedFlowEntries++;
-		    // Code for measurement purpose
-		    // TODO: Commented-out for now
-		    /*
-		    {
-			if (flowObj.getFlowId().equals(measurementFlowIdStr)) {
-			    processed_measurement_flow = true;
-			}
-		    }
-		    */
 		}
 
 		//
@@ -199,7 +153,7 @@
 		//
 		for (IFlowEntry flowEntryObj : addFlowEntries) {
 		    IFlowPath flowObj =
-			op.getFlowPathByFlowEntry(flowEntryObj);
+			dbHandler.getFlowPathByFlowEntry(flowEntryObj);
 		    if (flowObj == null)
 			continue;		// Should NOT happen
 		    if (flowObj.getFlowId() == null)
@@ -223,24 +177,16 @@
 		while (! deleteFlowEntries.isEmpty()) {
 		    IFlowEntry flowEntryObj = deleteFlowEntries.poll();
 		    IFlowPath flowObj =
-			op.getFlowPathByFlowEntry(flowEntryObj);
+			dbHandler.getFlowPathByFlowEntry(flowEntryObj);
 		    if (flowObj == null) {
 			log.debug("Did not find FlowPath to be deleted");
 			continue;
 		    }
 		    flowObj.removeFlowEntry(flowEntryObj);
-		    op.removeFlowEntry(flowEntryObj);
+		    dbHandler.removeFlowEntry(flowEntryObj);
 		}
 
-		op.commit();
-
-		if (processed_measurement_flow) {
-		    long estimatedTime =
-			System.nanoTime() - modifiedMeasurementFlowTime;
-		    String logMsg = "MEASUREMENT: Pushed Flow delay: " +
-			(double)estimatedTime / 1000000000 + " sec";
-		    log.debug(logMsg);
-		}
+		dbHandler.commit();
 
 		long estimatedTime = System.nanoTime() - startTime;
 		double rate = 0.0;
@@ -265,7 +211,7 @@
 		    runImpl();
 		} catch (Exception e) {
 		    log.debug("Exception processing All Flows from the Network MAP: ", e);
-		    op.rollback();
+		    dbHandler.rollback();
 		    return;
 		}
 	    }
@@ -287,15 +233,12 @@
 		}
 		LinkedList<IFlowPath> deleteFlows = new LinkedList<IFlowPath>();
 
-		boolean processed_measurement_flow = false;
-
 		//
 		// Fetch and recompute the Shortest Path for those
 		// Flow Paths this controller is responsible for.
 		//
-		Map<Long, ?> shortestPathTopo =
-		    topologyNetService.prepareShortestPathTopo();
-		Iterable<IFlowPath> allFlowPaths = op.getAllFlowPaths();
+		Topology topology = topologyNetService.newDatabaseTopology();
+		Iterable<IFlowPath> allFlowPaths = dbHandler.getAllFlowPaths();
 		for (IFlowPath flowPathObj : allFlowPaths) {
 		    counterAllFlowPaths++;
 		    if (flowPathObj == null)
@@ -359,18 +302,19 @@
 		    counterMyFlowPaths++;
 
 		    //
-		    // NOTE: Using here the regular getShortestPath() method
-		    // won't work here, because that method calls internally
-		    //  "conn.endTx(Transaction.COMMIT)", and that will
-		    // invalidate all handlers to the Titan database.
+		    // NOTE: Using here the regular getDatabaseShortestPath()
+		    // method won't work here, because that method calls
+		    // internally "conn.endTx(Transaction.COMMIT)", and that
+		    // will invalidate all handlers to the Titan database.
 		    // If we want to experiment with calling here
-		    // getShortestPath(), we need to refactor that code
+		    // getDatabaseShortestPath(), we need to refactor that code
 		    // to avoid closing the transaction.
 		    //
 		    DataPath dataPath =
-			topologyNetService.getTopoShortestPath(shortestPathTopo,
-							       srcSwitchPort,
-							       dstSwitchPort);
+			topologyNetService.getTopologyShortestPath(
+				topology,
+				srcSwitchPort,
+				dstSwitchPort);
 		    if (dataPath == null) {
 			// We need the DataPath to compare the paths
 			dataPath = new DataPath();
@@ -392,20 +336,12 @@
 		//
 		while (! deleteFlows.isEmpty()) {
 		    IFlowPath flowPathObj = deleteFlows.poll();
-		    op.removeFlowPath(flowPathObj);
+		    dbHandler.removeFlowPath(flowPathObj);
 		}
 
-		topologyNetService.dropShortestPathTopo(shortestPathTopo);
+		topologyNetService.dropTopology(topology);
 
-		op.commit();
-
-		if (processed_measurement_flow) {
-		    long estimatedTime =
-			System.nanoTime() - modifiedMeasurementFlowTime;
-		    String logMsg = "MEASUREMENT: Pushed Flow delay: " +
-			(double)estimatedTime / 1000000000 + " sec";
-		    log.debug(logMsg);
-		}
+		dbHandler.commit();
 
 		long estimatedTime = System.nanoTime() - startTime;
 		double rate = 0.0;
@@ -428,8 +364,7 @@
      */
     @Override
     public void init(String conf) {
-    	op = new GraphDBOperation(conf);
-	topologyNetService = new TopologyManager(conf);
+    	dbHandler = new GraphDBOperation(conf);
     }
 
     /**
@@ -444,7 +379,7 @@
      */
     @Override
     public void close() {
-    	op.close();
+    	dbHandler.close();
     }
 
     /**
@@ -469,9 +404,9 @@
     public Map<Class<? extends IFloodlightService>, IFloodlightService> 
 			       getServiceImpls() {
         Map<Class<? extends IFloodlightService>,
-        IFloodlightService> m = 
-            new HashMap<Class<? extends IFloodlightService>,
-                IFloodlightService>();
+	    IFloodlightService> m =
+	    new HashMap<Class<? extends IFloodlightService>,
+	    IFloodlightService>();
         m.put(IFlowService.class, this);
         return m;
     }
@@ -483,10 +418,12 @@
      */
     @Override
     public Collection<Class<? extends IFloodlightService>> 
-                                                    getModuleDependencies() {
+				      getModuleDependencies() {
 	Collection<Class<? extends IFloodlightService>> l =
 	    new ArrayList<Class<? extends IFloodlightService>>();
 	l.add(IFloodlightProviderService.class);
+	l.add(INetworkGraphService.class);
+	l.add(IDatagridService.class);
 	l.add(IRestApiService.class);
         return l;
     }
@@ -501,15 +438,16 @@
 	throws FloodlightModuleException {
 	this.context = context;
 	floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
+	topologyNetService = context.getServiceImpl(ITopologyNetService.class);
+	datagridService = context.getServiceImpl(IDatagridService.class);
 	restApi = context.getServiceImpl(IRestApiService.class);
+
 	messageDamper = new OFMessageDamper(OFMESSAGE_DAMPER_CAPACITY,
 					    EnumSet.of(OFType.FLOW_MOD),
 					    OFMESSAGE_DAMPER_TIMEOUT);
 
-	// TODO: An ugly hack!
-	String conf = "/tmp/cassandra.titan";
-	this.init(conf);
-	
+	this.init("");
+
 	mapReaderScheduler = Executors.newScheduledThreadPool(1);
 	shortestPathReconcileScheduler = Executors.newScheduledThreadPool(1);
     }
@@ -519,7 +457,7 @@
      *
      * @return the next Flow Entry ID to use.
      */
-    private synchronized long getNextFlowEntryId() {
+    public synchronized long getNextFlowEntryId() {
 	//
 	// Generate the next Flow Entry ID.
 	// NOTE: For now, the higher 32 bits are random, and
@@ -545,10 +483,10 @@
     @Override
     public void startUp(FloodlightModuleContext context) {
 	restApi.addRestletRoutable(new FlowWebRoutable());
-	
+
 	// Initialize the Flow Entry ID generator
 	nextFlowEntryIdPrefix = randomGenerator.nextInt();
-		
+
 	mapReaderScheduler.scheduleAtFixedRate(
 			mapReader, 3, 3, TimeUnit.SECONDS);
 	shortestPathReconcileScheduler.scheduleAtFixedRate(
@@ -558,9 +496,6 @@
     /**
      * Add a flow.
      *
-     * Internally, ONOS will automatically register the installer for
-     * receiving Flow Path Notifications for that path.
-     *
      * @param flowPath the Flow Path to install.
      * @param flowId the return-by-reference Flow ID as assigned internally.
      * @param dataPathSummaryStr the data path summary string if the added
@@ -570,147 +505,8 @@
     @Override
     public boolean addFlow(FlowPath flowPath, FlowId flowId,
 			   String dataPathSummaryStr) {
-	/*
-	 * TODO: Commented-out for now
-	if (flowPath.flowId().value() == measurementFlowId) {
-	    modifiedMeasurementFlowTime = System.nanoTime();
-	}
-	*/
-
-	IFlowPath flowObj = null;
-	boolean found = false;
-	try {
-	    if ((flowObj = op.searchFlowPath(flowPath.flowId()))
-		!= null) {
-		log.debug("Adding FlowPath with FlowId {}: found existing FlowPath",
-			  flowPath.flowId().toString());
-		found = true;
-	    } else {
-		flowObj = op.newFlowPath();
-		log.debug("Adding FlowPath with FlowId {}: creating new FlowPath",
-			  flowPath.flowId().toString());
-	    }
-	} catch (Exception e) {
-	    // TODO: handle exceptions
-	    op.rollback();
-
-	    StringWriter sw = new StringWriter();
-	    e.printStackTrace(new PrintWriter(sw));
-	    String stacktrace = sw.toString();
-
-	    log.error(":addFlow FlowId:{} failed: {}",
-		      flowPath.flowId().toString(),
-		      stacktrace);
-	}
-	if (flowObj == null) {
-	    log.error(":addFlow FlowId:{} failed: Flow object not created",
-		      flowPath.flowId().toString());
-	    op.rollback();
-	    return false;
-	}
-
-	//
-	// Set the Flow key:
-	// - flowId
-	//
-	flowObj.setFlowId(flowPath.flowId().toString());
-	flowObj.setType("flow");
-
-	//
-	// Set the Flow attributes:
-	// - flowPath.installerId()
-	// - flowPath.flowPathFlags()
-	// - flowPath.dataPath().srcPort()
-	// - flowPath.dataPath().dstPort()
-	// - flowPath.matchSrcMac()
-	// - flowPath.matchDstMac()
-	// - flowPath.matchEthernetFrameType()
-	// - flowPath.matchVlanId()
-	// - flowPath.matchVlanPriority()
-	// - flowPath.matchSrcIPv4Net()
-	// - flowPath.matchDstIPv4Net()
-	// - flowPath.matchIpProto()
-	// - flowPath.matchIpToS()
-	// - flowPath.matchSrcTcpUdpPort()
-	// - flowPath.matchDstTcpUdpPort()
-	// - flowPath.flowEntryActions()
-	//
-	flowObj.setInstallerId(flowPath.installerId().toString());
-	flowObj.setFlowPathFlags(flowPath.flowPathFlags().flags());
-	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());
-	if (flowPath.flowEntryMatch().matchSrcMac()) {
-	    flowObj.setMatchSrcMac(flowPath.flowEntryMatch().srcMac().toString());
-	}
-	if (flowPath.flowEntryMatch().matchDstMac()) {
-	    flowObj.setMatchDstMac(flowPath.flowEntryMatch().dstMac().toString());
-	}
-	if (flowPath.flowEntryMatch().matchEthernetFrameType()) {
-	    flowObj.setMatchEthernetFrameType(flowPath.flowEntryMatch().ethernetFrameType());
-	}
-	if (flowPath.flowEntryMatch().matchVlanId()) {
-	    flowObj.setMatchVlanId(flowPath.flowEntryMatch().vlanId());
-	}
-	if (flowPath.flowEntryMatch().matchVlanPriority()) {
-	    flowObj.setMatchVlanPriority(flowPath.flowEntryMatch().vlanPriority());
-	}
-	if (flowPath.flowEntryMatch().matchSrcIPv4Net()) {
-	    flowObj.setMatchSrcIPv4Net(flowPath.flowEntryMatch().srcIPv4Net().toString());
-	}
-	if (flowPath.flowEntryMatch().matchDstIPv4Net()) {
-	    flowObj.setMatchDstIPv4Net(flowPath.flowEntryMatch().dstIPv4Net().toString());
-	}
-	if (flowPath.flowEntryMatch().matchIpProto()) {
-	    flowObj.setMatchIpProto(flowPath.flowEntryMatch().ipProto());
-	}
-	if (flowPath.flowEntryMatch().matchIpToS()) {
-	    flowObj.setMatchIpToS(flowPath.flowEntryMatch().ipToS());
-	}
-	if (flowPath.flowEntryMatch().matchSrcTcpUdpPort()) {
-	    flowObj.setMatchSrcTcpUdpPort(flowPath.flowEntryMatch().srcTcpUdpPort());
-	}
-	if (flowPath.flowEntryMatch().matchDstTcpUdpPort()) {
-	    flowObj.setMatchDstTcpUdpPort(flowPath.flowEntryMatch().dstTcpUdpPort());
-	}
-	if (! flowPath.flowEntryActions().actions().isEmpty()) {
-	    flowObj.setActions(flowPath.flowEntryActions().toString());
-	}
-
-	if (dataPathSummaryStr != null) {
-	    flowObj.setDataPathSummary(dataPathSummaryStr);
-	} else {
-	    flowObj.setDataPathSummary("");
-	}
-
-	if (found)
-	    flowObj.setUserState("FE_USER_MODIFY");
-	else
-	    flowObj.setUserState("FE_USER_ADD");
-
-	// Flow edges:
-	//   HeadFE
-
-
-	//
-	// Flow Entries:
-	// flowPath.dataPath().flowEntries()
-	//
-	for (FlowEntry flowEntry : flowPath.dataPath().flowEntries()) {
-	    if (addFlowEntry(flowObj, flowEntry) == null) {
-		op.rollback();
-		return false;
-	    }
-	}
-	op.commit();
-
-	//
-	// TODO: We need a proper Flow ID allocation mechanism.
-	//
-	flowId.setValue(flowPath.flowId().value());
-
-	return true;
+	return FlowDatabaseOperation.addFlow(this, dbHandler, flowPath, flowId,
+					     dataPathSummaryStr);
     }
 
     /**
@@ -721,150 +517,8 @@
      * @return the added Flow Entry object on success, otherwise null.
      */
     private IFlowEntry addFlowEntry(IFlowPath flowObj, FlowEntry flowEntry) {
-	// Flow edges
-	//   HeadFE (TODO)
-
-	//
-	// Assign the FlowEntry ID.
-	//
-	if ((flowEntry.flowEntryId() == null) ||
-	    (flowEntry.flowEntryId().value() == 0)) {
-	    long id = getNextFlowEntryId();
-	    flowEntry.setFlowEntryId(new FlowEntryId(id));
-	}
-
-	IFlowEntry flowEntryObj = null;
-	boolean found = false;
-	try {
-	    if ((flowEntryObj =
-		 op.searchFlowEntry(flowEntry.flowEntryId())) != null) {
-		log.debug("Adding FlowEntry with FlowEntryId {}: found existing FlowEntry",
-			  flowEntry.flowEntryId().toString());
-		found = true;
-	    } else {
-		flowEntryObj = op.newFlowEntry();
-		log.debug("Adding FlowEntry with FlowEntryId {}: creating new FlowEntry",
-			  flowEntry.flowEntryId().toString());
-	    }
-	} catch (Exception e) {
-	    log.error(":addFlow FlowEntryId:{} failed",
-		      flowEntry.flowEntryId().toString());
-	    return null;
-	}
-	if (flowEntryObj == null) {
-	    log.error(":addFlow FlowEntryId:{} failed: FlowEntry object not created",
-		      flowEntry.flowEntryId().toString());
-	    return null;
-	}
-
-	//
-	// Set the Flow Entry key:
-	// - flowEntry.flowEntryId()
-	//
-	flowEntryObj.setFlowEntryId(flowEntry.flowEntryId().toString());
-	flowEntryObj.setType("flow_entry");
-
-	// 
-	// Set the Flow Entry Edges and attributes:
-	// - Switch edge
-	// - InPort edge
-	// - OutPort edge
-	//
-	// - flowEntry.dpid()
-	// - flowEntry.flowEntryUserState()
-	// - flowEntry.flowEntrySwitchState()
-	// - flowEntry.flowEntryErrorState()
-	// - flowEntry.matchInPort()
-	// - flowEntry.matchSrcMac()
-	// - flowEntry.matchDstMac()
-	// - flowEntry.matchEthernetFrameType()
-	// - flowEntry.matchVlanId()
-	// - flowEntry.matchVlanPriority()
-	// - flowEntry.matchSrcIPv4Net()
-	// - flowEntry.matchDstIPv4Net()
-	// - flowEntry.matchIpProto()
-	// - flowEntry.matchIpToS()
-	// - flowEntry.matchSrcTcpUdpPort()
-	// - flowEntry.matchDstTcpUdpPort()
-	// - flowEntry.actionOutputPort()
-	// - flowEntry.actions()
-	//
-	ISwitchObject sw = op.searchSwitch(flowEntry.dpid().toString());
-	flowEntryObj.setSwitchDpid(flowEntry.dpid().toString());
-	flowEntryObj.setSwitch(sw);
-	if (flowEntry.flowEntryMatch().matchInPort()) {
-	    IPortObject inport =
-		op.searchPort(flowEntry.dpid().toString(),
-					flowEntry.flowEntryMatch().inPort().value());
-	    flowEntryObj.setMatchInPort(flowEntry.flowEntryMatch().inPort().value());
-	    flowEntryObj.setInPort(inport);
-	}
-	if (flowEntry.flowEntryMatch().matchSrcMac()) {
-	    flowEntryObj.setMatchSrcMac(flowEntry.flowEntryMatch().srcMac().toString());
-	}
-	if (flowEntry.flowEntryMatch().matchDstMac()) {
-	    flowEntryObj.setMatchDstMac(flowEntry.flowEntryMatch().dstMac().toString());
-	}
-	if (flowEntry.flowEntryMatch().matchEthernetFrameType()) {
-	    flowEntryObj.setMatchEthernetFrameType(flowEntry.flowEntryMatch().ethernetFrameType());
-	}
-	if (flowEntry.flowEntryMatch().matchVlanId()) {
-	    flowEntryObj.setMatchVlanId(flowEntry.flowEntryMatch().vlanId());
-	}
-	if (flowEntry.flowEntryMatch().matchVlanPriority()) {
-	    flowEntryObj.setMatchVlanPriority(flowEntry.flowEntryMatch().vlanPriority());
-	}
-	if (flowEntry.flowEntryMatch().matchSrcIPv4Net()) {
-	    flowEntryObj.setMatchSrcIPv4Net(flowEntry.flowEntryMatch().srcIPv4Net().toString());
-	}
-	if (flowEntry.flowEntryMatch().matchDstIPv4Net()) {
-	    flowEntryObj.setMatchDstIPv4Net(flowEntry.flowEntryMatch().dstIPv4Net().toString());
-	}
-	if (flowEntry.flowEntryMatch().matchIpProto()) {
-	    flowEntryObj.setMatchIpProto(flowEntry.flowEntryMatch().ipProto());
-	}
-	if (flowEntry.flowEntryMatch().matchIpToS()) {
-	    flowEntryObj.setMatchIpToS(flowEntry.flowEntryMatch().ipToS());
-	}
-	if (flowEntry.flowEntryMatch().matchSrcTcpUdpPort()) {
-	    flowEntryObj.setMatchSrcTcpUdpPort(flowEntry.flowEntryMatch().srcTcpUdpPort());
-	}
-	if (flowEntry.flowEntryMatch().matchDstTcpUdpPort()) {
-	    flowEntryObj.setMatchDstTcpUdpPort(flowEntry.flowEntryMatch().dstTcpUdpPort());
-	}
-
-	for (FlowEntryAction fa : flowEntry.flowEntryActions().actions()) {
-	    if (fa.actionOutput() != null) {
-		IPortObject outport =
-		    op.searchPort(flowEntry.dpid().toString(),
-					      fa.actionOutput().port().value());
-		flowEntryObj.setActionOutputPort(fa.actionOutput().port().value());
-		flowEntryObj.setOutPort(outport);
-	    }
-	}
-	if (! flowEntry.flowEntryActions().isEmpty()) {
-	    flowEntryObj.setActions(flowEntry.flowEntryActions().toString());
-	}
-
-	// TODO: Hacks with hard-coded state names!
-	if (found)
-	    flowEntryObj.setUserState("FE_USER_MODIFY");
-	else
-	    flowEntryObj.setUserState("FE_USER_ADD");
-	flowEntryObj.setSwitchState("FE_SWITCH_NOT_UPDATED");
-	//
-	// TODO: Take care of the FlowEntryErrorState.
-	//
-
-	// Flow Entries edges:
-	//   Flow
-	//   NextFE (TODO)
-	if (! found) {
-	    flowObj.addFlowEntry(flowEntryObj);
-	    flowEntryObj.setFlow(flowObj);
-	}
-
-	return flowEntryObj;
+	return FlowDatabaseOperation.addFlowEntry(this, dbHandler, flowObj,
+						  flowEntry);
     }
 
     /**
@@ -874,64 +528,7 @@
      */
     @Override
     public boolean deleteAllFlows() {
-	final ConcurrentLinkedQueue<FlowId> concurrentAllFlowIds =
-	    new ConcurrentLinkedQueue<FlowId>();
-
-	// Get all Flow IDs
-	Iterable<IFlowPath> allFlowPaths = op.getAllFlowPaths();
-	for (IFlowPath flowPathObj : allFlowPaths) {
-	    if (flowPathObj == null)
-		continue;
-	    String flowIdStr = flowPathObj.getFlowId();
-	    if (flowIdStr == null)
-		continue;
-	    FlowId flowId = new FlowId(flowIdStr);
-	    concurrentAllFlowIds.add(flowId);
-	}
-
-	// Delete all flows one-by-one
-	for (FlowId flowId : concurrentAllFlowIds)
-	    deleteFlow(flowId);
-
-	/*
-	 * TODO: A faster mechanism to delete the Flow Paths by using
-	 * a number of threads. Commented-out for now.
-	 */
-	/*
-	//
-	// Create the threads to delete the Flow Paths
-	//
-	List<Thread> threads = new LinkedList<Thread>();
-	for (int i = 0; i < 10; i++) {
-	    Thread thread = new Thread(new Runnable() {
-		@Override
-		public void run() {
-		    while (true) {
-			FlowId flowId = concurrentAllFlowIds.poll();
-			if (flowId == null)
-			    return;
-			deleteFlow(flowId);
-		    }
-		}}, "Delete All Flow Paths");
-	    threads.add(thread);
-	}
-
-	// Start processing
-	for (Thread thread : threads) {
-	    thread.start();
-	}
-
-	// Wait for all threads to complete
-	for (Thread thread : threads) {
-	    try {
-		thread.join();
-	    } catch (InterruptedException e) {
-		log.debug("Exception waiting for a thread to delete a Flow Path: ", e);
-	    }
-	}
-	*/
-
-	return true;
+	return FlowDatabaseOperation.deleteAllFlows(dbHandler);
     }
 
     /**
@@ -942,58 +539,7 @@
      */
     @Override
     public boolean deleteFlow(FlowId flowId) {
-	/*
-	 * TODO: Commented-out for now
-	if (flowId.value() == measurementFlowId) {
-	    modifiedMeasurementFlowTime = System.nanoTime();
-	}
-	*/
-
-	IFlowPath flowObj = null;
-	//
-	// We just mark the entries for deletion,
-	// and let the switches remove each individual entry after
-	// it has been removed from the switches.
-	//
-	try {
-	    if ((flowObj = op.searchFlowPath(flowId))
-		!= null) {
-		log.debug("Deleting FlowPath with FlowId {}: found existing FlowPath",
-			  flowId.toString());
-	    } else {
-		log.debug("Deleting FlowPath with FlowId {}:  FlowPath not found",
-			  flowId.toString());
-	    }
-	} catch (Exception e) {
-	    // TODO: handle exceptions
-	    op.rollback();
-	    log.error(":deleteFlow FlowId:{} failed", flowId.toString());
-	}
-	if (flowObj == null) {
-	    op.commit();
-	    return true;		// OK: No such flow
-	}
-
-	//
-	// Find and mark for deletion all Flow Entries,
-	// and the Flow itself.
-	//
-	flowObj.setUserState("FE_USER_DELETE");
-	Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
-	boolean empty = true;	// TODO: an ugly hack
-	for (IFlowEntry flowEntryObj : flowEntries) {
-	    empty = false;
-	    // flowObj.removeFlowEntry(flowEntryObj);
-	    // conn.utils().removeFlowEntry(conn, flowEntryObj);
-	    flowEntryObj.setUserState("FE_USER_DELETE");
-	    flowEntryObj.setSwitchState("FE_SWITCH_NOT_UPDATED");
-	}
-	// Remove from the database empty flows
-	if (empty)
-	    op.removeFlowPath(flowObj);
-	op.commit();
-
-	return true;
+	return FlowDatabaseOperation.deleteFlow(dbHandler, flowId);
     }
 
     /**
@@ -1003,26 +549,7 @@
      */
     @Override
     public boolean clearAllFlows() {
-	List<FlowId> allFlowIds = new LinkedList<FlowId>();
-
-	// Get all Flow IDs
-	Iterable<IFlowPath> allFlowPaths = op.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);
-	}
-
-	// Clear all flows one-by-one
-	for (FlowId flowId : allFlowIds) {
-	    clearFlow(flowId);
-	}
-
-	return true;
+	return FlowDatabaseOperation.clearAllFlows(dbHandler);
     }
 
     /**
@@ -1033,39 +560,7 @@
      */
     @Override
     public boolean clearFlow(FlowId flowId) {
-	IFlowPath flowObj = null;
-	try {
-	    if ((flowObj = op.searchFlowPath(flowId))
-		!= null) {
-		log.debug("Clearing FlowPath with FlowId {}: found existing FlowPath",
-			  flowId.toString());
-	    } else {
-		log.debug("Clearing FlowPath with FlowId {}:  FlowPath not found",
-			  flowId.toString());
-	    }
-	} catch (Exception e) {
-	    // TODO: handle exceptions
-	    op.rollback();
-	    log.error(":clearFlow FlowId:{} failed", flowId.toString());
-	}
-	if (flowObj == null) {
-	    op.commit();
-	    return true;		// OK: No such flow
-	}
-
-	//
-	// Remove all Flow Entries
-	//
-	Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
-	for (IFlowEntry flowEntryObj : flowEntries) {
-	    flowObj.removeFlowEntry(flowEntryObj);
-	    op.removeFlowEntry(flowEntryObj);
-	}
-	// Remove the Flow itself
-	op.removeFlowPath(flowObj);
-	op.commit();
-
-	return true;
+	return FlowDatabaseOperation.clearFlow(dbHandler, flowId);
     }
 
     /**
@@ -1076,33 +571,17 @@
      */
     @Override
     public FlowPath getFlow(FlowId flowId) {
-	IFlowPath flowObj = null;
-	try {
-	    if ((flowObj = op.searchFlowPath(flowId))
-		!= null) {
-		log.debug("Get FlowPath with FlowId {}: found existing FlowPath",
-			  flowId.toString());
-	    } else {
-		log.debug("Get FlowPath with FlowId {}:  FlowPath not found",
-			  flowId.toString());
-	    }
-	} catch (Exception e) {
-	    // TODO: handle exceptions
-	    op.rollback();
-	    log.error(":getFlow FlowId:{} failed", flowId.toString());
-	}
-	if (flowObj == null) {
-	    op.commit();
-	    return null;		// Flow not found
-	}
+	return FlowDatabaseOperation.getFlow(dbHandler, flowId);
+    }
 
-	//
-	// Extract the Flow state
-	//
-	FlowPath flowPath = extractFlowPath(flowObj);
-	op.commit();
-
-	return flowPath;
+    /**
+     * Get all installed flows by all installers.
+     *
+     * @return the Flow Paths if found, otherwise null.
+     */
+    @Override
+    public ArrayList<FlowPath> getAllFlows() {
+	return FlowDatabaseOperation.getAllFlows(dbHandler);
     }
 
     /**
@@ -1116,45 +595,8 @@
     @Override
     public ArrayList<FlowPath> getAllFlows(CallerId installerId,
 					   DataPathEndpoints dataPathEndpoints) {
-	//
-	// TODO: The implementation below is not optimal:
-	// We fetch all flows, and then return only the subset that match
-	// the query conditions.
-	// We should use the appropriate Titan/Gremlin query to filter-out
-	// the flows as appropriate.
-	//
-	ArrayList<FlowPath> allFlows = getAllFlows();
-	ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
-
-	if (allFlows == null) {
-	    log.debug("Get FlowPaths for installerId{} and dataPathEndpoints{}: no FlowPaths found", installerId, dataPathEndpoints);
-	    return flowPaths;
-	}
-
-	for (FlowPath flow : allFlows) {
-	    //
-	    // TODO: String-based comparison is sub-optimal.
-	    // We are using it for now to save us the extra work of
-	    // implementing the "equals()" and "hashCode()" methods.
-	    //
-	    if (! flow.installerId().toString().equals(installerId.toString()))
-		continue;
-	    if (! flow.dataPath().srcPort().toString().equals(dataPathEndpoints.srcPort().toString())) {
-		continue;
-	    }
-	    if (! flow.dataPath().dstPort().toString().equals(dataPathEndpoints.dstPort().toString())) {
-		continue;
-	    }
-	    flowPaths.add(flow);
-	}
-
-	if (flowPaths.isEmpty()) {
-	    log.debug("Get FlowPaths for installerId{} and dataPathEndpoints{}: no FlowPaths found", installerId, dataPathEndpoints);
-	} else {
-	    log.debug("Get FlowPaths for installerId{} and dataPathEndpoints{}: FlowPaths are found", installerId, dataPathEndpoints);
-	}
-
-	return flowPaths;
+	return FlowDatabaseOperation.getAllFlows(dbHandler, installerId,
+						 dataPathEndpoints);
     }
 
     /**
@@ -1165,43 +607,7 @@
      */
     @Override
     public ArrayList<FlowPath> getAllFlows(DataPathEndpoints dataPathEndpoints) {
-	//
-	// TODO: The implementation below is not optimal:
-	// We fetch all flows, and then return only the subset that match
-	// the query conditions.
-	// We should use the appropriate Titan/Gremlin query to filter-out
-	// the flows as appropriate.
-	//
-    ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
-    ArrayList<FlowPath> allFlows = getAllFlows();
-
-	if (allFlows == null) {
-	    log.debug("Get FlowPaths for dataPathEndpoints{}: no FlowPaths found", dataPathEndpoints);
-	    return flowPaths;
-	}
-
-	for (FlowPath flow : allFlows) {
-	    //
-	    // TODO: String-based comparison is sub-optimal.
-	    // We are using it for now to save us the extra work of
-	    // implementing the "equals()" and "hashCode()" methods.
-	    //
-	    if (! flow.dataPath().srcPort().toString().equals(dataPathEndpoints.srcPort().toString())) {
-		continue;
-	    }
-	    if (! flow.dataPath().dstPort().toString().equals(dataPathEndpoints.dstPort().toString())) {
-		continue;
-	    }
-	    flowPaths.add(flow);
-	}
-
-	if (flowPaths.isEmpty()) {
-	    log.debug("Get FlowPaths for dataPathEndpoints{}: no FlowPaths found", dataPathEndpoints);
-	} else {
-	    log.debug("Get FlowPaths for dataPathEndpoints{}: FlowPaths are found", dataPathEndpoints);
-	}
-
-	return flowPaths;
+	return FlowDatabaseOperation.getAllFlows(dbHandler, dataPathEndpoints);
     }
 
     /**
@@ -1212,344 +618,19 @@
      * @return the Flow Paths if found, otherwise null.
      */
     @Override
-    public ArrayList<IFlowPath> getAllFlowsSummary(FlowId flowId, int maxFlows) {
-
-	//
-	// TODO: The implementation below is not optimal:
-	// We fetch all flows, and then return only the subset that match
-	// the query conditions.
-	// We should use the appropriate Titan/Gremlin query to filter-out
-	// the flows as appropriate.
-	//
-    	//ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
-    	
-    	ArrayList<IFlowPath> flowPathsWithoutFlowEntries = getAllFlowsWithoutFlowEntries();
-    	
-    	Collections.sort(flowPathsWithoutFlowEntries, 
-    			new Comparator<IFlowPath>(){
-					@Override
-					public int compare(IFlowPath first, IFlowPath second) {
-						// TODO Auto-generated method stub
-						long result = new FlowId(first.getFlowId()).value()
-								- new FlowId(second.getFlowId()).value();
-						if (result > 0) return 1;
-						else if (result < 0) return -1;
-						else return 0;
-					}
-    			}
-    	);
-    	
-    	return flowPathsWithoutFlowEntries;
-    	
-    	/*
-    	ArrayList<FlowPath> allFlows = getAllFlows();
-
-		if (allFlows == null) {
-		    log.debug("Get FlowPathsSummary for {} {}: no FlowPaths found", flowId, maxFlows);
-		    return flowPaths;
-		}
-	
-		Collections.sort(allFlows);
-		
-		for (FlowPath flow : allFlows) {
-		    flow.setFlowEntryMatch(null);
-			
-		    // start from desired flowId
-		    if (flow.flowId().value() < flowId.value()) {
-			continue;
-		    }
-			
-			// Summarize by making null flow entry fields that are not relevant to report
-			for (FlowEntry flowEntry : flow.dataPath().flowEntries()) {
-				flowEntry.setFlowEntryActions(null);
-				flowEntry.setFlowEntryMatch(null);
-			}
-			
-		    flowPaths.add(flow);
-		    if (maxFlows != 0 && flowPaths.size() >= maxFlows) {
-		    	break;
-		    }
-		}
-	
-		if (flowPaths.isEmpty()) {
-		    log.debug("Get FlowPathsSummary {} {}: no FlowPaths found", flowId, maxFlows);
-		} else {
-		    log.debug("Get FlowPathsSummary for {} {}: FlowPaths were found", flowId, maxFlows);
-		}
-	
-		return flowPaths;
-		*/
+    public ArrayList<IFlowPath> getAllFlowsSummary(FlowId flowId,
+						   int maxFlows) {
+	return FlowDatabaseOperation.getAllFlowsSummary(dbHandler, flowId,
+							maxFlows);
     }
     
     /**
-     * Get all installed flows by all installers.
-     *
-     * @return the Flow Paths if found, otherwise null.
-     */
-    @Override
-    public ArrayList<FlowPath> getAllFlows() {
-	Iterable<IFlowPath> flowPathsObj = null;
-	ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
-
-	try {
-	    if ((flowPathsObj = op.getAllFlowPaths()) != null) {
-		log.debug("Get all FlowPaths: found FlowPaths");
-	    } else {
-		log.debug("Get all FlowPaths: no FlowPaths found");
-	    }
-	} catch (Exception e) {
-	    // TODO: handle exceptions
-	    op.rollback();
-	    log.error(":getAllFlowPaths failed");
-	}
-	if ((flowPathsObj == null) || (flowPathsObj.iterator().hasNext() == false)) {
-	    op.commit();
-	    return flowPaths;	// No Flows found
-	}
-
-	for (IFlowPath flowObj : flowPathsObj) {
-	    //
-	    // Extract the Flow state
-	    //
-	    FlowPath flowPath = extractFlowPath(flowObj);
-	    if (flowPath != null)
-		flowPaths.add(flowPath);
-	}
-
-	op.commit();
-
-	return flowPaths;
-    }
-
-    /**
      * Get all Flows information, without the associated Flow Entries.
      *
      * @return all Flows information, without the associated Flow Entries.
      */
     public ArrayList<IFlowPath> getAllFlowsWithoutFlowEntries() {
-    	Iterable<IFlowPath> flowPathsObj = null;
-    	ArrayList<IFlowPath> flowPathsObjArray = new ArrayList<IFlowPath>();
-
-    	op.commit();
-    	
-    	try {
-    	    if ((flowPathsObj = op.getAllFlowPaths()) != null) {
-    		log.debug("Get all FlowPaths: found FlowPaths");
-    	    } else {
-    		log.debug("Get all FlowPaths: no FlowPaths found");
-    	    }
-    	} catch (Exception e) {
-    	    // TODO: handle exceptions
-    	    op.rollback();
-    	    log.error(":getAllFlowPaths failed");
-    	}
-    	if ((flowPathsObj == null) || (flowPathsObj.iterator().hasNext() == false)) {
-    	    return new ArrayList<IFlowPath>();	// No Flows found
-    	}
-    	
-    	for (IFlowPath flowObj : flowPathsObj){
-    		flowPathsObjArray.add(flowObj);
-    	}
-    	/*
-    	ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
-    	for (IFlowPath flowObj : flowPathsObj) {
-    	    //
-    	    // Extract the Flow state
-    	    //
-    	    FlowPath flowPath = extractFlowPath(flowObj);
-    	    if (flowPath != null)
-    		flowPaths.add(flowPath);
-    	}
-    	*/
-
-    	//conn.endTx(Transaction.COMMIT);
-
-    	return flowPathsObjArray;
-    }
-
-    /**
-     * Extract Flow Path State from a Titan Database Object @ref IFlowPath.
-     *
-     * @param flowObj the object to extract the Flow Path State from.
-     * @return the extracted Flow Path State.
-     */
-    private FlowPath extractFlowPath(IFlowPath flowObj) {
-	//
-	// Extract the Flow state
-	//
-	String flowIdStr = flowObj.getFlowId();
-	String installerIdStr = flowObj.getInstallerId();
-	Long flowPathFlags = flowObj.getFlowPathFlags();
-	String srcSwitchStr = flowObj.getSrcSwitch();
-	Short srcPortShort = flowObj.getSrcPort();
-	String dstSwitchStr = flowObj.getDstSwitch();
-	Short dstPortShort = flowObj.getDstPort();
-
-	if ((flowIdStr == null) ||
-	    (installerIdStr == null) ||
-	    (flowPathFlags == null) ||
-	    (srcSwitchStr == null) ||
-	    (srcPortShort == null) ||
-	    (dstSwitchStr == null) ||
-	    (dstPortShort == null)) {
-	    // TODO: A work-around, becauuse of some bogus database objects
-	    return null;
-	}
-
-	FlowPath flowPath = new FlowPath();
-	flowPath.setFlowId(new FlowId(flowIdStr));
-	flowPath.setInstallerId(new CallerId(installerIdStr));
-	flowPath.setFlowPathFlags(new FlowPathFlags(flowPathFlags));
-	flowPath.dataPath().srcPort().setDpid(new Dpid(srcSwitchStr));
-	flowPath.dataPath().srcPort().setPort(new Port(srcPortShort));
-	flowPath.dataPath().dstPort().setDpid(new Dpid(dstSwitchStr));
-	flowPath.dataPath().dstPort().setPort(new Port(dstPortShort));
-	//
-	// 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);
-
-	    flowPath.setFlowEntryMatch(match);
-	}
-	//
-	// Extract the actions for the first Flow Entry
-	//
-	{
-	    String actionsStr = flowObj.getActions();
-	    if (actionsStr != null) {
-		FlowEntryActions flowEntryActions = new FlowEntryActions(actionsStr);
-		flowPath.setFlowEntryActions(flowEntryActions);
-	    }
-	}
-
-	//
-	// Extract all Flow Entries
-	//
-	Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
-	for (IFlowEntry flowEntryObj : flowEntries) {
-	    FlowEntry flowEntry = extractFlowEntry(flowEntryObj);
-	    if (flowEntry == null)
-		continue;
-	    flowPath.dataPath().flowEntries().add(flowEntry);
-	}
-
-	return flowPath;
-    }
-
-    /**
-     * Extract Flow Entry State from a Titan Database Object @ref IFlowEntry.
-     *
-     * @param flowEntryObj the object to extract the Flow Entry State from.
-     * @return the extracted Flow Entry State.
-     */
-    private FlowEntry extractFlowEntry(IFlowEntry flowEntryObj) {
-	String flowEntryIdStr = flowEntryObj.getFlowEntryId();
-	String switchDpidStr = flowEntryObj.getSwitchDpid();
-	String userState = flowEntryObj.getUserState();
-	String switchState = flowEntryObj.getSwitchState();
-
-	if ((flowEntryIdStr == null) ||
-	    (switchDpidStr == null) ||
-	    (userState == null) ||
-	    (switchState == null)) {
-	    // TODO: A work-around, becauuse of some bogus database objects
-	    return null;
-	}
-
-	FlowEntry flowEntry = new FlowEntry();
-	flowEntry.setFlowEntryId(new FlowEntryId(flowEntryIdStr));
-	flowEntry.setDpid(new Dpid(switchDpidStr));
-
-	//
-	// 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);
-	flowEntry.setFlowEntryMatch(match);
-
-	//
-	// Extract the actions
-	//
-	FlowEntryActions actions = new FlowEntryActions();
-	String actionsStr = flowEntryObj.getActions();
-	if (actionsStr != null)
-	    actions = new FlowEntryActions(actionsStr);
-	flowEntry.setFlowEntryActions(actions);
-	flowEntry.setFlowEntryUserState(FlowEntryUserState.valueOf(userState));
-	flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.valueOf(switchState));
-	//
-	// TODO: Take care of FlowEntryErrorState.
-	//
-	return flowEntry;
+	return FlowDatabaseOperation.getAllFlowsWithoutFlowEntries(dbHandler);
     }
 
     /**
@@ -1680,311 +761,9 @@
      */
     public boolean installFlowEntry(IOFSwitch mySwitch, IFlowPath flowObj,
 				    IFlowEntry flowEntryObj) {
-	String flowEntryIdStr = flowEntryObj.getFlowEntryId();
-	if (flowEntryIdStr == null)
-	    return false;
-	FlowEntryId flowEntryId = new FlowEntryId(flowEntryIdStr);
-	String userState = flowEntryObj.getUserState();
-	if (userState == null)
-	    return false;
-
-	//
-	// Create the Open Flow Flow Modification Entry to push
-	//
-	OFFlowMod fm = (OFFlowMod) floodlightProvider.getOFMessageFactory()
-	    .getMessage(OFType.FLOW_MOD);
-	long cookie = flowEntryId.value();
-
-	short flowModCommand = OFFlowMod.OFPFC_ADD;
-	if (userState.equals("FE_USER_ADD")) {
-	    flowModCommand = OFFlowMod.OFPFC_ADD;
-	} else if (userState.equals("FE_USER_MODIFY")) {
-	    flowModCommand = OFFlowMod.OFPFC_MODIFY_STRICT;
-	} else if (userState.equals("FE_USER_DELETE")) {
-	    flowModCommand = OFFlowMod.OFPFC_DELETE_STRICT;
-	} else {
-	    // Unknown user state. Ignore the entry
-	    log.debug("Flow Entry ignored (FlowEntryId = {}): unknown user state {}",
-		      flowEntryId.toString(), userState);
-	    return false;
-	}
-
-	//
-	// Fetch the match conditions.
-	//
-	// NOTE: The Flow matching conditions common for all Flow Entries are
-	// used ONLY if a Flow Entry does NOT have the corresponding matching
-	// condition set.
-	//
-	OFMatch match = new OFMatch();
-	match.setWildcards(OFMatch.OFPFW_ALL);
-
-	// Match the Incoming Port
-	Short matchInPort = flowEntryObj.getMatchInPort();
-	if (matchInPort != null) {
-	    match.setInputPort(matchInPort);
-	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_IN_PORT);
-	}
-
-	// Match the Source MAC address
-	String matchSrcMac = flowEntryObj.getMatchSrcMac();
-	if (matchSrcMac == null)
-	    matchSrcMac = flowObj.getMatchSrcMac();
-	if (matchSrcMac != null) {
-	    match.setDataLayerSource(matchSrcMac);
-	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_SRC);
-	}
-
-	// Match the Destination MAC address
-	String matchDstMac = flowEntryObj.getMatchDstMac();
-	if (matchDstMac == null)
-	    matchDstMac = flowObj.getMatchDstMac();
-	if (matchDstMac != null) {
-	    match.setDataLayerDestination(matchDstMac);
-	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_DST);
-	}
-
-	// Match the Ethernet Frame Type
-	Short matchEthernetFrameType = flowEntryObj.getMatchEthernetFrameType();
-	if (matchEthernetFrameType == null)
-	    matchEthernetFrameType = flowObj.getMatchEthernetFrameType();
-	if (matchEthernetFrameType != null) {
-	    match.setDataLayerType(matchEthernetFrameType);
-	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_TYPE);
-	}
-
-	// Match the VLAN ID
-	Short matchVlanId = flowEntryObj.getMatchVlanId();
-	if (matchVlanId == null)
-	    matchVlanId = flowObj.getMatchVlanId();
-	if (matchVlanId != null) {
-	    match.setDataLayerVirtualLan(matchVlanId);
-	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_VLAN);
-	}
-
-	// Match the VLAN priority
-	Byte matchVlanPriority = flowEntryObj.getMatchVlanPriority();
-	if (matchVlanPriority == null)
-	    matchVlanPriority = flowObj.getMatchVlanPriority();
-	if (matchVlanPriority != null) {
-	    match.setDataLayerVirtualLanPriorityCodePoint(matchVlanPriority);
-	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_VLAN_PCP);
-	}
-
-	// Match the Source IPv4 Network prefix
-	String matchSrcIPv4Net = flowEntryObj.getMatchSrcIPv4Net();
-	if (matchSrcIPv4Net == null)
-	    matchSrcIPv4Net = flowObj.getMatchSrcIPv4Net();
-	if (matchSrcIPv4Net != null) {
-	    match.setFromCIDR(matchSrcIPv4Net, OFMatch.STR_NW_SRC);
-	}
-
-	// Natch the Destination IPv4 Network prefix
-	String matchDstIPv4Net = flowEntryObj.getMatchDstIPv4Net();
-	if (matchDstIPv4Net == null)
-	    matchDstIPv4Net = flowObj.getMatchDstIPv4Net();
-	if (matchDstIPv4Net != null) {
-	    match.setFromCIDR(matchDstIPv4Net, OFMatch.STR_NW_DST);
-	}
-
-	// Match the IP protocol
-	Byte matchIpProto = flowEntryObj.getMatchIpProto();
-	if (matchIpProto == null)
-	    matchIpProto = flowObj.getMatchIpProto();
-	if (matchIpProto != null) {
-	    match.setNetworkProtocol(matchIpProto);
-	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_NW_PROTO);
-	}
-
-	// Match the IP ToS (DSCP field, 6 bits)
-	Byte matchIpToS = flowEntryObj.getMatchIpToS();
-	if (matchIpToS == null)
-	    matchIpToS = flowObj.getMatchIpToS();
-	if (matchIpToS != null) {
-	    match.setNetworkTypeOfService(matchIpToS);
-	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_NW_TOS);
-	}
-
-	// Match the Source TCP/UDP port
-	Short matchSrcTcpUdpPort = flowEntryObj.getMatchSrcTcpUdpPort();
-	if (matchSrcTcpUdpPort == null)
-	    matchSrcTcpUdpPort = flowObj.getMatchSrcTcpUdpPort();
-	if (matchSrcTcpUdpPort != null) {
-	    match.setTransportSource(matchSrcTcpUdpPort);
-	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_TP_SRC);
-	}
-
-	// Match the Destination TCP/UDP port
-	Short matchDstTcpUdpPort = flowEntryObj.getMatchDstTcpUdpPort();
-	if (matchDstTcpUdpPort == null)
-	    matchDstTcpUdpPort = flowObj.getMatchDstTcpUdpPort();
-	if (matchDstTcpUdpPort != null) {
-	    match.setTransportDestination(matchDstTcpUdpPort);
-	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_TP_DST);
-	}
-
-	//
-	// Fetch the actions
-	//
-	Short actionOutputPort = null;
-	List<OFAction> openFlowActions = new ArrayList<OFAction>();
-	int actionsLen = 0;
-	FlowEntryActions flowEntryActions = null;
-	String actionsStr = flowEntryObj.getActions();
-	if (actionsStr != null)
-	    flowEntryActions = new FlowEntryActions(actionsStr);
-	for (FlowEntryAction action : flowEntryActions.actions()) {
-	    ActionOutput actionOutput = action.actionOutput();
-	    ActionSetVlanId actionSetVlanId = action.actionSetVlanId();
-	    ActionSetVlanPriority actionSetVlanPriority = action.actionSetVlanPriority();
-	    ActionStripVlan actionStripVlan = action.actionStripVlan();
-	    ActionSetEthernetAddr actionSetEthernetSrcAddr = action.actionSetEthernetSrcAddr();
-	    ActionSetEthernetAddr actionSetEthernetDstAddr = action.actionSetEthernetDstAddr();
-	    ActionSetIPv4Addr actionSetIPv4SrcAddr = action.actionSetIPv4SrcAddr();
-	    ActionSetIPv4Addr actionSetIPv4DstAddr = action.actionSetIPv4DstAddr();
-	    ActionSetIpToS actionSetIpToS = action.actionSetIpToS();
-	    ActionSetTcpUdpPort actionSetTcpUdpSrcPort = action.actionSetTcpUdpSrcPort();
-	    ActionSetTcpUdpPort actionSetTcpUdpDstPort = action.actionSetTcpUdpDstPort();
-	    ActionEnqueue actionEnqueue = action.actionEnqueue();
-
-	    if (actionOutput != null) {
-		actionOutputPort = actionOutput.port().value();
-		// XXX: The max length is hard-coded for now
-		OFActionOutput ofa =
-		    new OFActionOutput(actionOutput.port().value(),
-				       (short)0xffff);
-		openFlowActions.add(ofa);
-		actionsLen += ofa.getLength();
-	    }
-
-	    if (actionSetVlanId != null) {
-		OFActionVirtualLanIdentifier ofa =
-		    new OFActionVirtualLanIdentifier(actionSetVlanId.vlanId());
-		openFlowActions.add(ofa);
-		actionsLen += ofa.getLength();
-	    }
-
-	    if (actionSetVlanPriority != null) {
-		OFActionVirtualLanPriorityCodePoint ofa =
-		    new OFActionVirtualLanPriorityCodePoint(actionSetVlanPriority.vlanPriority());
-		openFlowActions.add(ofa);
-		actionsLen += ofa.getLength();
-	    }
-
-	    if (actionStripVlan != null) {
-		if (actionStripVlan.stripVlan() == true) {
-		    OFActionStripVirtualLan ofa = new OFActionStripVirtualLan();
-		    openFlowActions.add(ofa);
-		    actionsLen += ofa.getLength();
-		}
-	    }
-
-	    if (actionSetEthernetSrcAddr != null) {
-		OFActionDataLayerSource ofa = 
-		    new OFActionDataLayerSource(actionSetEthernetSrcAddr.addr().toBytes());
-		openFlowActions.add(ofa);
-		actionsLen += ofa.getLength();
-	    }
-
-	    if (actionSetEthernetDstAddr != null) {
-		OFActionDataLayerDestination ofa =
-		    new OFActionDataLayerDestination(actionSetEthernetDstAddr.addr().toBytes());
-		openFlowActions.add(ofa);
-		actionsLen += ofa.getLength();
-	    }
-
-	    if (actionSetIPv4SrcAddr != null) {
-		OFActionNetworkLayerSource ofa =
-		    new OFActionNetworkLayerSource(actionSetIPv4SrcAddr.addr().value());
-		openFlowActions.add(ofa);
-		actionsLen += ofa.getLength();
-	    }
-
-	    if (actionSetIPv4DstAddr != null) {
-		OFActionNetworkLayerDestination ofa =
-		    new OFActionNetworkLayerDestination(actionSetIPv4DstAddr.addr().value());
-		openFlowActions.add(ofa);
-		actionsLen += ofa.getLength();
-	    }
-
-	    if (actionSetIpToS != null) {
-		OFActionNetworkTypeOfService ofa =
-		    new OFActionNetworkTypeOfService(actionSetIpToS.ipToS());
-		openFlowActions.add(ofa);
-		actionsLen += ofa.getLength();
-	    }
-
-	    if (actionSetTcpUdpSrcPort != null) {
-		OFActionTransportLayerSource ofa =
-		    new OFActionTransportLayerSource(actionSetTcpUdpSrcPort.port());
-		openFlowActions.add(ofa);
-		actionsLen += ofa.getLength();
-	    }
-
-	    if (actionSetTcpUdpDstPort != null) {
-		OFActionTransportLayerDestination ofa =
-		    new OFActionTransportLayerDestination(actionSetTcpUdpDstPort.port());
-		openFlowActions.add(ofa);
-		actionsLen += ofa.getLength();
-	    }
-
-	    if (actionEnqueue != null) {
-		OFActionEnqueue ofa =
-		    new OFActionEnqueue(actionEnqueue.port().value(),
-					actionEnqueue.queueId());
-		openFlowActions.add(ofa);
-		actionsLen += ofa.getLength();
-	    }
-	}
-
-	fm.setIdleTimeout(FLOWMOD_DEFAULT_IDLE_TIMEOUT)
-	    .setHardTimeout(FLOWMOD_DEFAULT_HARD_TIMEOUT)
-	    .setPriority(PRIORITY_DEFAULT)
-	    .setBufferId(OFPacketOut.BUFFER_ID_NONE)
-	    .setCookie(cookie)
-	    .setCommand(flowModCommand)
-	    .setMatch(match)
-	    .setActions(openFlowActions)
-	    .setLengthU(OFFlowMod.MINIMUM_LENGTH + actionsLen);
-	fm.setOutPort(OFPort.OFPP_NONE.getValue());
-	if ((flowModCommand == OFFlowMod.OFPFC_DELETE) ||
-	    (flowModCommand == OFFlowMod.OFPFC_DELETE_STRICT)) {
-	    if (actionOutputPort != null)
-		fm.setOutPort(actionOutputPort);
-	}
-
-	//
-	// TODO: Set the following flag
-	// fm.setFlags(OFFlowMod.OFPFF_SEND_FLOW_REM);
-	// See method ForwardingBase::pushRoute()
-	//
-
-	//
-	// Write the message to the switch
-	//
-	log.debug("MEASUREMENT: Installing flow entry " + userState +
-		  " into switch DPID: " +
-		  mySwitch.getStringId() +
-		  " flowEntryId: " + flowEntryId.toString() +
-		  " srcMac: " + matchSrcMac + " dstMac: " + matchDstMac +
-		  " inPort: " + matchInPort + " outPort: " + actionOutputPort
-		  );
-	try {
-	    messageDamper.write(mySwitch, fm, null);
-	    mySwitch.flush();
-	    //
-	    // TODO: We should use the OpenFlow Barrier mechanism
-	    // to check for errors, and update the SwitchState
-	    // for a flow entry after the Barrier message is
-	    // is received.
-	    //
-	    flowEntryObj.setSwitchState("FE_SWITCH_UPDATED");
-	} catch (IOException e) {
-	    log.error("Failure writing flow mod from network map", e);
-	    return false;
-	}
-
-	return true;
+	return FlowSwitchOperation.installFlowEntry(
+		floodlightProvider.getOFMessageFactory(),
+		messageDamper, mySwitch, flowObj, flowEntryObj);
     }
 
     /**
@@ -1997,309 +776,9 @@
      */
     public boolean installFlowEntry(IOFSwitch mySwitch, FlowPath flowPath,
 				    FlowEntry flowEntry) {
-	//
-	// Create the OpenFlow Flow Modification Entry to push
-	//
-	OFFlowMod fm = (OFFlowMod) floodlightProvider.getOFMessageFactory()
-	    .getMessage(OFType.FLOW_MOD);
-	long cookie = flowEntry.flowEntryId().value();
-
-	short flowModCommand = OFFlowMod.OFPFC_ADD;
-	if (flowEntry.flowEntryUserState() == FlowEntryUserState.FE_USER_ADD) {
-	    flowModCommand = OFFlowMod.OFPFC_ADD;
-	} else if (flowEntry.flowEntryUserState() == FlowEntryUserState.FE_USER_MODIFY) {
-	    flowModCommand = OFFlowMod.OFPFC_MODIFY_STRICT;
-	} else if (flowEntry.flowEntryUserState() == FlowEntryUserState.FE_USER_DELETE) {
-	    flowModCommand = OFFlowMod.OFPFC_DELETE_STRICT;
-	} else {
-	    // Unknown user state. Ignore the entry
-	    log.debug("Flow Entry ignored (FlowEntryId = {}): unknown user state {}",
-		      flowEntry.flowEntryId().toString(),
-		      flowEntry.flowEntryUserState());
-	    return false;
-	}
-
-	//
-	// Fetch the match conditions.
-	//
-	// NOTE: The Flow matching conditions common for all Flow Entries are
-	// used ONLY if a Flow Entry does NOT have the corresponding matching
-	// condition set.
-	//
-	OFMatch match = new OFMatch();
-	match.setWildcards(OFMatch.OFPFW_ALL);
-	FlowEntryMatch flowPathMatch = flowPath.flowEntryMatch();
-	FlowEntryMatch flowEntryMatch = flowEntry.flowEntryMatch();
-
-	// Match the Incoming Port
-	Port matchInPort = flowEntryMatch.inPort();
-	if (matchInPort != null) {
-	    match.setInputPort(matchInPort.value());
-	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_IN_PORT);
-	}
-
-	// Match the Source MAC address
-	MACAddress matchSrcMac = flowEntryMatch.srcMac();
-	if ((matchSrcMac == null) && (flowPathMatch != null)) {
-	    matchSrcMac = flowPathMatch.srcMac();
-	}
-	if (matchSrcMac != null) {
-	    match.setDataLayerSource(matchSrcMac.toString());
-	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_SRC);
-	}
-
-	// Match the Destination MAC address
-	MACAddress matchDstMac = flowEntryMatch.dstMac();
-	if ((matchDstMac == null) && (flowPathMatch != null)) {
-	    matchDstMac = flowPathMatch.dstMac();
-	}
-	if (matchDstMac != null) {
-	    match.setDataLayerDestination(matchDstMac.toString());
-	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_DST);
-	}
-
-	// Match the Ethernet Frame Type
-	Short matchEthernetFrameType = flowEntryMatch.ethernetFrameType();
-	if ((matchEthernetFrameType == null) && (flowPathMatch != null)) {
-	    matchEthernetFrameType = flowPathMatch.ethernetFrameType();
-	}
-	if (matchEthernetFrameType != null) {
-	    match.setDataLayerType(matchEthernetFrameType);
-	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_TYPE);
-	}
-
-	// Match the VLAN ID
-	Short matchVlanId = flowEntryMatch.vlanId();
-	if ((matchVlanId == null) && (flowPathMatch != null)) {
-	    matchVlanId = flowPathMatch.vlanId();
-	}
-	if (matchVlanId != null) {
-	    match.setDataLayerVirtualLan(matchVlanId);
-	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_VLAN);
-	}
-
-	// Match the VLAN priority
-	Byte matchVlanPriority = flowEntryMatch.vlanPriority();
-	if ((matchVlanPriority == null) && (flowPathMatch != null)) {
-	    matchVlanPriority = flowPathMatch.vlanPriority();
-	}
-	if (matchVlanPriority != null) {
-	    match.setDataLayerVirtualLanPriorityCodePoint(matchVlanPriority);
-	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_VLAN_PCP);
-	}
-
-	// Match the Source IPv4 Network prefix
-	IPv4Net matchSrcIPv4Net = flowEntryMatch.srcIPv4Net();
-	if ((matchSrcIPv4Net == null) && (flowPathMatch != null)) {
-	    matchSrcIPv4Net = flowPathMatch.srcIPv4Net();
-	}
-	if (matchSrcIPv4Net != null) {
-	    match.setFromCIDR(matchSrcIPv4Net.toString(), OFMatch.STR_NW_SRC);
-	}
-
-	// Natch the Destination IPv4 Network prefix
-	IPv4Net matchDstIPv4Net = flowEntryMatch.dstIPv4Net();
-	if ((matchDstIPv4Net == null) && (flowPathMatch != null)) {
-	    matchDstIPv4Net = flowPathMatch.dstIPv4Net();
-	}
-	if (matchDstIPv4Net != null) {
-	    match.setFromCIDR(matchDstIPv4Net.toString(), OFMatch.STR_NW_DST);
-	}
-
-	// Match the IP protocol
-	Byte matchIpProto = flowEntryMatch.ipProto();
-	if ((matchIpProto == null) && (flowPathMatch != null)) {
-	    matchIpProto = flowPathMatch.ipProto();
-	}
-	if (matchIpProto != null) {
-	    match.setNetworkProtocol(matchIpProto);
-	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_NW_PROTO);
-	}
-
-	// Match the IP ToS (DSCP field, 6 bits)
-	Byte matchIpToS = flowEntryMatch.ipToS();
-	if ((matchIpToS == null) && (flowPathMatch != null)) {
-	    matchIpToS = flowPathMatch.ipToS();
-	}
-	if (matchIpToS != null) {
-	    match.setNetworkTypeOfService(matchIpToS);
-	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_NW_TOS);
-	}
-
-	// Match the Source TCP/UDP port
-	Short matchSrcTcpUdpPort = flowEntryMatch.srcTcpUdpPort();
-	if ((matchSrcTcpUdpPort == null) && (flowPathMatch != null)) {
-	    matchSrcTcpUdpPort = flowPathMatch.srcTcpUdpPort();
-	}
-	if (matchSrcTcpUdpPort != null) {
-	    match.setTransportSource(matchSrcTcpUdpPort);
-	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_TP_SRC);
-	}
-
-	// Match the Destination TCP/UDP port
-	Short matchDstTcpUdpPort = flowEntryMatch.dstTcpUdpPort();
-	if ((matchDstTcpUdpPort == null) && (flowPathMatch != null)) {
-	    matchDstTcpUdpPort = flowPathMatch.dstTcpUdpPort();
-	}
-	if (matchDstTcpUdpPort != null) {
-	    match.setTransportDestination(matchDstTcpUdpPort);
-	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_TP_DST);
-	}
-
-	//
-	// Fetch the actions
-	//
-	Short actionOutputPort = null;
-	List<OFAction> openFlowActions = new ArrayList<OFAction>();
-	int actionsLen = 0;
-	FlowEntryActions flowEntryActions = flowEntry.flowEntryActions();
-	//
-	for (FlowEntryAction action : flowEntryActions.actions()) {
-	    ActionOutput actionOutput = action.actionOutput();
-	    ActionSetVlanId actionSetVlanId = action.actionSetVlanId();
-	    ActionSetVlanPriority actionSetVlanPriority = action.actionSetVlanPriority();
-	    ActionStripVlan actionStripVlan = action.actionStripVlan();
-	    ActionSetEthernetAddr actionSetEthernetSrcAddr = action.actionSetEthernetSrcAddr();
-	    ActionSetEthernetAddr actionSetEthernetDstAddr = action.actionSetEthernetDstAddr();
-	    ActionSetIPv4Addr actionSetIPv4SrcAddr = action.actionSetIPv4SrcAddr();
-	    ActionSetIPv4Addr actionSetIPv4DstAddr = action.actionSetIPv4DstAddr();
-	    ActionSetIpToS actionSetIpToS = action.actionSetIpToS();
-	    ActionSetTcpUdpPort actionSetTcpUdpSrcPort = action.actionSetTcpUdpSrcPort();
-	    ActionSetTcpUdpPort actionSetTcpUdpDstPort = action.actionSetTcpUdpDstPort();
-	    ActionEnqueue actionEnqueue = action.actionEnqueue();
-
-	    if (actionOutput != null) {
-		actionOutputPort = actionOutput.port().value();
-		// XXX: The max length is hard-coded for now
-		OFActionOutput ofa =
-		    new OFActionOutput(actionOutput.port().value(),
-				       (short)0xffff);
-		openFlowActions.add(ofa);
-		actionsLen += ofa.getLength();
-	    }
-
-	    if (actionSetVlanId != null) {
-		OFActionVirtualLanIdentifier ofa =
-		    new OFActionVirtualLanIdentifier(actionSetVlanId.vlanId());
-		openFlowActions.add(ofa);
-		actionsLen += ofa.getLength();
-	    }
-
-	    if (actionSetVlanPriority != null) {
-		OFActionVirtualLanPriorityCodePoint ofa =
-		    new OFActionVirtualLanPriorityCodePoint(actionSetVlanPriority.vlanPriority());
-		openFlowActions.add(ofa);
-		actionsLen += ofa.getLength();
-	    }
-
-	    if (actionStripVlan != null) {
-		if (actionStripVlan.stripVlan() == true) {
-		    OFActionStripVirtualLan ofa = new OFActionStripVirtualLan();
-		    openFlowActions.add(ofa);
-		    actionsLen += ofa.getLength();
-		}
-	    }
-
-	    if (actionSetEthernetSrcAddr != null) {
-		OFActionDataLayerSource ofa = 
-		    new OFActionDataLayerSource(actionSetEthernetSrcAddr.addr().toBytes());
-		openFlowActions.add(ofa);
-		actionsLen += ofa.getLength();
-	    }
-
-	    if (actionSetEthernetDstAddr != null) {
-		OFActionDataLayerDestination ofa =
-		    new OFActionDataLayerDestination(actionSetEthernetDstAddr.addr().toBytes());
-		openFlowActions.add(ofa);
-		actionsLen += ofa.getLength();
-	    }
-
-	    if (actionSetIPv4SrcAddr != null) {
-		OFActionNetworkLayerSource ofa =
-		    new OFActionNetworkLayerSource(actionSetIPv4SrcAddr.addr().value());
-		openFlowActions.add(ofa);
-		actionsLen += ofa.getLength();
-	    }
-
-	    if (actionSetIPv4DstAddr != null) {
-		OFActionNetworkLayerDestination ofa =
-		    new OFActionNetworkLayerDestination(actionSetIPv4DstAddr.addr().value());
-		openFlowActions.add(ofa);
-		actionsLen += ofa.getLength();
-	    }
-
-	    if (actionSetIpToS != null) {
-		OFActionNetworkTypeOfService ofa =
-		    new OFActionNetworkTypeOfService(actionSetIpToS.ipToS());
-		openFlowActions.add(ofa);
-		actionsLen += ofa.getLength();
-	    }
-
-	    if (actionSetTcpUdpSrcPort != null) {
-		OFActionTransportLayerSource ofa =
-		    new OFActionTransportLayerSource(actionSetTcpUdpSrcPort.port());
-		openFlowActions.add(ofa);
-		actionsLen += ofa.getLength();
-	    }
-
-	    if (actionSetTcpUdpDstPort != null) {
-		OFActionTransportLayerDestination ofa =
-		    new OFActionTransportLayerDestination(actionSetTcpUdpDstPort.port());
-		openFlowActions.add(ofa);
-		actionsLen += ofa.getLength();
-	    }
-
-	    if (actionEnqueue != null) {
-		OFActionEnqueue ofa =
-		    new OFActionEnqueue(actionEnqueue.port().value(),
-					actionEnqueue.queueId());
-		openFlowActions.add(ofa);
-		actionsLen += ofa.getLength();
-	    }
-	}
-
-	fm.setIdleTimeout(FLOWMOD_DEFAULT_IDLE_TIMEOUT)
-	    .setHardTimeout(FLOWMOD_DEFAULT_HARD_TIMEOUT)
-	    .setPriority(PRIORITY_DEFAULT)
-	    .setBufferId(OFPacketOut.BUFFER_ID_NONE)
-	    .setCookie(cookie)
-	    .setCommand(flowModCommand)
-	    .setMatch(match)
-	    .setActions(openFlowActions)
-	    .setLengthU(OFFlowMod.MINIMUM_LENGTH + actionsLen);
-	fm.setOutPort(OFPort.OFPP_NONE.getValue());
-	if ((flowModCommand == OFFlowMod.OFPFC_DELETE) ||
-	    (flowModCommand == OFFlowMod.OFPFC_DELETE_STRICT)) {
-	    if (actionOutputPort != null)
-		fm.setOutPort(actionOutputPort);
-	}
-
-	//
-	// TODO: Set the following flag
-	// fm.setFlags(OFFlowMod.OFPFF_SEND_FLOW_REM);
-	// See method ForwardingBase::pushRoute()
-	//
-
-	//
-	// Write the message to the switch
-	//
-	try {
-	    messageDamper.write(mySwitch, fm, null);
-	    mySwitch.flush();
-	    //
-	    // TODO: We should use the OpenFlow Barrier mechanism
-	    // to check for errors, and update the SwitchState
-	    // for a flow entry after the Barrier message is
-	    // is received.
-	    //
-	    // TODO: The FlowEntry Object in Titan should be set
-	    // to FE_SWITCH_UPDATED.
-	    //
-	} catch (IOException e) {
-	    log.error("Failure writing flow mod from network map", e);
-	    return false;
-	}
-	return true;
+	return FlowSwitchOperation.installFlowEntry(
+		floodlightProvider.getOFMessageFactory(),
+		messageDamper, mySwitch, flowPath, flowEntry);
     }
 
     /**
@@ -2318,39 +797,4 @@
 	//
 	return (installFlowEntry(mySwitch, flowPath, flowEntry));
     }
-
-    /**
-     * Install a Flow Entry on a remote controller.
-     *
-     * TODO: We need it now: Jono
-     * - For now it will make a REST call to the remote controller.
-     * - Internally, it needs to know the name of the remote controller.
-     *
-     * @param flowPath the flow path for the flow entry to install.
-     * @param flowEntry the flow entry to install.
-     * @return true on success, otherwise false.
-     */
-    public boolean installRemoteFlowEntry(FlowPath flowPath,
-					  FlowEntry flowEntry) {
-	// TODO: We need it now: Jono
-	//  - For now it will make a REST call to the remote controller.
-	//  - Internally, it needs to know the name of the remote controller.
-	return true;
-    }
-
-    /**
-     * Remove a flow entry on a remote controller.
-     *
-     * @param flowPath the flow path for the flow entry to remove.
-     * @param flowEntry the flow entry to remove.
-     * @return true on success, otherwise false.
-     */
-    public boolean removeRemoteFlowEntry(FlowPath flowPath,
-					 FlowEntry flowEntry) {
-	//
-	// The installRemoteFlowEntry() method implements both installation
-	// and removal of flow entries.
-	//
-	return (installRemoteFlowEntry(flowPath, flowEntry));
-    }
 }
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowSwitchOperation.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowSwitchOperation.java
new file mode 100644
index 0000000..3eea1e1
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowSwitchOperation.java
@@ -0,0 +1,676 @@
+package net.onrc.onos.ofcontroller.flowmanager;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.util.MACAddress;
+import net.floodlightcontroller.util.OFMessageDamper;
+
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
+import net.onrc.onos.ofcontroller.util.*;
+import net.onrc.onos.ofcontroller.util.FlowEntryAction.*;
+
+import org.openflow.protocol.OFFlowMod;
+import org.openflow.protocol.OFMatch;
+import org.openflow.protocol.OFPacketOut;
+import org.openflow.protocol.OFPort;
+import org.openflow.protocol.OFType;
+import org.openflow.protocol.action.*;
+import org.openflow.protocol.factory.BasicFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Class for performing Flow-related operations on the Switch.
+ */
+class FlowSwitchOperation {
+    private static Logger log = LoggerFactory.getLogger(FlowSwitchOperation.class);
+    //
+    // TODO: Values copied from elsewhere (class LearningSwitch).
+    // The local copy should go away!
+    //
+    public static final short PRIORITY_DEFAULT = 100;
+    public static final short FLOWMOD_DEFAULT_IDLE_TIMEOUT = 0;	// infinity
+    public static final short FLOWMOD_DEFAULT_HARD_TIMEOUT = 0;	// infinite
+
+    /**
+     * Install a Flow Entry on a switch.
+     *
+     * @param messageFactory the OpenFlow message factory to use.
+     * @maram messageDamper the OpenFlow message damper to use.
+     * @param mySwitch the switch to install the Flow Entry into.
+     * @param flowObj the flow path object for the flow entry to install.
+     * @param flowEntryObj the flow entry object to install.
+     * @return true on success, otherwise false.
+     */
+    static boolean installFlowEntry(BasicFactory messageFactory,
+				    OFMessageDamper messageDamper,
+				    IOFSwitch mySwitch, IFlowPath flowObj,
+				    IFlowEntry flowEntryObj) {
+	String flowEntryIdStr = flowEntryObj.getFlowEntryId();
+	if (flowEntryIdStr == null)
+	    return false;
+	FlowEntryId flowEntryId = new FlowEntryId(flowEntryIdStr);
+	String userState = flowEntryObj.getUserState();
+	if (userState == null)
+	    return false;
+
+	//
+	// Create the Open Flow Flow Modification Entry to push
+	//
+	OFFlowMod fm = (OFFlowMod)messageFactory.getMessage(OFType.FLOW_MOD);
+	long cookie = flowEntryId.value();
+
+	short flowModCommand = OFFlowMod.OFPFC_ADD;
+	if (userState.equals("FE_USER_ADD")) {
+	    flowModCommand = OFFlowMod.OFPFC_ADD;
+	} else if (userState.equals("FE_USER_MODIFY")) {
+	    flowModCommand = OFFlowMod.OFPFC_MODIFY_STRICT;
+	} else if (userState.equals("FE_USER_DELETE")) {
+	    flowModCommand = OFFlowMod.OFPFC_DELETE_STRICT;
+	} else {
+	    // Unknown user state. Ignore the entry
+	    log.debug("Flow Entry ignored (FlowEntryId = {}): unknown user state {}",
+		      flowEntryId.toString(), userState);
+	    return false;
+	}
+
+	//
+	// Fetch the match conditions.
+	//
+	// NOTE: The Flow matching conditions common for all Flow Entries are
+	// used ONLY if a Flow Entry does NOT have the corresponding matching
+	// condition set.
+	//
+	OFMatch match = new OFMatch();
+	match.setWildcards(OFMatch.OFPFW_ALL);
+
+	// Match the Incoming Port
+	Short matchInPort = flowEntryObj.getMatchInPort();
+	if (matchInPort != null) {
+	    match.setInputPort(matchInPort);
+	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_IN_PORT);
+	}
+
+	// Match the Source MAC address
+	String matchSrcMac = flowEntryObj.getMatchSrcMac();
+	if (matchSrcMac == null)
+	    matchSrcMac = flowObj.getMatchSrcMac();
+	if (matchSrcMac != null) {
+	    match.setDataLayerSource(matchSrcMac);
+	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_SRC);
+	}
+
+	// Match the Destination MAC address
+	String matchDstMac = flowEntryObj.getMatchDstMac();
+	if (matchDstMac == null)
+	    matchDstMac = flowObj.getMatchDstMac();
+	if (matchDstMac != null) {
+	    match.setDataLayerDestination(matchDstMac);
+	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_DST);
+	}
+
+	// Match the Ethernet Frame Type
+	Short matchEthernetFrameType = flowEntryObj.getMatchEthernetFrameType();
+	if (matchEthernetFrameType == null)
+	    matchEthernetFrameType = flowObj.getMatchEthernetFrameType();
+	if (matchEthernetFrameType != null) {
+	    match.setDataLayerType(matchEthernetFrameType);
+	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_TYPE);
+	}
+
+	// Match the VLAN ID
+	Short matchVlanId = flowEntryObj.getMatchVlanId();
+	if (matchVlanId == null)
+	    matchVlanId = flowObj.getMatchVlanId();
+	if (matchVlanId != null) {
+	    match.setDataLayerVirtualLan(matchVlanId);
+	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_VLAN);
+	}
+
+	// Match the VLAN priority
+	Byte matchVlanPriority = flowEntryObj.getMatchVlanPriority();
+	if (matchVlanPriority == null)
+	    matchVlanPriority = flowObj.getMatchVlanPriority();
+	if (matchVlanPriority != null) {
+	    match.setDataLayerVirtualLanPriorityCodePoint(matchVlanPriority);
+	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_VLAN_PCP);
+	}
+
+	// Match the Source IPv4 Network prefix
+	String matchSrcIPv4Net = flowEntryObj.getMatchSrcIPv4Net();
+	if (matchSrcIPv4Net == null)
+	    matchSrcIPv4Net = flowObj.getMatchSrcIPv4Net();
+	if (matchSrcIPv4Net != null) {
+	    match.setFromCIDR(matchSrcIPv4Net, OFMatch.STR_NW_SRC);
+	}
+
+	// Natch the Destination IPv4 Network prefix
+	String matchDstIPv4Net = flowEntryObj.getMatchDstIPv4Net();
+	if (matchDstIPv4Net == null)
+	    matchDstIPv4Net = flowObj.getMatchDstIPv4Net();
+	if (matchDstIPv4Net != null) {
+	    match.setFromCIDR(matchDstIPv4Net, OFMatch.STR_NW_DST);
+	}
+
+	// Match the IP protocol
+	Byte matchIpProto = flowEntryObj.getMatchIpProto();
+	if (matchIpProto == null)
+	    matchIpProto = flowObj.getMatchIpProto();
+	if (matchIpProto != null) {
+	    match.setNetworkProtocol(matchIpProto);
+	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_NW_PROTO);
+	}
+
+	// Match the IP ToS (DSCP field, 6 bits)
+	Byte matchIpToS = flowEntryObj.getMatchIpToS();
+	if (matchIpToS == null)
+	    matchIpToS = flowObj.getMatchIpToS();
+	if (matchIpToS != null) {
+	    match.setNetworkTypeOfService(matchIpToS);
+	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_NW_TOS);
+	}
+
+	// Match the Source TCP/UDP port
+	Short matchSrcTcpUdpPort = flowEntryObj.getMatchSrcTcpUdpPort();
+	if (matchSrcTcpUdpPort == null)
+	    matchSrcTcpUdpPort = flowObj.getMatchSrcTcpUdpPort();
+	if (matchSrcTcpUdpPort != null) {
+	    match.setTransportSource(matchSrcTcpUdpPort);
+	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_TP_SRC);
+	}
+
+	// Match the Destination TCP/UDP port
+	Short matchDstTcpUdpPort = flowEntryObj.getMatchDstTcpUdpPort();
+	if (matchDstTcpUdpPort == null)
+	    matchDstTcpUdpPort = flowObj.getMatchDstTcpUdpPort();
+	if (matchDstTcpUdpPort != null) {
+	    match.setTransportDestination(matchDstTcpUdpPort);
+	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_TP_DST);
+	}
+
+	//
+	// Fetch the actions
+	//
+	Short actionOutputPort = null;
+	List<OFAction> openFlowActions = new ArrayList<OFAction>();
+	int actionsLen = 0;
+	FlowEntryActions flowEntryActions = null;
+	String actionsStr = flowEntryObj.getActions();
+	if (actionsStr != null)
+	    flowEntryActions = new FlowEntryActions(actionsStr);
+	for (FlowEntryAction action : flowEntryActions.actions()) {
+	    ActionOutput actionOutput = action.actionOutput();
+	    ActionSetVlanId actionSetVlanId = action.actionSetVlanId();
+	    ActionSetVlanPriority actionSetVlanPriority = action.actionSetVlanPriority();
+	    ActionStripVlan actionStripVlan = action.actionStripVlan();
+	    ActionSetEthernetAddr actionSetEthernetSrcAddr = action.actionSetEthernetSrcAddr();
+	    ActionSetEthernetAddr actionSetEthernetDstAddr = action.actionSetEthernetDstAddr();
+	    ActionSetIPv4Addr actionSetIPv4SrcAddr = action.actionSetIPv4SrcAddr();
+	    ActionSetIPv4Addr actionSetIPv4DstAddr = action.actionSetIPv4DstAddr();
+	    ActionSetIpToS actionSetIpToS = action.actionSetIpToS();
+	    ActionSetTcpUdpPort actionSetTcpUdpSrcPort = action.actionSetTcpUdpSrcPort();
+	    ActionSetTcpUdpPort actionSetTcpUdpDstPort = action.actionSetTcpUdpDstPort();
+	    ActionEnqueue actionEnqueue = action.actionEnqueue();
+
+	    if (actionOutput != null) {
+		actionOutputPort = actionOutput.port().value();
+		// XXX: The max length is hard-coded for now
+		OFActionOutput ofa =
+		    new OFActionOutput(actionOutput.port().value(),
+				       (short)0xffff);
+		openFlowActions.add(ofa);
+		actionsLen += ofa.getLength();
+	    }
+
+	    if (actionSetVlanId != null) {
+		OFActionVirtualLanIdentifier ofa =
+		    new OFActionVirtualLanIdentifier(actionSetVlanId.vlanId());
+		openFlowActions.add(ofa);
+		actionsLen += ofa.getLength();
+	    }
+
+	    if (actionSetVlanPriority != null) {
+		OFActionVirtualLanPriorityCodePoint ofa =
+		    new OFActionVirtualLanPriorityCodePoint(actionSetVlanPriority.vlanPriority());
+		openFlowActions.add(ofa);
+		actionsLen += ofa.getLength();
+	    }
+
+	    if (actionStripVlan != null) {
+		if (actionStripVlan.stripVlan() == true) {
+		    OFActionStripVirtualLan ofa = new OFActionStripVirtualLan();
+		    openFlowActions.add(ofa);
+		    actionsLen += ofa.getLength();
+		}
+	    }
+
+	    if (actionSetEthernetSrcAddr != null) {
+		OFActionDataLayerSource ofa = 
+		    new OFActionDataLayerSource(actionSetEthernetSrcAddr.addr().toBytes());
+		openFlowActions.add(ofa);
+		actionsLen += ofa.getLength();
+	    }
+
+	    if (actionSetEthernetDstAddr != null) {
+		OFActionDataLayerDestination ofa =
+		    new OFActionDataLayerDestination(actionSetEthernetDstAddr.addr().toBytes());
+		openFlowActions.add(ofa);
+		actionsLen += ofa.getLength();
+	    }
+
+	    if (actionSetIPv4SrcAddr != null) {
+		OFActionNetworkLayerSource ofa =
+		    new OFActionNetworkLayerSource(actionSetIPv4SrcAddr.addr().value());
+		openFlowActions.add(ofa);
+		actionsLen += ofa.getLength();
+	    }
+
+	    if (actionSetIPv4DstAddr != null) {
+		OFActionNetworkLayerDestination ofa =
+		    new OFActionNetworkLayerDestination(actionSetIPv4DstAddr.addr().value());
+		openFlowActions.add(ofa);
+		actionsLen += ofa.getLength();
+	    }
+
+	    if (actionSetIpToS != null) {
+		OFActionNetworkTypeOfService ofa =
+		    new OFActionNetworkTypeOfService(actionSetIpToS.ipToS());
+		openFlowActions.add(ofa);
+		actionsLen += ofa.getLength();
+	    }
+
+	    if (actionSetTcpUdpSrcPort != null) {
+		OFActionTransportLayerSource ofa =
+		    new OFActionTransportLayerSource(actionSetTcpUdpSrcPort.port());
+		openFlowActions.add(ofa);
+		actionsLen += ofa.getLength();
+	    }
+
+	    if (actionSetTcpUdpDstPort != null) {
+		OFActionTransportLayerDestination ofa =
+		    new OFActionTransportLayerDestination(actionSetTcpUdpDstPort.port());
+		openFlowActions.add(ofa);
+		actionsLen += ofa.getLength();
+	    }
+
+	    if (actionEnqueue != null) {
+		OFActionEnqueue ofa =
+		    new OFActionEnqueue(actionEnqueue.port().value(),
+					actionEnqueue.queueId());
+		openFlowActions.add(ofa);
+		actionsLen += ofa.getLength();
+	    }
+	}
+
+	fm.setIdleTimeout(FLOWMOD_DEFAULT_IDLE_TIMEOUT)
+	    .setHardTimeout(FLOWMOD_DEFAULT_HARD_TIMEOUT)
+	    .setPriority(PRIORITY_DEFAULT)
+	    .setBufferId(OFPacketOut.BUFFER_ID_NONE)
+	    .setCookie(cookie)
+	    .setCommand(flowModCommand)
+	    .setMatch(match)
+	    .setActions(openFlowActions)
+	    .setLengthU(OFFlowMod.MINIMUM_LENGTH + actionsLen);
+	fm.setOutPort(OFPort.OFPP_NONE.getValue());
+	if ((flowModCommand == OFFlowMod.OFPFC_DELETE) ||
+	    (flowModCommand == OFFlowMod.OFPFC_DELETE_STRICT)) {
+	    if (actionOutputPort != null)
+		fm.setOutPort(actionOutputPort);
+	}
+
+	//
+	// TODO: Set the following flag
+	// fm.setFlags(OFFlowMod.OFPFF_SEND_FLOW_REM);
+	// See method ForwardingBase::pushRoute()
+	//
+
+	//
+	// Write the message to the switch
+	//
+	log.debug("MEASUREMENT: Installing flow entry " + userState +
+		  " into switch DPID: " +
+		  mySwitch.getStringId() +
+		  " flowEntryId: " + flowEntryId.toString() +
+		  " srcMac: " + matchSrcMac + " dstMac: " + matchDstMac +
+		  " inPort: " + matchInPort + " outPort: " + actionOutputPort
+		  );
+	try {
+	    messageDamper.write(mySwitch, fm, null);
+	    mySwitch.flush();
+	    //
+	    // TODO: We should use the OpenFlow Barrier mechanism
+	    // to check for errors, and update the SwitchState
+	    // for a flow entry after the Barrier message is
+	    // is received.
+	    //
+	    flowEntryObj.setSwitchState("FE_SWITCH_UPDATED");
+	} catch (IOException e) {
+	    log.error("Failure writing flow mod from network map", e);
+	    return false;
+	}
+
+	return true;
+    }
+
+    /**
+     * Install a Flow Entry on a switch.
+     *
+     * @param messageFactory the OpenFlow message factory to use.
+     * @maram messageDamper the OpenFlow message damper to use.
+     * @param mySwitch the switch to install the Flow Entry into.
+     * @param flowPath the flow path for the flow entry to install.
+     * @param flowEntry the flow entry to install.
+     * @return true on success, otherwise false.
+     */
+    static boolean installFlowEntry(BasicFactory messageFactory,
+				    OFMessageDamper messageDamper,
+				    IOFSwitch mySwitch, FlowPath flowPath,
+				    FlowEntry flowEntry) {
+	//
+	// Create the OpenFlow Flow Modification Entry to push
+	//
+	OFFlowMod fm = (OFFlowMod)messageFactory.getMessage(OFType.FLOW_MOD);
+	long cookie = flowEntry.flowEntryId().value();
+
+	short flowModCommand = OFFlowMod.OFPFC_ADD;
+	if (flowEntry.flowEntryUserState() == FlowEntryUserState.FE_USER_ADD) {
+	    flowModCommand = OFFlowMod.OFPFC_ADD;
+	} else if (flowEntry.flowEntryUserState() == FlowEntryUserState.FE_USER_MODIFY) {
+	    flowModCommand = OFFlowMod.OFPFC_MODIFY_STRICT;
+	} else if (flowEntry.flowEntryUserState() == FlowEntryUserState.FE_USER_DELETE) {
+	    flowModCommand = OFFlowMod.OFPFC_DELETE_STRICT;
+	} else {
+	    // Unknown user state. Ignore the entry
+	    log.debug("Flow Entry ignored (FlowEntryId = {}): unknown user state {}",
+		      flowEntry.flowEntryId().toString(),
+		      flowEntry.flowEntryUserState());
+	    return false;
+	}
+
+	//
+	// Fetch the match conditions.
+	//
+	// NOTE: The Flow matching conditions common for all Flow Entries are
+	// used ONLY if a Flow Entry does NOT have the corresponding matching
+	// condition set.
+	//
+	OFMatch match = new OFMatch();
+	match.setWildcards(OFMatch.OFPFW_ALL);
+	FlowEntryMatch flowPathMatch = flowPath.flowEntryMatch();
+	FlowEntryMatch flowEntryMatch = flowEntry.flowEntryMatch();
+
+	// Match the Incoming Port
+	Port matchInPort = flowEntryMatch.inPort();
+	if (matchInPort != null) {
+	    match.setInputPort(matchInPort.value());
+	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_IN_PORT);
+	}
+
+	// Match the Source MAC address
+	MACAddress matchSrcMac = flowEntryMatch.srcMac();
+	if ((matchSrcMac == null) && (flowPathMatch != null)) {
+	    matchSrcMac = flowPathMatch.srcMac();
+	}
+	if (matchSrcMac != null) {
+	    match.setDataLayerSource(matchSrcMac.toString());
+	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_SRC);
+	}
+
+	// Match the Destination MAC address
+	MACAddress matchDstMac = flowEntryMatch.dstMac();
+	if ((matchDstMac == null) && (flowPathMatch != null)) {
+	    matchDstMac = flowPathMatch.dstMac();
+	}
+	if (matchDstMac != null) {
+	    match.setDataLayerDestination(matchDstMac.toString());
+	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_DST);
+	}
+
+	// Match the Ethernet Frame Type
+	Short matchEthernetFrameType = flowEntryMatch.ethernetFrameType();
+	if ((matchEthernetFrameType == null) && (flowPathMatch != null)) {
+	    matchEthernetFrameType = flowPathMatch.ethernetFrameType();
+	}
+	if (matchEthernetFrameType != null) {
+	    match.setDataLayerType(matchEthernetFrameType);
+	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_TYPE);
+	}
+
+	// Match the VLAN ID
+	Short matchVlanId = flowEntryMatch.vlanId();
+	if ((matchVlanId == null) && (flowPathMatch != null)) {
+	    matchVlanId = flowPathMatch.vlanId();
+	}
+	if (matchVlanId != null) {
+	    match.setDataLayerVirtualLan(matchVlanId);
+	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_VLAN);
+	}
+
+	// Match the VLAN priority
+	Byte matchVlanPriority = flowEntryMatch.vlanPriority();
+	if ((matchVlanPriority == null) && (flowPathMatch != null)) {
+	    matchVlanPriority = flowPathMatch.vlanPriority();
+	}
+	if (matchVlanPriority != null) {
+	    match.setDataLayerVirtualLanPriorityCodePoint(matchVlanPriority);
+	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_VLAN_PCP);
+	}
+
+	// Match the Source IPv4 Network prefix
+	IPv4Net matchSrcIPv4Net = flowEntryMatch.srcIPv4Net();
+	if ((matchSrcIPv4Net == null) && (flowPathMatch != null)) {
+	    matchSrcIPv4Net = flowPathMatch.srcIPv4Net();
+	}
+	if (matchSrcIPv4Net != null) {
+	    match.setFromCIDR(matchSrcIPv4Net.toString(), OFMatch.STR_NW_SRC);
+	}
+
+	// Natch the Destination IPv4 Network prefix
+	IPv4Net matchDstIPv4Net = flowEntryMatch.dstIPv4Net();
+	if ((matchDstIPv4Net == null) && (flowPathMatch != null)) {
+	    matchDstIPv4Net = flowPathMatch.dstIPv4Net();
+	}
+	if (matchDstIPv4Net != null) {
+	    match.setFromCIDR(matchDstIPv4Net.toString(), OFMatch.STR_NW_DST);
+	}
+
+	// Match the IP protocol
+	Byte matchIpProto = flowEntryMatch.ipProto();
+	if ((matchIpProto == null) && (flowPathMatch != null)) {
+	    matchIpProto = flowPathMatch.ipProto();
+	}
+	if (matchIpProto != null) {
+	    match.setNetworkProtocol(matchIpProto);
+	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_NW_PROTO);
+	}
+
+	// Match the IP ToS (DSCP field, 6 bits)
+	Byte matchIpToS = flowEntryMatch.ipToS();
+	if ((matchIpToS == null) && (flowPathMatch != null)) {
+	    matchIpToS = flowPathMatch.ipToS();
+	}
+	if (matchIpToS != null) {
+	    match.setNetworkTypeOfService(matchIpToS);
+	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_NW_TOS);
+	}
+
+	// Match the Source TCP/UDP port
+	Short matchSrcTcpUdpPort = flowEntryMatch.srcTcpUdpPort();
+	if ((matchSrcTcpUdpPort == null) && (flowPathMatch != null)) {
+	    matchSrcTcpUdpPort = flowPathMatch.srcTcpUdpPort();
+	}
+	if (matchSrcTcpUdpPort != null) {
+	    match.setTransportSource(matchSrcTcpUdpPort);
+	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_TP_SRC);
+	}
+
+	// Match the Destination TCP/UDP port
+	Short matchDstTcpUdpPort = flowEntryMatch.dstTcpUdpPort();
+	if ((matchDstTcpUdpPort == null) && (flowPathMatch != null)) {
+	    matchDstTcpUdpPort = flowPathMatch.dstTcpUdpPort();
+	}
+	if (matchDstTcpUdpPort != null) {
+	    match.setTransportDestination(matchDstTcpUdpPort);
+	    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_TP_DST);
+	}
+
+	//
+	// Fetch the actions
+	//
+	Short actionOutputPort = null;
+	List<OFAction> openFlowActions = new ArrayList<OFAction>();
+	int actionsLen = 0;
+	FlowEntryActions flowEntryActions = flowEntry.flowEntryActions();
+	//
+	for (FlowEntryAction action : flowEntryActions.actions()) {
+	    ActionOutput actionOutput = action.actionOutput();
+	    ActionSetVlanId actionSetVlanId = action.actionSetVlanId();
+	    ActionSetVlanPriority actionSetVlanPriority = action.actionSetVlanPriority();
+	    ActionStripVlan actionStripVlan = action.actionStripVlan();
+	    ActionSetEthernetAddr actionSetEthernetSrcAddr = action.actionSetEthernetSrcAddr();
+	    ActionSetEthernetAddr actionSetEthernetDstAddr = action.actionSetEthernetDstAddr();
+	    ActionSetIPv4Addr actionSetIPv4SrcAddr = action.actionSetIPv4SrcAddr();
+	    ActionSetIPv4Addr actionSetIPv4DstAddr = action.actionSetIPv4DstAddr();
+	    ActionSetIpToS actionSetIpToS = action.actionSetIpToS();
+	    ActionSetTcpUdpPort actionSetTcpUdpSrcPort = action.actionSetTcpUdpSrcPort();
+	    ActionSetTcpUdpPort actionSetTcpUdpDstPort = action.actionSetTcpUdpDstPort();
+	    ActionEnqueue actionEnqueue = action.actionEnqueue();
+
+	    if (actionOutput != null) {
+		actionOutputPort = actionOutput.port().value();
+		// XXX: The max length is hard-coded for now
+		OFActionOutput ofa =
+		    new OFActionOutput(actionOutput.port().value(),
+				       (short)0xffff);
+		openFlowActions.add(ofa);
+		actionsLen += ofa.getLength();
+	    }
+
+	    if (actionSetVlanId != null) {
+		OFActionVirtualLanIdentifier ofa =
+		    new OFActionVirtualLanIdentifier(actionSetVlanId.vlanId());
+		openFlowActions.add(ofa);
+		actionsLen += ofa.getLength();
+	    }
+
+	    if (actionSetVlanPriority != null) {
+		OFActionVirtualLanPriorityCodePoint ofa =
+		    new OFActionVirtualLanPriorityCodePoint(actionSetVlanPriority.vlanPriority());
+		openFlowActions.add(ofa);
+		actionsLen += ofa.getLength();
+	    }
+
+	    if (actionStripVlan != null) {
+		if (actionStripVlan.stripVlan() == true) {
+		    OFActionStripVirtualLan ofa = new OFActionStripVirtualLan();
+		    openFlowActions.add(ofa);
+		    actionsLen += ofa.getLength();
+		}
+	    }
+
+	    if (actionSetEthernetSrcAddr != null) {
+		OFActionDataLayerSource ofa = 
+		    new OFActionDataLayerSource(actionSetEthernetSrcAddr.addr().toBytes());
+		openFlowActions.add(ofa);
+		actionsLen += ofa.getLength();
+	    }
+
+	    if (actionSetEthernetDstAddr != null) {
+		OFActionDataLayerDestination ofa =
+		    new OFActionDataLayerDestination(actionSetEthernetDstAddr.addr().toBytes());
+		openFlowActions.add(ofa);
+		actionsLen += ofa.getLength();
+	    }
+
+	    if (actionSetIPv4SrcAddr != null) {
+		OFActionNetworkLayerSource ofa =
+		    new OFActionNetworkLayerSource(actionSetIPv4SrcAddr.addr().value());
+		openFlowActions.add(ofa);
+		actionsLen += ofa.getLength();
+	    }
+
+	    if (actionSetIPv4DstAddr != null) {
+		OFActionNetworkLayerDestination ofa =
+		    new OFActionNetworkLayerDestination(actionSetIPv4DstAddr.addr().value());
+		openFlowActions.add(ofa);
+		actionsLen += ofa.getLength();
+	    }
+
+	    if (actionSetIpToS != null) {
+		OFActionNetworkTypeOfService ofa =
+		    new OFActionNetworkTypeOfService(actionSetIpToS.ipToS());
+		openFlowActions.add(ofa);
+		actionsLen += ofa.getLength();
+	    }
+
+	    if (actionSetTcpUdpSrcPort != null) {
+		OFActionTransportLayerSource ofa =
+		    new OFActionTransportLayerSource(actionSetTcpUdpSrcPort.port());
+		openFlowActions.add(ofa);
+		actionsLen += ofa.getLength();
+	    }
+
+	    if (actionSetTcpUdpDstPort != null) {
+		OFActionTransportLayerDestination ofa =
+		    new OFActionTransportLayerDestination(actionSetTcpUdpDstPort.port());
+		openFlowActions.add(ofa);
+		actionsLen += ofa.getLength();
+	    }
+
+	    if (actionEnqueue != null) {
+		OFActionEnqueue ofa =
+		    new OFActionEnqueue(actionEnqueue.port().value(),
+					actionEnqueue.queueId());
+		openFlowActions.add(ofa);
+		actionsLen += ofa.getLength();
+	    }
+	}
+
+	fm.setIdleTimeout(FLOWMOD_DEFAULT_IDLE_TIMEOUT)
+	    .setHardTimeout(FLOWMOD_DEFAULT_HARD_TIMEOUT)
+	    .setPriority(PRIORITY_DEFAULT)
+	    .setBufferId(OFPacketOut.BUFFER_ID_NONE)
+	    .setCookie(cookie)
+	    .setCommand(flowModCommand)
+	    .setMatch(match)
+	    .setActions(openFlowActions)
+	    .setLengthU(OFFlowMod.MINIMUM_LENGTH + actionsLen);
+	fm.setOutPort(OFPort.OFPP_NONE.getValue());
+	if ((flowModCommand == OFFlowMod.OFPFC_DELETE) ||
+	    (flowModCommand == OFFlowMod.OFPFC_DELETE_STRICT)) {
+	    if (actionOutputPort != null)
+		fm.setOutPort(actionOutputPort);
+	}
+
+	//
+	// TODO: Set the following flag
+	// fm.setFlags(OFFlowMod.OFPFF_SEND_FLOW_REM);
+	// See method ForwardingBase::pushRoute()
+	//
+
+	//
+	// Write the message to the switch
+	//
+	try {
+	    messageDamper.write(mySwitch, fm, null);
+	    mySwitch.flush();
+	    //
+	    // TODO: We should use the OpenFlow Barrier mechanism
+	    // to check for errors, and update the SwitchState
+	    // for a flow entry after the Barrier message is
+	    // is received.
+	    //
+	    // TODO: The FlowEntry Object in Titan should be set
+	    // to FE_SWITCH_UPDATED.
+	    //
+	} catch (IOException e) {
+	    log.error("Failure writing flow mod from network map", e);
+	    return false;
+	}
+	return true;
+    }
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/IFlowService.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/IFlowService.java
index df11d6b..73f86b6 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/IFlowService.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/IFlowService.java
@@ -67,6 +67,13 @@
     FlowPath getFlow(FlowId flowId);
 
     /**
+     * Get all installed flows by all installers.
+     *
+     * @return the Flow Paths if found, otherwise null.
+     */
+    ArrayList<FlowPath> getAllFlows();
+
+    /**
      * Get all previously added flows by a specific installer for a given
      * data path endpoints.
      *
@@ -95,13 +102,6 @@
     ArrayList<IFlowPath> getAllFlowsSummary(FlowId flowId, int maxFlows);
     
     /**
-     * Get all installed flows by all installers.
-     *
-     * @return the Flow Paths if found, otherwise null.
-     */
-    ArrayList<FlowPath> getAllFlows();
-
-    /**
      * Add and maintain a shortest-path flow.
      *
      * NOTE: The Flow Path argument does NOT contain all flow entries.
diff --git a/src/main/java/net/onrc/onos/ofcontroller/topology/ITopologyNetService.java b/src/main/java/net/onrc/onos/ofcontroller/topology/ITopologyNetService.java
index bd0ca38..9585366 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/topology/ITopologyNetService.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/topology/ITopologyNetService.java
@@ -11,73 +11,72 @@
  */
 public interface ITopologyNetService extends IFloodlightService {
     /**
-     * Get the shortest path from a source to a destination.
-     *
-     * @param src the source in the shortest path computation.
-     * @param dest the destination in the shortest path computation.
-     * @return the data path with the computed shortest path if
-     * found, otherwise null.
-     */
-    DataPath getShortestPath(SwitchPort src, SwitchPort dest);
-
-    /**
      * Fetch the Switch and Ports info from the Titan Graph
      * and return it for fast access during the shortest path
      * computation.
      *
-     * After fetching the state, method @ref getTopoShortestPath()
+     * After fetching the state, method @ref getTopologyShortestPath()
      * can be used for fast shortest path computation.
      *
      * Note: There is certain cost to fetch the state, hence it should
      * be used only when there is a large number of shortest path
      * computations that need to be done on the same topology.
-     * Typically, a single call to @ref prepareShortestPathTopo()
+     * Typically, a single call to @ref newDatabaseTopology()
      * should be followed by a large number of calls to
-     * method @ref getTopoShortestPath().
-     * After the last @ref getTopoShortestPath() call,
-     * method @ref dropShortestPathTopo() should be used to release
+     * method @ref getTopologyShortestPath().
+     * After the last @ref getTopologyShortestPath() call,
+     * method @ref dropTopology() should be used to release
      * the internal state that is not needed anymore:
      *
-     *       Map<Long, ?> shortestPathTopo;
-     *       shortestPathTopo = prepareShortestPathTopo();
+     *       Topology topology = topologyManager.newDatabaseTopology();
      *       for (int i = 0; i < 10000; i++) {
-     *           dataPath = getTopoShortestPath(shortestPathTopo, ...);
+     *           dataPath = topologyManager.getTopologyShortestPath(topology, ...);
      *           ...
      *        }
-     *        dropShortestPathTopo(shortestPathTopo);
+     *        topologyManager.dropTopology(shortestPathTopo);
      *
-     * @return the Shortest Path info handler stored in a map.
+     * @return the allocated topology handler.
      */
-    Map<Long, ?> prepareShortestPathTopo();
+    Topology newDatabaseTopology();
 
     /**
-     * Release the state that was populated by
-     * method @ref prepareShortestPathTopo().
+     * Release the topology that was populated by
+     * method @ref newDatabaseTopology().
      *
-     * See the documentation for method @ref prepareShortestPathTopo()
+     * See the documentation for method @ref newDatabaseTopology()
      * for additional information and usage.
      *
-     * @param shortestPathTopo the Shortest Path info handler to release.
+     * @param topology the topology to release.
      */
-    void dropShortestPathTopo(Map<Long, ?> shortestPathTopo);
+    void dropTopology(Topology topology);
 
     /**
      * Get the shortest path from a source to a destination by
      * using the pre-populated local topology state prepared
-     * by method @ref prepareShortestPathTopo().
+     * by method @ref newDatabaseTopology().
      *
-     * See the documentation for method @ref prepareShortestPathTopo()
+     * See the documentation for method @ref newDatabaseTopology()
      * for additional information and usage.
      *
-     * @param shortestPathTopo the Shortest Path info handler
-     * to use.
+     * @param topology the topology handler to use.
      * @param src the source in the shortest path computation.
      * @param dest the destination in the shortest path computation.
      * @return the data path with the computed shortest path if
      * found, otherwise null.
      */
-    DataPath getTopoShortestPath(Map<Long, ?> shortestPathTopo,
-				 SwitchPort src, SwitchPort dest);
+    DataPath getTopologyShortestPath(Topology topology,
+				     SwitchPort src, SwitchPort dest);
+
+    /**
+     * Get the shortest path from a source to a destination by using
+     * the underlying database.
+     *
+     * @param src the source in the shortest path computation.
+     * @param dest the destination in the shortest path computation.
+     * @return the data path with the computed shortest path if
+     * found, otherwise null.
+     */
+    DataPath getDatabaseShortestPath(SwitchPort src, SwitchPort dest);
 
     /**
      * Test whether a route exists from a source to a destination.
diff --git a/src/main/java/net/onrc/onos/ofcontroller/topology/ShortestPath.java b/src/main/java/net/onrc/onos/ofcontroller/topology/ShortestPath.java
new file mode 100644
index 0000000..1133d3d
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/topology/ShortestPath.java
@@ -0,0 +1,325 @@
+package net.onrc.onos.ofcontroller.topology;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Set;
+
+import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
+import net.onrc.onos.ofcontroller.util.DataPath;
+import net.onrc.onos.ofcontroller.util.Dpid;
+import net.onrc.onos.ofcontroller.util.FlowEntry;
+import net.onrc.onos.ofcontroller.util.Port;
+import net.onrc.onos.ofcontroller.util.SwitchPort;
+
+import org.openflow.util.HexString;
+
+import com.tinkerpop.blueprints.Direction;
+import com.tinkerpop.blueprints.Vertex;
+
+/**
+ * A class for implementing the Shortest Path in a topology.
+ */
+public class ShortestPath {
+    /**
+     * Get the shortest path from a source to a destination by
+     * using the pre-populated local topology state prepared
+     * by method @ref TopologyManager.newDatabaseTopology().
+     *
+     * For additional documentation and usage, see method
+     * @ref TopologyManager.newDatabaseTopology()
+     *
+     * @param topology the topology handler to use.
+     * @param src the source in the shortest path computation.
+     * @param dest the destination in the shortest path computation.
+     * @return the data path with the computed shortest path if
+     * found, otherwise null.
+     */
+    public static DataPath getTopologyShortestPath(
+		Topology topology,
+		SwitchPort src, SwitchPort dest) {
+	DataPath result_data_path = new DataPath();
+
+	// Initialize the source and destination in the data path to return
+	result_data_path.setSrcPort(src);
+	result_data_path.setDstPort(dest);
+
+	String dpid_src = src.dpid().toString();
+	String dpid_dest = dest.dpid().toString();
+
+	// Get the source vertex
+	Node v_src = topology.getNode(src.dpid().value());
+	if (v_src == null) {
+	    return null;		// Source vertex not found
+	}
+
+	// Get the destination vertex
+	Node v_dest = topology.getNode(dest.dpid().value());
+	if (v_dest == null) {
+	    return null;		// Destination vertex not found
+	}
+
+	//
+	// Test whether we are computing a path from/to the same DPID.
+	// If "yes", then just add a single flow entry in the return result.
+	//
+	if (dpid_src.equals(dpid_dest)) {
+	    FlowEntry flowEntry = new FlowEntry();
+	    flowEntry.setDpid(src.dpid());
+	    flowEntry.setInPort(src.port());
+	    flowEntry.setOutPort(dest.port());
+	    result_data_path.flowEntries().add(flowEntry);
+	    return result_data_path;
+	}
+
+	//
+	// Implement the Shortest Path computation by using Breath First Search
+	//
+	Set<Node> visitedSet = new HashSet<Node>();
+	Queue<Node> processingList = new LinkedList<Node>();
+	Map<Node, Node.Link> previousVertexMap = new HashMap<Node, Node.Link>();
+	processingList.add(v_src);
+	visitedSet.add(v_src);
+	Boolean path_found = false;
+	while (! processingList.isEmpty()) {
+	    Node nextVertex = processingList.poll();
+	    if (v_dest == nextVertex) {
+		path_found = true;
+		break;
+	    }
+	    for (Node.Link link : nextVertex.links.values()) {
+		Node child = link.neighbor;
+		if (! visitedSet.contains(child)) {
+		    previousVertexMap.put(child, link);
+		    visitedSet.add(child);
+		    processingList.add(child);
+		}
+	    }
+	}
+	if (! path_found)
+	    return null;		// No path found
+
+	// Collect the path as a list of links
+	List<Node.Link> resultPath = new LinkedList<Node.Link>();
+	Node previousVertex = v_dest;
+	while (! v_src.equals(previousVertex)) {
+	    Node.Link currentLink = previousVertexMap.get(previousVertex);
+	    resultPath.add(currentLink);
+	    previousVertex = currentLink.me;
+	}
+	Collections.reverse(resultPath);
+
+	//
+	// Loop through the result and prepare the return result
+	// as a list of Flow Entries.
+	//
+	Port inPort = new Port(src.port().value());
+	Port outPort;
+	for (Node.Link link: resultPath) {
+	    // Setup the outgoing port, and add the Flow Entry
+	    outPort = new Port(link.myPort);
+
+	    FlowEntry flowEntry = new FlowEntry();
+	    flowEntry.setDpid(new Dpid(link.me.nodeId));
+	    flowEntry.setInPort(inPort);
+	    flowEntry.setOutPort(outPort);
+	    result_data_path.flowEntries().add(flowEntry);
+
+	    // Setup the next incoming port
+	    inPort = new Port(link.neighborPort);
+	}
+	if (resultPath.size() > 0) {
+	    // Add the last Flow Entry
+	    FlowEntry flowEntry = new FlowEntry();
+	    flowEntry.setDpid(new Dpid(dest.dpid().value()));
+	    flowEntry.setInPort(inPort);
+	    flowEntry.setOutPort(dest.port());
+	    result_data_path.flowEntries().add(flowEntry);
+	}
+
+	if (result_data_path.flowEntries().size() > 0)
+	    return result_data_path;
+
+	return null;
+    }
+
+    /**
+     * Get the shortest path from a source to a destination by using
+     * the underlying Graph Database.
+     *
+     * @param dbHandler the Graph Database handler to use.
+     * @param src the source in the shortest path computation.
+     * @param dest the destination in the shortest path computation.
+     * @return the data path with the computed shortest path if
+     * found, otherwise null.
+     */
+    public static DataPath getDatabaseShortestPath(GraphDBOperation dbHandler,
+					     SwitchPort src, SwitchPort dest) {
+	DataPath result_data_path = new DataPath();
+
+	// Initialize the source and destination in the data path to return
+	result_data_path.setSrcPort(src);
+	result_data_path.setDstPort(dest);
+
+	String dpid_src = src.dpid().toString();
+	String dpid_dest = dest.dpid().toString();
+
+	// Get the source and destination switches
+	ISwitchObject srcSwitch =
+	    dbHandler.searchActiveSwitch(dpid_src);
+	ISwitchObject destSwitch =
+	    dbHandler.searchActiveSwitch(dpid_dest);
+	if (srcSwitch == null || destSwitch == null) {
+	    return null;
+	}
+
+	//
+	// Test whether we are computing a path from/to the same DPID.
+	// If "yes", then just add a single flow entry in the return result.
+	//
+	if (dpid_src.equals(dpid_dest)) {
+	    FlowEntry flowEntry = new FlowEntry();
+	    flowEntry.setDpid(src.dpid());
+	    flowEntry.setInPort(src.port());
+	    flowEntry.setOutPort(dest.port());
+	    result_data_path.flowEntries().add(flowEntry);
+	    dbHandler.commit();
+	    return result_data_path;
+	}
+
+	Vertex v_src = srcSwitch.asVertex();	
+	Vertex v_dest = destSwitch.asVertex();
+
+	//
+	// Implement the Shortest Path computation by using Breath First Search
+	//
+	Set<Vertex> visitedSet = new HashSet<Vertex>();
+	Queue<Vertex> processingList = new LinkedList<Vertex>();
+	Map<Vertex, Vertex> previousVertexMap = new HashMap<Vertex, Vertex>();
+
+	processingList.add(v_src);
+	visitedSet.add(v_src);
+	Boolean path_found = false;
+	while (! processingList.isEmpty()) {
+	    Vertex nextVertex = processingList.poll();
+	    if (v_dest.equals(nextVertex)) {
+		path_found = true;
+		break;
+	    }
+	    for (Vertex parentPort : nextVertex.getVertices(Direction.OUT, "on")) {
+		// Ignore inactive ports
+		if (! parentPort.getProperty("state").toString().equals("ACTIVE"))
+			continue;
+
+		for (Vertex childPort : parentPort.getVertices(Direction.OUT, "link")) {
+		    // Ignore inactive ports
+		    if (! childPort.getProperty("state").toString().equals("ACTIVE"))
+			continue;
+
+		    for (Vertex child : childPort.getVertices(Direction.IN, "on")) {
+			// Ignore inactive switches
+			String state = child.getProperty("state").toString();
+			if (! state.equals(SwitchState.ACTIVE.toString()))
+			    continue;
+
+			if (! visitedSet.contains(child)) {
+			    previousVertexMap.put(parentPort, nextVertex);
+			    previousVertexMap.put(childPort, parentPort);
+			    previousVertexMap.put(child, childPort);
+			    visitedSet.add(child);
+			    processingList.add(child);
+			}
+		    }
+		}
+	    }
+	}
+	if (! path_found)
+	    return null;		// No path found
+
+	List<Vertex> resultPath = new LinkedList<Vertex>();
+	Vertex previousVertex = v_dest;
+	resultPath.add(v_dest);
+	while (! v_src.equals(previousVertex)) {
+	    Vertex currentVertex = previousVertexMap.get(previousVertex);
+	    resultPath.add(currentVertex);
+	    previousVertex = currentVertex;
+	}
+	Collections.reverse(resultPath);
+
+
+	//
+	// Loop through the result and prepare the return result
+	// as a list of Flow Entries.
+	//
+	long nodeId = 0;
+	short portId = 0;
+	Port inPort = new Port(src.port().value());
+	Port outPort = new Port();
+	int idx = 0;
+	for (Vertex v: resultPath) {
+	    String type = v.getProperty("type").toString();
+	    // System.out.println("type: " + type);
+	    if (type.equals("port")) {
+		//String number = v.getProperty("number").toString();
+		// System.out.println("number: " + number);
+
+		Object obj = v.getProperty("number");
+		// String class_str = obj.getClass().toString();
+		if (obj instanceof Short) {
+		    portId = (Short)obj;
+		} else if (obj instanceof Integer) {
+		    Integer int_nodeId = (Integer)obj;
+		    portId = int_nodeId.shortValue();
+		    // int int_nodeId = (Integer)obj;
+		    // portId = (short)int_nodeId.;
+		}
+	    } else if (type.equals("switch")) {
+		String dpid = v.getProperty("dpid").toString();
+		nodeId = HexString.toLong(dpid);
+
+		// System.out.println("dpid: " + dpid);
+	    }
+	    idx++;
+	    if (idx == 1) {
+		continue;
+	    }
+	    int mod = idx % 3;
+	    if (mod == 0) {
+		// Setup the incoming port
+		inPort = new Port(portId);
+		continue;
+	    }
+	    if (mod == 2) {
+		// Setup the outgoing port, and add the Flow Entry
+		outPort = new Port(portId);
+
+		FlowEntry flowEntry = new FlowEntry();
+		flowEntry.setDpid(new Dpid(nodeId));
+		flowEntry.setInPort(inPort);
+		flowEntry.setOutPort(outPort);
+		result_data_path.flowEntries().add(flowEntry);
+		continue;
+	    }
+	}
+	if (idx > 0) {
+	    // Add the last Flow Entry
+	    FlowEntry flowEntry = new FlowEntry();
+	    flowEntry.setDpid(new Dpid(nodeId));
+	    flowEntry.setInPort(inPort);
+	    flowEntry.setOutPort(dest.port());
+	    result_data_path.flowEntries().add(flowEntry);
+	}
+
+	dbHandler.commit();
+	if (result_data_path.flowEntries().size() > 0)
+	    return result_data_path;
+
+	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
new file mode 100644
index 0000000..a2f2c21
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/topology/Topology.java
@@ -0,0 +1,174 @@
+package net.onrc.onos.ofcontroller.topology;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
+
+import org.openflow.util.HexString;
+
+import com.tinkerpop.blueprints.Direction;
+import com.tinkerpop.blueprints.Vertex;
+
+/**
+ * A class for storing Node and Link information for fast computation
+ * of shortest paths.
+ */
+class Node {
+    /**
+     * A class for storing Link information for fast computation of shortest
+     * paths.
+     */
+    class Link {
+	public Node me;			// The node this link originates from
+	public Node neighbor;		// The neighbor node on the other side
+	public short myPort;		// Local port number for the link
+	public short neighborPort;	// Neighbor port number 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 number for the link.
+	 * @param neighborPort neighrobr port number for the link.
+	 */
+	public Link(Node me, Node neighbor, short myPort, short neighborPort) {
+	    this.me = me;
+	    this.neighbor = neighbor;
+	    this.myPort = myPort;
+	    this.neighborPort = neighborPort;
+	}
+    };
+
+    public long nodeId;			// The node ID
+    public HashMap<Short, Link> links;	// The links originating from this node
+
+    /**
+     * Node constructor.
+     *
+     * @param nodeId the node ID.
+     */
+    public Node(long nodeId) {
+	this.nodeId = nodeId;
+	links = new HashMap<Short, Link>();
+    }
+
+    /**
+     * Add a neighbor.
+     *
+     * A new link to the neighbor will be created. 
+     *
+     * @param neighbor the neighbor to add.
+     * @param myPort the local port number for the link to the neighbor.
+     * @param neighborPort the neighbor port number for the link.
+     */
+    public void addNeighbor(Node neighbor, short myPort, short neighborPort) {
+	Link link = new Link(this, neighbor, myPort, neighborPort);
+	links.put(myPort, link);
+    }
+};
+
+/**
+ * A class for storing topology information.
+ */
+public class Topology {
+    private Map<Long, Node> nodesMap;	// The dpid->Node mapping
+
+    public Topology() {
+	nodesMap = new HashMap<Long, Node>();
+    }
+
+    /**
+     * Get a node for a give Node ID.
+     *
+     * @param nodeId the Node ID to use.
+     * @return the corresponding Node if found, otherwise null.
+     */
+    Node getNode(long nodeId) {
+	return nodesMap.get(nodeId);
+    }
+
+    /**
+     * Read topology state from the database.
+     *
+     * @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 = new Node(nodeId);
+		nodesMap.put(nodeId, me);
+	    }
+
+	    //
+	    // The local Port info
+	    //
+	    for (Vertex myPortVertex : nodeVertex.getVertices(Direction.OUT, "on")) {
+		// Ignore inactive ports
+		if (! myPortVertex.getProperty("state").toString().equals("ACTIVE"))
+		    continue;
+
+		short myPort = 0;
+		Object obj = myPortVertex.getProperty("number");
+		if (obj instanceof Short) {
+		    myPort = (Short)obj;
+		} else if (obj instanceof Integer) {
+		    Integer int_nodeId = (Integer)obj;
+		    myPort = int_nodeId.shortValue();
+		}
+
+		//
+		// The neighbor Port info
+		//
+		for (Vertex neighborPortVertex : myPortVertex.getVertices(Direction.OUT, "link")) {
+		    // Ignore inactive ports
+		    if (! neighborPortVertex.getProperty("state").toString().equals("ACTIVE"))
+			continue;
+
+		    short neighborPort = 0;
+		    obj = neighborPortVertex.getProperty("number");
+		    if (obj instanceof Short) {
+			neighborPort = (Short)obj;
+		    } else if (obj instanceof Integer) {
+			Integer int_nodeId = (Integer)obj;
+			neighborPort = int_nodeId.shortValue();
+		    }
+		    //
+		    // 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;
+
+			String neighborDpid = neighborVertex.getProperty("dpid").toString();
+			long neighborId = HexString.toLong(neighborDpid);
+			Node neighbor = nodesMap.get(neighborId);
+			if (neighbor == null) {
+			    neighbor = new Node(neighborId);
+			    nodesMap.put(neighborId, neighbor);
+			}
+			me.addNeighbor(neighbor, myPort, neighborPort);
+		    }
+		}
+	    }
+	}
+	dbHandler.commit();
+    }
+}
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 618ae39..81ff599 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/topology/TopologyManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/topology/TopologyManager.java
@@ -1,99 +1,34 @@
 package net.onrc.onos.ofcontroller.topology;
 
-import java.util.Collections;
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
 import java.util.Map;
-import java.util.Queue;
-import java.util.Set;
 
+import net.floodlightcontroller.core.IFloodlightProviderService;
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.core.module.FloodlightModuleException;
+import net.floodlightcontroller.core.module.IFloodlightModule;
+import net.floodlightcontroller.core.module.IFloodlightService;
+
+import net.onrc.onos.datagrid.IDatagridService;
 import net.onrc.onos.graph.GraphDBOperation;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
-import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
+import net.onrc.onos.ofcontroller.floodlightlistener.INetworkGraphService;
 import net.onrc.onos.ofcontroller.util.DataPath;
-import net.onrc.onos.ofcontroller.util.Dpid;
-import net.onrc.onos.ofcontroller.util.FlowEntry;
-import net.onrc.onos.ofcontroller.util.Port;
 import net.onrc.onos.ofcontroller.util.SwitchPort;
 
-import org.openflow.util.HexString;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.tinkerpop.blueprints.Direction;
-import com.tinkerpop.blueprints.Vertex;
-
-
-/**
- * A class for storing Node and Link information for fast computation
- * of shortest paths.
- */
-class Node {
-    /**
-     * A class for storing Link information for fast computation of shortest
-     * paths.
-     */
-    class Link {
-	public Node me;			// The node this link originates from
-	public Node neighbor;		// The neighbor node on the other side
-	public short myPort;		// Local port number for the link
-	public short neighborPort;	// Neighbor port number 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 number for the link.
-	 * @param neighborPort neighrobr port number for the link.
-	 */
-	public Link(Node me, Node neighbor, short myPort, short neighborPort) {
-	    this.me = me;
-	    this.neighbor = neighbor;
-	    this.myPort = myPort;
-	    this.neighborPort = neighborPort;
-	}
-    };
-
-    public long nodeId;			// The node ID
-    public HashMap<Short, Link> links;	// The links originating from this node
-
-    /**
-     * Node constructor.
-     *
-     * @param nodeId the node ID.
-     */
-    public Node(long nodeId) {
-	this.nodeId = nodeId;
-	links = new HashMap<Short, Link>();
-    }
-
-    /**
-     * Add a neighbor.
-     *
-     * A new link to the neighbor will be created. 
-     *
-     * @param neighbor the neighbor to add.
-     * @param myPort the local port number for the link to the neighbor.
-     * @param neighborPort the neighbor port number for the link.
-     */
-    public void addNeighbor(Node neighbor, short myPort, short neighborPort) {
-	Link link = new Link(this, neighbor, myPort, neighborPort);
-	links.put(myPort, link);
-    }
-};
-
 /**
  * A class for implementing Topology Network Service.
  */
-public class TopologyManager implements ITopologyNetService {
-
-    /** The logger. */
+public class TopologyManager implements IFloodlightModule,
+					ITopologyNetService {
     private static Logger log = LoggerFactory.getLogger(TopologyManager.class);
-    
-    protected GraphDBOperation op;
+    protected IFloodlightProviderService floodlightProvider;
+
+    protected GraphDBOperation dbHandler;
 
 
     /**
@@ -113,6 +48,16 @@
     }
 
     /**
+     * Constructor for a given database operation handler.
+     *
+     * @param dbHandler the database operation handler to use for the
+     * initialization.
+     */
+    public TopologyManager(GraphDBOperation dbHandler) {
+	this.dbHandler = dbHandler;
+    }
+
+    /**
      * Init the module.
      *
      * @param config the database configuration file to use for
@@ -120,27 +65,93 @@
      */
     public void init(String config) {
 	try {
-	    op = new GraphDBOperation(config);
+	    dbHandler = new GraphDBOperation(config);
 	} catch (Exception e) {
 	    log.error(e.getMessage());
 	}
     }
 
     /**
-     * Close the service. It will close the corresponding database connection.
+     * Shutdown the Topology Manager operation.
      */
-    public void close() {
-	op.close();
+    public void finalize() {
+	close();
     }
 
     /**
-     * Set the database operation handler.
-     *
-     * @param init_op the database operation handler to use for the
-     * initialization.
+     * Close the service. It will close the corresponding database connection.
      */
-    public void setDbOperationHandler(GraphDBOperation init_op) {
-    	op = init_op;
+    public void close() {
+	dbHandler.close();
+    }
+
+    /**
+     * Get the collection of offered module services.
+     *
+     * @return the collection of offered module services.
+     */
+    @Override
+    public Collection<Class<? extends IFloodlightService>> getModuleServices() {
+        Collection<Class<? extends IFloodlightService>> l = 
+            new ArrayList<Class<? extends IFloodlightService>>();
+        l.add(ITopologyNetService.class);
+        return l;
+    }
+
+    /**
+     * Get the collection of implemented services.
+     *
+     * @return the collection of implemented services.
+     */
+    @Override
+    public Map<Class<? extends IFloodlightService>, IFloodlightService> 
+			       getServiceImpls() {
+        Map<Class<? extends IFloodlightService>,
+	    IFloodlightService> m = 
+            new HashMap<Class<? extends IFloodlightService>,
+	    IFloodlightService>();
+        m.put(ITopologyNetService.class, this);
+        return m;
+    }
+
+    /**
+     * Get the collection of modules this module depends on.
+     *
+     * @return the collection of modules this module depends on.
+     */
+    @Override
+    public Collection<Class<? extends IFloodlightService>> 
+                                                    getModuleDependencies() {
+	Collection<Class<? extends IFloodlightService>> l =
+	    new ArrayList<Class<? extends IFloodlightService>>();
+	l.add(IFloodlightProviderService.class);
+	l.add(INetworkGraphService.class);
+	l.add(IDatagridService.class);
+        return l;
+    }
+
+    /**
+     * Initialize the module.
+     *
+     * @param context the module context to use for the initialization.
+     */
+    @Override
+    public void init(FloodlightModuleContext context)
+	throws FloodlightModuleException {
+	floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
+
+	String conf = "";
+	this.init(conf);
+    }
+
+    /**
+     * Startup module operation.
+     *
+     * @param context the module context to use for the startup.
+     */
+    @Override
+    public void startUp(FloodlightModuleContext context) {
+
     }
 
     /**
@@ -148,248 +159,70 @@
      * and return it for fast access during the shortest path
      * computation.
      *
-     * After fetching the state, method @ref getTopoShortestPath()
+     * After fetching the state, method @ref getTopologyShortestPath()
      * can be used for fast shortest path computation.
      *
      * Note: There is certain cost to fetch the state, hence it should
      * be used only when there is a large number of shortest path
      * computations that need to be done on the same topology.
-     * Typically, a single call to @ref prepareShortestPathTopo()
+     * Typically, a single call to @ref newDatabaseTopology()
      * should be followed by a large number of calls to
-     * method @ref getTopoShortestPath().
-     * After the last @ref getTopoShortestPath() call,
-     * method @ref dropShortestPathTopo() should be used to release
+     * method @ref getTopologyShortestPath().
+     * After the last @ref getTopologyShortestPath() call,
+     * method @ref dropTopology() should be used to release
      * the internal state that is not needed anymore:
      *
-     *       Map<Long, ?> shortestPathTopo;
-     *       shortestPathTopo = prepareShortestPathTopo();
+     *       Topology topology = topologyManager.newDatabaseTopology();
      *       for (int i = 0; i < 10000; i++) {
-     *           dataPath = getTopoShortestPath(shortestPathTopo, ...);
+     *           dataPath = topologyManager.getTopologyShortestPath(topology, ...);
      *           ...
      *        }
-     *        dropShortestPathTopo(shortestPathTopo);
+     *        topologyManager.dropTopology(shortestPathTopo);
      *
-     * @return the Shortest Path info handler stored in a map.
+     * @return the allocated topology handler.
      */
-    public Map<Long, ?> prepareShortestPathTopo() {
-	Map<Long, Node> shortestPathTopo = new HashMap<Long, Node>();
+    public Topology newDatabaseTopology() {
+	Topology topology = new Topology();
+	topology.readFromDatabase(dbHandler);
 
-	//
-	// Fetch the relevant info from the Switch and Port vertices
-	// from the Titan Graph.
-	//
-	Iterable<ISwitchObject> nodes = op.getActiveSwitches();
-	for (ISwitchObject switchObj : nodes) {
-	    Vertex nodeVertex = switchObj.asVertex();
-	    //
-	    // The Switch info
-	    //
-	    String nodeDpid = nodeVertex.getProperty("dpid").toString();
-	    long nodeId = HexString.toLong(nodeDpid);
-	    Node me = shortestPathTopo.get(nodeId);
-	    if (me == null) {
-		me = new Node(nodeId);
-		shortestPathTopo.put(nodeId, me);
-	    }
-
-	    //
-	    // The local Port info
-	    //
-	    for (Vertex myPortVertex : nodeVertex.getVertices(Direction.OUT, "on")) {
-		// Ignore inactive ports
-		if (! myPortVertex.getProperty("state").toString().equals("ACTIVE"))
-		    continue;
-
-		short myPort = 0;
-		Object obj = myPortVertex.getProperty("number");
-		if (obj instanceof Short) {
-		    myPort = (Short)obj;
-		} else if (obj instanceof Integer) {
-		    Integer int_nodeId = (Integer)obj;
-		    myPort = int_nodeId.shortValue();
-		}
-
-		//
-		// The neighbor Port info
-		//
-		for (Vertex neighborPortVertex : myPortVertex.getVertices(Direction.OUT, "link")) {
-		    // Ignore inactive ports
-		    if (! neighborPortVertex.getProperty("state").toString().equals("ACTIVE"))
-			continue;
-
-		    short neighborPort = 0;
-		    obj = neighborPortVertex.getProperty("number");
-		    if (obj instanceof Short) {
-			neighborPort = (Short)obj;
-		    } else if (obj instanceof Integer) {
-			Integer int_nodeId = (Integer)obj;
-			neighborPort = int_nodeId.shortValue();
-		    }
-		    //
-		    // 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;
-
-			String neighborDpid = neighborVertex.getProperty("dpid").toString();
-			long neighborId = HexString.toLong(neighborDpid);
-			Node neighbor = shortestPathTopo.get(neighborId);
-			if (neighbor == null) {
-			    neighbor = new Node(neighborId);
-			    shortestPathTopo.put(neighborId, neighbor);
-			}
-			me.addNeighbor(neighbor, myPort, neighborPort);
-		    }
-		}
-	    }
-	}
-	op.commit();
-
-	return shortestPathTopo;
+	return topology;
     }
 
     /**
-     * Release the state that was populated by
-     * method @ref prepareShortestPathTopo().
+     * Release the topology that was populated by
+     * method @ref newDatabaseTopology().
      *
-     * See the documentation for method @ref prepareShortestPathTopo()
+     * See the documentation for method @ref newDatabaseTopology()
      * for additional information and usage.
      *
-     * @param shortestPathTopo the Shortest Path info handler to release.
+     * @param topology the topology to release.
      */
-    public void dropShortestPathTopo(Map<Long, ?> shortestPathTopo) {
-	shortestPathTopo = null;
+    public void dropTopology(Topology topology) {
+	topology = null;
     }
 
     /**
      * Get the shortest path from a source to a destination by
      * using the pre-populated local topology state prepared
-     * by method @ref prepareShortestPathTopo().
+     * by method @ref newDatabaseTopology().
      *
-     * See the documentation for method @ref prepareShortestPathTopo()
+     * See the documentation for method @ref newDatabaseTopology()
      * for additional information and usage.
      *
-     * @param shortestPathTopoHandler the Shortest Path info handler
-     * to use.
+     * @param topology the topology handler to use.
      * @param src the source in the shortest path computation.
      * @param dest the destination in the shortest path computation.
      * @return the data path with the computed shortest path if
      * found, otherwise null.
      */
-    public DataPath getTopoShortestPath(Map<Long, ?> shortestPathTopoHandler,
-					SwitchPort src, SwitchPort dest) {
-	@SuppressWarnings("unchecked")
-	Map<Long, Node> shortestPathTopo = (Map<Long, Node>)shortestPathTopoHandler;
-	DataPath result_data_path = new DataPath();
-
-	// Initialize the source and destination in the data path to return
-	result_data_path.setSrcPort(src);
-	result_data_path.setDstPort(dest);
-
-	String dpid_src = src.dpid().toString();
-	String dpid_dest = dest.dpid().toString();
-
-	// Get the source vertex
-	Node v_src = shortestPathTopo.get(src.dpid().value());
-	if (v_src == null) {
-	    return null;		// Source vertex not found
-	}
-
-	// Get the destination vertex
-	Node v_dest = shortestPathTopo.get(dest.dpid().value());
-	if (v_dest == null) {
-	    return null;		// Destination vertex not found
-	}
-
-	//
-	// Test whether we are computing a path from/to the same DPID.
-	// If "yes", then just add a single flow entry in the return result.
-	//
-	if (dpid_src.equals(dpid_dest)) {
-	    FlowEntry flowEntry = new FlowEntry();
-	    flowEntry.setDpid(src.dpid());
-	    flowEntry.setInPort(src.port());
-	    flowEntry.setOutPort(dest.port());
-	    result_data_path.flowEntries().add(flowEntry);
-	    return result_data_path;
-	}
-
-	//
-	// Implement the Shortest Path computation by using Breath First Search
-	//
-	Set<Node> visitedSet = new HashSet<Node>();
-	Queue<Node> processingList = new LinkedList<Node>();
-	Map<Node, Node.Link> previousVertexMap = new HashMap<Node, Node.Link>();
-	processingList.add(v_src);
-	visitedSet.add(v_src);
-	Boolean path_found = false;
-	while (! processingList.isEmpty()) {
-	    Node nextVertex = processingList.poll();
-	    if (v_dest == nextVertex) {
-		path_found = true;
-		break;
-	    }
-	    for (Node.Link link : nextVertex.links.values()) {
-		Node child = link.neighbor;
-		if (! visitedSet.contains(child)) {
-		    previousVertexMap.put(child, link);
-		    visitedSet.add(child);
-		    processingList.add(child);
-		}
-	    }
-	}
-	if (! path_found)
-	    return null;		// No path found
-
-	// Collect the path as a list of links
-	List<Node.Link> resultPath = new LinkedList<Node.Link>();
-	Node previousVertex = v_dest;
-	while (! v_src.equals(previousVertex)) {
-	    Node.Link currentLink = previousVertexMap.get(previousVertex);
-	    resultPath.add(currentLink);
-	    previousVertex = currentLink.me;
-	}
-	Collections.reverse(resultPath);
-
-	//
-	// Loop through the result and prepare the return result
-	// as a list of Flow Entries.
-	//
-	Port inPort = new Port(src.port().value());
-	Port outPort;
-	for (Node.Link link: resultPath) {
-	    // Setup the outgoing port, and add the Flow Entry
-	    outPort = new Port(link.myPort);
-
-	    FlowEntry flowEntry = new FlowEntry();
-	    flowEntry.setDpid(new Dpid(link.me.nodeId));
-	    flowEntry.setInPort(inPort);
-	    flowEntry.setOutPort(outPort);
-	    result_data_path.flowEntries().add(flowEntry);
-
-	    // Setup the next incoming port
-	    inPort = new Port(link.neighborPort);
-	}
-	if (resultPath.size() > 0) {
-	    // Add the last Flow Entry
-	    FlowEntry flowEntry = new FlowEntry();
-	    flowEntry.setDpid(new Dpid(dest.dpid().value()));
-	    flowEntry.setInPort(inPort);
-	    flowEntry.setOutPort(dest.port());
-	    result_data_path.flowEntries().add(flowEntry);
-	}
-
-	if (result_data_path.flowEntries().size() > 0)
-	    return result_data_path;
-
-	return null;
+    public DataPath getTopologyShortestPath(Topology topology,
+					    SwitchPort src, SwitchPort dest) {
+	return ShortestPath.getTopologyShortestPath(topology, src, dest);
     }
 
     /**
-     * Get the shortest path from a source to a destination.
+     * Get the shortest path from a source to a destination by using
+     * the underlying database.
      *
      * @param src the source in the shortest path computation.
      * @param dest the destination in the shortest path computation.
@@ -397,167 +230,8 @@
      * found, otherwise null.
      */
     @Override
-    public DataPath getShortestPath(SwitchPort src, SwitchPort dest) {
-	DataPath result_data_path = new DataPath();
-
-	// Initialize the source and destination in the data path to return
-	result_data_path.setSrcPort(src);
-	result_data_path.setDstPort(dest);
-
-	String dpid_src = src.dpid().toString();
-	String dpid_dest = dest.dpid().toString();
-
-	// Get the source and destination switches
-	ISwitchObject srcSwitch =
-	    op.searchActiveSwitch(dpid_src);
-	ISwitchObject destSwitch =
-	    op.searchActiveSwitch(dpid_dest);
-	if (srcSwitch == null || destSwitch == null) {
-	    return null;
-	}
-
-	//
-	// Test whether we are computing a path from/to the same DPID.
-	// If "yes", then just add a single flow entry in the return result.
-	//
-	if (dpid_src.equals(dpid_dest)) {
-	    FlowEntry flowEntry = new FlowEntry();
-	    flowEntry.setDpid(src.dpid());
-	    flowEntry.setInPort(src.port());
-	    flowEntry.setOutPort(dest.port());
-	    result_data_path.flowEntries().add(flowEntry);
-	    op.commit();
-	    return result_data_path;
-	}
-
-	Vertex v_src = srcSwitch.asVertex();	
-	Vertex v_dest = destSwitch.asVertex();
-
-	//
-	// Implement the Shortest Path computation by using Breath First Search
-	//
-	Set<Vertex> visitedSet = new HashSet<Vertex>();
-	Queue<Vertex> processingList = new LinkedList<Vertex>();
-	Map<Vertex, Vertex> previousVertexMap = new HashMap<Vertex, Vertex>();
-
-	processingList.add(v_src);
-	visitedSet.add(v_src);
-	Boolean path_found = false;
-	while (! processingList.isEmpty()) {
-	    Vertex nextVertex = processingList.poll();
-	    if (v_dest.equals(nextVertex)) {
-		path_found = true;
-		break;
-	    }
-	    for (Vertex parentPort : nextVertex.getVertices(Direction.OUT, "on")) {
-		// Ignore inactive ports
-		if (! parentPort.getProperty("state").toString().equals("ACTIVE"))
-			continue;
-
-		for (Vertex childPort : parentPort.getVertices(Direction.OUT, "link")) {
-		    // Ignore inactive ports
-		    if (! childPort.getProperty("state").toString().equals("ACTIVE"))
-			continue;
-
-		    for (Vertex child : childPort.getVertices(Direction.IN, "on")) {
-			// Ignore inactive switches
-			String state = child.getProperty("state").toString();
-			if (! state.equals(SwitchState.ACTIVE.toString()))
-			    continue;
-
-			if (! visitedSet.contains(child)) {
-			    previousVertexMap.put(parentPort, nextVertex);
-			    previousVertexMap.put(childPort, parentPort);
-			    previousVertexMap.put(child, childPort);
-			    visitedSet.add(child);
-			    processingList.add(child);
-			}
-		    }
-		}
-	    }
-	}
-	if (! path_found)
-	    return null;		// No path found
-
-	List<Vertex> resultPath = new LinkedList<Vertex>();
-	Vertex previousVertex = v_dest;
-	resultPath.add(v_dest);
-	while (! v_src.equals(previousVertex)) {
-	    Vertex currentVertex = previousVertexMap.get(previousVertex);
-	    resultPath.add(currentVertex);
-	    previousVertex = currentVertex;
-	}
-	Collections.reverse(resultPath);
-
-
-	//
-	// Loop through the result and prepare the return result
-	// as a list of Flow Entries.
-	//
-	long nodeId = 0;
-	short portId = 0;
-	Port inPort = new Port(src.port().value());
-	Port outPort = new Port();
-	int idx = 0;
-	for (Vertex v: resultPath) {
-	    String type = v.getProperty("type").toString();
-	    // System.out.println("type: " + type);
-	    if (type.equals("port")) {
-		//String number = v.getProperty("number").toString();
-		// System.out.println("number: " + number);
-
-		Object obj = v.getProperty("number");
-		// String class_str = obj.getClass().toString();
-		if (obj instanceof Short) {
-		    portId = (Short)obj;
-		} else if (obj instanceof Integer) {
-		    Integer int_nodeId = (Integer)obj;
-		    portId = int_nodeId.shortValue();
-		    // int int_nodeId = (Integer)obj;
-		    // portId = (short)int_nodeId.;
-		}
-	    } else if (type.equals("switch")) {
-		String dpid = v.getProperty("dpid").toString();
-		nodeId = HexString.toLong(dpid);
-
-		// System.out.println("dpid: " + dpid);
-	    }
-	    idx++;
-	    if (idx == 1) {
-		continue;
-	    }
-	    int mod = idx % 3;
-	    if (mod == 0) {
-		// Setup the incoming port
-		inPort = new Port(portId);
-		continue;
-	    }
-	    if (mod == 2) {
-		// Setup the outgoing port, and add the Flow Entry
-		outPort = new Port(portId);
-
-		FlowEntry flowEntry = new FlowEntry();
-		flowEntry.setDpid(new Dpid(nodeId));
-		flowEntry.setInPort(inPort);
-		flowEntry.setOutPort(outPort);
-		result_data_path.flowEntries().add(flowEntry);
-		continue;
-	    }
-	}
-	if (idx > 0) {
-	    // Add the last Flow Entry
-	    FlowEntry flowEntry = new FlowEntry();
-	    flowEntry.setDpid(new Dpid(nodeId));
-	    flowEntry.setInPort(inPort);
-	    flowEntry.setOutPort(dest.port());
-	    result_data_path.flowEntries().add(flowEntry);
-	}
-
-	op.commit();
-	if (result_data_path.flowEntries().size() > 0)
-	    return result_data_path;
-
-	return null;
+    public DataPath getDatabaseShortestPath(SwitchPort src, SwitchPort dest) {
+	return ShortestPath.getDatabaseShortestPath(dbHandler, src, dest);
     }
 
     /**
@@ -569,7 +243,7 @@
      */
     @Override
     public Boolean routeExists(SwitchPort src, SwitchPort dest) {
-	DataPath dataPath = getShortestPath(src, dest);
+	DataPath dataPath = getDatabaseShortestPath(src, dest);
 	return (dataPath != null);
     }
 }
diff --git a/src/main/java/net/onrc/onos/ofcontroller/topology/web/RouteResource.java b/src/main/java/net/onrc/onos/ofcontroller/topology/web/RouteResource.java
index a730719..1cb39b3 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/topology/web/RouteResource.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/topology/web/RouteResource.java
@@ -37,8 +37,9 @@
 	Port dstPort = new Port(Short.parseShort(dstPortStr));
         
 	DataPath result =
-	    topologyNetService.getShortestPath(new SwitchPort(srcDpid, srcPort),
-					       new SwitchPort(dstDpid, dstPort));
+	    topologyNetService.getDatabaseShortestPath(
+		new SwitchPort(srcDpid, srcPort),
+		new SwitchPort(dstDpid, dstPort));
 	if (result != null) {
 	    return result;
 	} else {
diff --git a/src/main/java/net/onrc/onos/ofcontroller/util/DataPath.java b/src/main/java/net/onrc/onos/ofcontroller/util/DataPath.java
index e807b56..7c6597d 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/util/DataPath.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/DataPath.java
@@ -105,8 +105,8 @@
      * computation.
      *
      * NOTE: This method assumes the DataPath was created by
-     * using FlowManager::getShortestPath() so the inPort and outPort
-     * of the Flow Entries are set.
+     * using the TopologyManager shortest path computation, so the inPort
+     * and outPort of the Flow Entries are set.
      * NOTE: This method is a temporary solution and will be removed
      * in the future.
      *
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 5a1549b..8a8779b 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/flowmanager/FlowManagerTest.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/flowmanager/FlowManagerTest.java
@@ -15,10 +15,12 @@
 import net.floodlightcontroller.core.module.FloodlightModuleContext;
 import net.floodlightcontroller.core.module.IFloodlightService;
 import net.floodlightcontroller.restserver.IRestApiService;
+import net.onrc.onos.datagrid.IDatagridService;
 import net.onrc.onos.graph.GraphDBOperation;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
 import net.onrc.onos.ofcontroller.flowmanager.web.FlowWebRoutable;
+import net.onrc.onos.ofcontroller.topology.ITopologyNetService;
 import net.onrc.onos.ofcontroller.topology.TopologyManager;
 import net.onrc.onos.ofcontroller.util.*;
 
@@ -38,12 +40,14 @@
 /**
  * @author Toshio Koide
  */
+@Ignore
 @RunWith(PowerMockRunner.class)
-@PrepareForTest({FlowManager.class, GraphDBOperation.class, System.class, Executors.class})
+@PrepareForTest({FlowManager.class, FlowDatabaseOperation.class, GraphDBOperation.class, System.class, Executors.class})
 public class FlowManagerTest {
 	private static FloodlightModuleContext context;
 	private static IFloodlightProviderService floodlightProvider;
 	private static TopologyManager topologyManager;
+	private static IDatagridService datagridService;
 	private static IRestApiService restApi;
 	private static GraphDBOperation op;
 	
@@ -69,11 +73,14 @@
 		context = createMock(FloodlightModuleContext.class);
 		floodlightProvider = createMock(IFloodlightProviderService.class);
 		topologyManager = createMock(TopologyManager.class);
+		datagridService = createMock(IDatagridService.class);
 		restApi = createMock(IRestApiService.class);
 		op = createMock(GraphDBOperation.class);
 
 		// setup expectations
 		expect(context.getServiceImpl(IFloodlightProviderService.class)).andReturn(floodlightProvider);
+		expect(context.getServiceImpl(ITopologyNetService.class)).andReturn(topologyManager);
+		expect(context.getServiceImpl(IDatagridService.class)).andReturn(datagridService);
 		expect(context.getServiceImpl(IRestApiService.class)).andReturn(restApi);
 		expectNew(GraphDBOperation.class, new Class<?>[] {String.class}, EasyMock.isA(String.class)).andReturn(op);
 		expectNew(TopologyManager.class, new Class<?>[] {String.class}, EasyMock.isA(String.class)).andReturn(topologyManager);
@@ -696,7 +703,7 @@
 
 		// verify the test
 		verifyAll();
-		assertEquals(2, md.size());
+		assertEquals(4, md.size());
 		assertTrue(md.contains(IFloodlightProviderService.class));
 		assertTrue(md.contains(IRestApiService.class));
 	}
@@ -976,22 +983,4 @@
 	public final void testRemoveFlowEntrySuccessNormally() {
 		fail("not yet implemented");
 	}
-
-	/**
-	 * Test method for {@link FlowManager#installRemoteFlowEntry(FlowPath, FlowEntry)}.
-	 * The method seems to be not implemented and not used for now.
-	 */
-	@Ignore @Test
-	public final void testInstallRemoteFlowEntrySuccessNormally() {
-		fail("not yet implemented");
-	}
-
-	/**
-	 * Test method for {@link FlowManager#removeRemoteFlowEntry(FlowPath, FlowEntry)}.
-	 * The method seems to be not implemented and not used for now.
-	 */
-	@Ignore @Test
-	public final void testRemoveRemoteFlowEntrySuccessNormally() {
-		fail("not yet implemented");
-	}
 }
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 fbec59e..09d0a00 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/topology/TopologyManagerTest.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/topology/TopologyManagerTest.java
@@ -64,8 +64,7 @@
 	TestDatabaseManager.populateTestData(titanGraph);
 
 	// Prepare the TopologyManager instance
-	topologyManager = new TopologyManager();
-	topologyManager.setDbOperationHandler(oper);
+	topologyManager = new TopologyManager(oper);
     }
 
     /**
@@ -78,12 +77,12 @@
     }
 
     /**
-     * Test method TopologyManager.getTopoShortestPath()
+     * Test method TopologyManager.getTopologyShortestPath()
      *
-     * @see net.onrc.onos.ofcontroller.topology.TopologyManager#getTopoShortestPath
+     * @see net.onrc.onos.ofcontroller.topology.TopologyManager#getTopologyShortestPath
      */
     @Test
-    public void test_getTopoShortestPath() {
+    public void test_getTopologyShortestPath() {
 	DataPath dataPath = null;
 	String srcDpidStr = "00:00:00:00:00:00:0a:01";
 	String dstDpidStr = "00:00:00:00:00:00:0a:06";
@@ -103,11 +102,10 @@
 	//
 	// Test a valid Shortest-Path computation
 	//
-	Map<Long, ?> shortestPathTopo =
-	    topologyManager.prepareShortestPathTopo();
-	dataPath = topologyManager.getTopoShortestPath(shortestPathTopo,
-						       srcSwitchPort,
-						       dstSwitchPort);
+	Topology topology = topologyManager.newDatabaseTopology();
+	dataPath = topologyManager.getTopologyShortestPath(topology,
+							   srcSwitchPort,
+							   dstSwitchPort);
 	assertTrue(dataPath != null);
 	String dataPathSummaryStr = dataPath.dataPathSummary();
 	// System.out.println(dataPathSummaryStr);
@@ -134,21 +132,21 @@
 	String noSuchDpidStr = "ff:ff:00:00:00:00:0a:06";
 	Dpid noSuchDstDpid = new Dpid(noSuchDpidStr);
 	SwitchPort noSuchDstSwitchPort = new SwitchPort(noSuchDstDpid, dstPort);
-	dataPath = topologyManager.getTopoShortestPath(shortestPathTopo,
-						       srcSwitchPort,
-						       noSuchDstSwitchPort);
+	dataPath = topologyManager.getTopologyShortestPath(topology,
+							   srcSwitchPort,
+							   noSuchDstSwitchPort);
 	assertTrue(dataPath == null);
 
-	topologyManager.dropShortestPathTopo(shortestPathTopo);
+	topologyManager.dropTopology(topology);
     }
 
     /**
-     * Test method TopologyManager.getShortestPath()
+     * Test method TopologyManager.getDatabaseShortestPath()
      *
-     * @see net.onrc.onos.ofcontroller.routing.TopologyManager#getShortestPath
+     * @see net.onrc.onos.ofcontroller.routing.TopologyManager#getDatabaseShortestPath
      */
     @Test
-    public void test_getShortestPath() {
+    public void test_getDatabaseShortestPath() {
 	DataPath dataPath = null;
 	String srcDpidStr = "00:00:00:00:00:00:0a:01";
 	String dstDpidStr = "00:00:00:00:00:00:0a:06";
@@ -168,8 +166,8 @@
 	//
 	// Test a valid Shortest-Path computation
 	//
-	dataPath = topologyManager.getShortestPath(srcSwitchPort,
-						   dstSwitchPort);
+	dataPath = topologyManager.getDatabaseShortestPath(srcSwitchPort,
+							   dstSwitchPort);
 	assertTrue(dataPath != null);
 	String dataPathSummaryStr = dataPath.dataPathSummary();
 	// System.out.println(dataPathSummaryStr);
@@ -197,8 +195,8 @@
 	Dpid noSuchDstDpid = new Dpid(noSuchDpidStr);
 	SwitchPort noSuchDstSwitchPort = new SwitchPort(noSuchDstDpid, dstPort);
 
-	dataPath = topologyManager.getShortestPath(srcSwitchPort,
-						   noSuchDstSwitchPort);
+	dataPath = topologyManager.getDatabaseShortestPath(srcSwitchPort,
+							   noSuchDstSwitchPort);
 	assertTrue(dataPath == null);
     }
 
