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 2766ea8..79cca4b 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;
@@ -82,7 +83,7 @@
 	private static Logger log = LoggerFactory.getLogger(BgpRoute.class);
 
 	private IFloodlightProviderService floodlightProvider;
-	private ITopologyService topology;
+	private ITopologyService topologyService;
 	private ITopologyNetService topologyNetService;
 	private ILinkDiscoveryService linkDiscoveryService;
 	private IRestApiService restApi;
@@ -142,8 +143,8 @@
 	
 	private FlowCache flowCache;
 	
-	private volatile Map<Long, ?> shortestPathTopo = null;
-
+	private volatile Topology topology = null;
+		
 	private class TopologyChangeDetector implements Runnable {
 		@Override
 		public void run() {
@@ -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();
@@ -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());
 			}
 			
@@ -697,12 +698,12 @@
 			}
 			
 			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){
@@ -1193,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/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 e0ac4e1..6db2009 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;
@@ -44,8 +45,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;
@@ -226,14 +231,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/FlowManager.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
index 2c5f4ba..82aa25c 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
@@ -27,14 +27,18 @@
 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.Topology;
 import net.onrc.onos.ofcontroller.topology.TopologyManager;
 import net.onrc.onos.ofcontroller.util.CallerId;
 import net.onrc.onos.ofcontroller.util.DataPath;
@@ -71,9 +75,10 @@
 
     protected GraphDBOperation op;
 
-    protected IRestApiService restApi;
     protected volatile IFloodlightProviderService floodlightProvider;
     protected volatile ITopologyNetService topologyNetService;
+    protected volatile IDatagridService datagridService;
+    protected IRestApiService restApi;
     protected FloodlightModuleContext context;
 
     protected OFMessageDamper messageDamper;
@@ -94,12 +99,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);
 
@@ -143,10 +142,10 @@
 		    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();
 		for (IFlowEntry flowEntryObj : allFlowEntries) {
@@ -183,15 +182,6 @@
 			addFlowEntries.add(flowEntryObj);
 		    }
 		    counterMyNotUpdatedFlowEntries++;
-		    // Code for measurement purpose
-		    // TODO: Commented-out for now
-		    /*
-		    {
-			if (flowObj.getFlowId().equals(measurementFlowIdStr)) {
-			    processed_measurement_flow = true;
-			}
-		    }
-		    */
 		}
 
 		//
@@ -234,14 +224,6 @@
 
 		op.commit();
 
-		if (processed_measurement_flow) {
-		    long estimatedTime =
-			System.nanoTime() - modifiedMeasurementFlowTime;
-		    String logMsg = "MEASUREMENT: Pushed Flow delay: " +
-			(double)estimatedTime / 1000000000 + " sec";
-		    log.debug(logMsg);
-		}
-
 		long estimatedTime = System.nanoTime() - startTime;
 		double rate = 0.0;
 		if (estimatedTime > 0)
@@ -287,14 +269,11 @@
 		}
 		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();
+		Topology topology = topologyNetService.newDatabaseTopology();
 		Iterable<IFlowPath> allFlowPaths = op.getAllFlowPaths();
 		for (IFlowPath flowPathObj : allFlowPaths) {
 		    counterAllFlowPaths++;
@@ -359,18 +338,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();
@@ -395,18 +375,10 @@
 		    op.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);
-		}
-
 		long estimatedTime = System.nanoTime() - startTime;
 		double rate = 0.0;
 		if (estimatedTime > 0)
@@ -429,7 +401,6 @@
     @Override
     public void init(String conf) {
     	op = new GraphDBOperation(conf);
-	topologyNetService = new TopologyManager(conf);
     }
 
     /**
@@ -469,9 +440,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 +454,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 +474,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);
     }
@@ -545,10 +519,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(
@@ -570,25 +544,13 @@
     @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());
+	    if ((flowObj = op.searchFlowPath(flowPath.flowId())) != null) {
 		found = true;
 	    } else {
 		flowObj = op.newFlowPath();
-		log.debug("Adding FlowPath with FlowId {}: creating new FlowPath",
-			  flowPath.flowId().toString());
 	    }
 	} catch (Exception e) {
 	    // TODO: handle exceptions
@@ -738,13 +700,9 @@
 	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",
@@ -942,13 +900,6 @@
      */
     @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,
@@ -956,14 +907,7 @@
 	// 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());
-	    }
+	    flowObj = op.searchFlowPath(flowId);
 	} catch (Exception e) {
 	    // TODO: handle exceptions
 	    op.rollback();
@@ -1035,14 +979,7 @@
     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());
-	    }
+	    flowObj = op.searchFlowPath(flowId);
 	} catch (Exception e) {
 	    // TODO: handle exceptions
 	    op.rollback();
@@ -1078,14 +1015,7 @@
     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());
-	    }
+	    flowObj = op.searchFlowPath(flowId);
 	} catch (Exception e) {
 	    // TODO: handle exceptions
 	    op.rollback();
@@ -1126,10 +1056,8 @@
 	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);
+	if (allFlows == null)
 	    return flowPaths;
-	}
 
 	for (FlowPath flow : allFlows) {
 	    //
@@ -1148,12 +1076,6 @@
 	    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;
     }
 
@@ -1172,13 +1094,11 @@
 	// 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();
+	ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
+	ArrayList<FlowPath> allFlows = getAllFlows();
 
-	if (allFlows == null) {
-	    log.debug("Get FlowPaths for dataPathEndpoints{}: no FlowPaths found", dataPathEndpoints);
+	if (allFlows == null)
 	    return flowPaths;
-	}
 
 	for (FlowPath flow : allFlows) {
 	    //
@@ -1195,13 +1115,7 @@
 	    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 flowPaths;
     }
 
     /**
@@ -1212,7 +1126,8 @@
      * @return the Flow Paths if found, otherwise null.
      */
     @Override
-    public ArrayList<IFlowPath> getAllFlowsSummary(FlowId flowId, int maxFlows) {
+    public ArrayList<IFlowPath> getAllFlowsSummary(FlowId flowId,
+						   int maxFlows) {
 
 	//
 	// TODO: The implementation below is not optimal:
@@ -1221,64 +1136,28 @@
 	// 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();
-    	
+    	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;
-					}
-    			}
-    	);
+			 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;
-    	
-    	/*
-    	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;
-		*/
     }
     
     /**
@@ -1292,11 +1171,7 @@
 	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");
-	    }
+	    flowPathsObj = op.getAllFlowPaths();
 	} catch (Exception e) {
 	    // TODO: handle exceptions
 	    op.rollback();
@@ -1330,39 +1205,24 @@
     	Iterable<IFlowPath> flowPathsObj = null;
     	ArrayList<IFlowPath> flowPathsObjArray = new ArrayList<IFlowPath>();
 
+	// TODO: Remove this op.commit() flow, because it is not needed?
     	op.commit();
-    	
+
     	try {
-    	    if ((flowPathsObj = op.getAllFlowPaths()) != null) {
-    		log.debug("Get all FlowPaths: found FlowPaths");
-    	    } else {
-    		log.debug("Get all FlowPaths: no FlowPaths found");
-    	    }
+    	    flowPathsObj = op.getAllFlowPaths();
     	} 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
+    	    return flowPathsObjArray;		// 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);
-    	}
-    	*/
+    	for (IFlowPath flowObj : flowPathsObj)
+	    flowPathsObjArray.add(flowObj);
 
-    	//conn.endTx(Transaction.COMMIT);
+    	// conn.endTx(Transaction.COMMIT);
 
     	return flowPathsObjArray;
     }
@@ -2318,39 +2178,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/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.
      *
