merge conflicts
diff --git a/mastership-test.sh b/mastership-test.sh
index 06189df..06907f0 100755
--- a/mastership-test.sh
+++ b/mastership-test.sh
@@ -1 +1 @@
-java -Dlogback.configurationFile=logback.xml -cp target/floodlight-only.jar:lib/*:lib/titan/* net.floodlightcontroller.mastership.MastershipManager $1
+java -Dlogback.configurationFile=logback.xml -cp target/floodlight-only.jar:lib/*:lib/titan/* net.floodlightcontroller.mastership.MastershipRunner $1
diff --git a/src/main/java/net/floodlightcontroller/core/FloodlightProvider.java b/src/main/java/net/floodlightcontroller/core/FloodlightProvider.java
index e84e0f6..5c847b7 100644
--- a/src/main/java/net/floodlightcontroller/core/FloodlightProvider.java
+++ b/src/main/java/net/floodlightcontroller/core/FloodlightProvider.java
@@ -10,7 +10,9 @@
 import net.floodlightcontroller.core.module.FloodlightModuleException;
 import net.floodlightcontroller.core.module.IFloodlightModule;
 import net.floodlightcontroller.core.module.IFloodlightService;
+import net.floodlightcontroller.core.INetMapTopologyService.ITopoRouteService;
 import net.floodlightcontroller.counter.ICounterStoreService;
+import net.floodlightcontroller.flowcache.IFlowService;
 import net.floodlightcontroller.mastership.IMastershipService;
 import net.floodlightcontroller.perfmon.IPktInProcessingTimeService;
 import net.floodlightcontroller.restserver.IRestApiService;
@@ -51,6 +53,8 @@
         dependencies.add(ICounterStoreService.class);
         dependencies.add(IThreadPoolService.class);
         dependencies.add(IMastershipService.class);
+        dependencies.add(IFlowService.class);
+        dependencies.add(ITopoRouteService.class);
         return dependencies;
     }
 
@@ -67,6 +71,8 @@
        controller.setThreadPoolService(
            context.getServiceImpl(IThreadPoolService.class));
        controller.setMastershipService(context.getServiceImpl(IMastershipService.class));
+       controller.setFlowService(context.getServiceImpl(IFlowService.class));
+       controller.setTopoRouteService(context.getServiceImpl(ITopoRouteService.class));
        controller.init(context.getConfigParams(this));
     }
 
diff --git a/src/main/java/net/floodlightcontroller/core/INetMapTopologyService.java b/src/main/java/net/floodlightcontroller/core/INetMapTopologyService.java
index 937c551..a3eb830 100644
--- a/src/main/java/net/floodlightcontroller/core/INetMapTopologyService.java
+++ b/src/main/java/net/floodlightcontroller/core/INetMapTopologyService.java
@@ -2,6 +2,7 @@
 
 import java.util.List;
 
+import net.floodlightcontroller.core.module.IFloodlightService;
 import net.floodlightcontroller.core.INetMapTopologyObjects.IDeviceObject;
 import net.floodlightcontroller.core.INetMapTopologyObjects.IPortObject;
 import net.floodlightcontroller.core.INetMapTopologyObjects.ISwitchObject;
@@ -29,7 +30,7 @@
 		Iterable<IDeviceObject> getDevicesOnSwitch(String dpid, short port_num);
 	}
 	
-	public interface ITopoRouteService {
+	public interface ITopoRouteService extends IFloodlightService {
 		List<NodePortTuple> getShortestPath(NodePortTuple src, NodePortTuple dest);
 		Boolean routeExists(NodePortTuple src, NodePortTuple dest);
 	}
diff --git a/src/main/java/net/floodlightcontroller/core/internal/Controller.java b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
index d9cc5e1..cbcd9a0 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/Controller.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
@@ -58,6 +58,7 @@
 import net.floodlightcontroller.core.IOFSwitch;
 import net.floodlightcontroller.core.IOFSwitchFilter;
 import net.floodlightcontroller.core.IOFSwitchListener;
+import net.floodlightcontroller.core.INetMapTopologyService.ITopoRouteService;
 import net.floodlightcontroller.core.ISwitchStorage.SwitchState;
 import net.floodlightcontroller.core.annotations.LogMessageDoc;
 import net.floodlightcontroller.core.annotations.LogMessageDocs;
@@ -65,6 +66,7 @@
 import net.floodlightcontroller.core.util.ListenerDispatcher;
 import net.floodlightcontroller.core.web.CoreWebRoutable;
 import net.floodlightcontroller.counter.ICounterStoreService;
+import net.floodlightcontroller.flowcache.IFlowService;
 import net.floodlightcontroller.mastership.IMastershipService;
 import net.floodlightcontroller.packet.Ethernet;
 import net.floodlightcontroller.perfmon.IPktInProcessingTimeService;
@@ -190,6 +192,8 @@
     protected IPktInProcessingTimeService pktinProcTime;
     protected IThreadPoolService threadPool;
     protected IMastershipService masterHelper;
+    protected IFlowService flowService;
+    protected ITopoRouteService topoRouteService;
     
     // Configuration options
     protected int openFlowPort = 6633;
@@ -392,9 +396,17 @@
         this.threadPool = tp;
     }
 
-	public void setMastershipService(IMastershipService serviceImpl) {
-		this.masterHelper = serviceImpl;		
-	}
+    public void setMastershipService(IMastershipService serviceImpl) {
+	this.masterHelper = serviceImpl;		
+    }
+
+    public void setFlowService(IFlowService serviceImpl) {
+	this.flowService = serviceImpl;		
+    }
+
+    public void setTopoRouteService(ITopoRouteService serviceImpl) {
+	this.topoRouteService = serviceImpl;		
+    }
 	
     @Override
     public Role getRole() {
diff --git a/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java b/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java
index d9f19ba..12ed505 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java
@@ -26,7 +26,7 @@
 
     /** The logger. */
     private static Logger logger =
-	LoggerFactory.getLogger(FlowReconcileManager.class);
+	LoggerFactory.getLogger(FlowManager.class);
 
     @Override
     public Collection<Class<? extends IFloodlightService>> getModuleServices() {
diff --git a/src/main/java/net/floodlightcontroller/flowcache/web/AddFlowResource.java b/src/main/java/net/floodlightcontroller/flowcache/web/AddFlowResource.java
index 35367eb..f32d124 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/web/AddFlowResource.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/web/AddFlowResource.java
@@ -1,6 +1,8 @@
 package net.floodlightcontroller.flowcache.web;
 
 import net.floodlightcontroller.flowcache.IFlowService;
+import net.floodlightcontroller.util.FlowId;
+import net.floodlightcontroller.util.FlowPath;
 
 import org.restlet.resource.Get;
 import org.restlet.resource.ServerResource;
@@ -12,8 +14,8 @@
     protected static Logger log = LoggerFactory.getLogger(AddFlowResource.class);
 
     @Get("json")
-    public Boolean retrieve() {
-	Boolean result = false;
+    public FlowId retrieve() {
+	FlowId result = new FlowId();
 
         IFlowService flowService =
                 (IFlowService)getContext().getAttributes().
@@ -26,10 +28,13 @@
 
 	// Extract the arguments
 	String flowPathStr = (String) getRequestAttributes().get("flow");
+	FlowPath flowPath = new FlowPath(flowPathStr);
+
 	log.debug("Add Flow Path: " + flowPathStr);
 
-	// TODO: Implement it.
-	result = true;
+	if (flowService.addFlow(flowPath, result) != true) {
+	    result = new FlowId();	// Error: Empty Flow Id
+	}
 
         return result;
     }
diff --git a/src/main/java/net/floodlightcontroller/flowcache/web/DeleteFlowResource.java b/src/main/java/net/floodlightcontroller/flowcache/web/DeleteFlowResource.java
index f323a54..cefad18 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/web/DeleteFlowResource.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/web/DeleteFlowResource.java
@@ -1,6 +1,7 @@
 package net.floodlightcontroller.flowcache.web;
 
 import net.floodlightcontroller.flowcache.IFlowService;
+import net.floodlightcontroller.util.FlowId;
 
 import org.openflow.util.HexString;
 import org.restlet.resource.Get;
@@ -26,11 +27,11 @@
 
 	// Extract the arguments
 	String flowIdStr = (String) getRequestAttributes().get("flow-id");
-	long flowId = HexString.toLong(flowIdStr);
+	FlowId flowId = new FlowId(HexString.toLong(flowIdStr));
+
 	log.debug("Delete Flow Id: " + flowIdStr);
 
-	// TODO: Implement it.
-	result = true;
+	result = flowService.deleteFlow(flowId);
 
         return result;
     }
diff --git a/src/main/java/net/floodlightcontroller/flowcache/web/FlowWebRoutable.java b/src/main/java/net/floodlightcontroller/flowcache/web/FlowWebRoutable.java
index b1188c8..0859397 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/web/FlowWebRoutable.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/web/FlowWebRoutable.java
@@ -16,8 +16,8 @@
         router.attach("/add/{flow}/json", AddFlowResource.class);
         router.attach("/delete/{flow-id}/json", DeleteFlowResource.class);
         router.attach("/get/{flow-id}/json", GetFlowByIdResource.class);
-        router.attach("/get/{installer-id}/{data-path-endpoints}/json", GetFlowByInstallerIdResource.class);
-        router.attach("/getall/{data-path-endpoints}/json", GetAllFlowsByEndpointsResource.class);
+        router.attach("/get/{installer-id}/{src-dpid}/{src-port}/{dst-dpid}/{dst-port}/json", GetFlowByInstallerIdResource.class);
+        router.attach("/getall/{src-dpid}/{src-port}/{dst-dpid}/{dst-port}/json", GetAllFlowsByEndpointsResource.class);
         router.attach("/getall/json", GetAllFlowsResource.class);
         return router;
     }
diff --git a/src/main/java/net/floodlightcontroller/flowcache/web/GetAllFlowsByEndpointsResource.java b/src/main/java/net/floodlightcontroller/flowcache/web/GetAllFlowsByEndpointsResource.java
index 211a051..4e96c0c 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/web/GetAllFlowsByEndpointsResource.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/web/GetAllFlowsByEndpointsResource.java
@@ -3,8 +3,13 @@
 import java.util.ArrayList;
 
 import net.floodlightcontroller.flowcache.IFlowService;
+import net.floodlightcontroller.util.DataPathEndpoints;
+import net.floodlightcontroller.util.Dpid;
 import net.floodlightcontroller.util.FlowPath;
+import net.floodlightcontroller.util.Port;
+import net.floodlightcontroller.util.SwitchPort;
 
+import org.openflow.util.HexString;
 import org.restlet.resource.Get;
 import org.restlet.resource.ServerResource;
 import org.slf4j.Logger;
@@ -27,10 +32,24 @@
 	}
 
 	// Extract the arguments
-	String dataPathEndpointsStr = (String) getRequestAttributes().get("data-path-endpoints");
-	log.debug("Get All Flows Endpoints: " + dataPathEndpointsStr);
+        String srcDpidStr = (String) getRequestAttributes().get("src-dpid");
+        String srcPortStr = (String) getRequestAttributes().get("src-port");
+        String dstDpidStr = (String) getRequestAttributes().get("dst-dpid");
+        String dstPortStr = (String) getRequestAttributes().get("dst-port");
 
-	// TODO: Implement it.
+	log.debug("Get All Flows Endpoints: " + srcDpidStr + "--" +
+		  srcPortStr + "--" + dstDpidStr + "--" + dstPortStr);
+
+	Dpid srcDpid = new Dpid(HexString.toLong(srcDpidStr));
+	Port srcPort = new Port(Short.parseShort(srcPortStr));
+	Dpid dstDpid = new Dpid(HexString.toLong(dstDpidStr));
+	Port dstPort = new Port(Short.parseShort(dstPortStr));
+	SwitchPort srcSwitchPort = new SwitchPort(srcDpid, srcPort);
+	SwitchPort dstSwitchPort = new SwitchPort(dstDpid, dstPort);
+	DataPathEndpoints dataPathEndpoints =
+	    new DataPathEndpoints(srcSwitchPort, dstSwitchPort);
+
+	flowService.getAllFlows(dataPathEndpoints, result);
 
         return result;
     }
diff --git a/src/main/java/net/floodlightcontroller/flowcache/web/GetAllFlowsResource.java b/src/main/java/net/floodlightcontroller/flowcache/web/GetAllFlowsResource.java
index 9d95651..5bf3a50 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/web/GetAllFlowsResource.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/web/GetAllFlowsResource.java
@@ -29,7 +29,7 @@
 	// Extract the arguments
 	log.debug("Get All Flows Endpoints");
 
-	// TODO: Implement it.
+	flowService.getAllFlows(result);
 
         return result;
     }
diff --git a/src/main/java/net/floodlightcontroller/flowcache/web/GetFlowByIdResource.java b/src/main/java/net/floodlightcontroller/flowcache/web/GetFlowByIdResource.java
index 99f880c..2863c79 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/web/GetFlowByIdResource.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/web/GetFlowByIdResource.java
@@ -1,6 +1,7 @@
 package net.floodlightcontroller.flowcache.web;
 
 import net.floodlightcontroller.flowcache.IFlowService;
+import net.floodlightcontroller.util.FlowId;
 import net.floodlightcontroller.util.FlowPath;
 
 import org.openflow.util.HexString;
@@ -27,10 +28,11 @@
 
 	// Extract the arguments
 	String flowIdStr = (String) getRequestAttributes().get("flow-id");
-	long flowId = HexString.toLong(flowIdStr);
+	FlowId flowId = new FlowId(HexString.toLong(flowIdStr));
+
 	log.debug("Get Flow Id: " + flowIdStr);
 
-	// TODO: Implement it.
+	flowService.getFlow(flowId, result);
 
         return result;
     }
diff --git a/src/main/java/net/floodlightcontroller/flowcache/web/GetFlowByInstallerIdResource.java b/src/main/java/net/floodlightcontroller/flowcache/web/GetFlowByInstallerIdResource.java
index 32d20cc..6b5f7f4 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/web/GetFlowByInstallerIdResource.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/web/GetFlowByInstallerIdResource.java
@@ -1,8 +1,14 @@
 package net.floodlightcontroller.flowcache.web;
 
 import net.floodlightcontroller.flowcache.IFlowService;
+import net.floodlightcontroller.util.CallerId;
+import net.floodlightcontroller.util.DataPathEndpoints;
+import net.floodlightcontroller.util.Dpid;
 import net.floodlightcontroller.util.FlowPath;
+import net.floodlightcontroller.util.Port;
+import net.floodlightcontroller.util.SwitchPort;
 
+import org.openflow.util.HexString;
 import org.restlet.resource.Get;
 import org.restlet.resource.ServerResource;
 import org.slf4j.Logger;
@@ -25,11 +31,27 @@
 	}
 
 	// Extract the arguments
-	String installerIdStr = (String) getRequestAttributes().get("installer-id");
-	String dataPathEndpointsStr = (String) getRequestAttributes().get("data-path-endpoints");
-	log.debug("Get Flow Installer: " + installerIdStr + " Endpoints: " + dataPathEndpointsStr);
+        String installerIdStr = (String) getRequestAttributes().get("installer-id");
+        String srcDpidStr = (String) getRequestAttributes().get("src-dpid");
+        String srcPortStr = (String) getRequestAttributes().get("src-port");
+        String dstDpidStr = (String) getRequestAttributes().get("dst-dpid");
+        String dstPortStr = (String) getRequestAttributes().get("dst-port");
 
-	// TODO: Implement it.
+	log.debug("Get Flow By Installer: " + installerIdStr + " Endpoints: " +
+		  srcDpidStr + "--" + srcPortStr + "--" +
+		  dstDpidStr + "--" + dstPortStr);
+
+	CallerId installerId = new CallerId(installerIdStr);
+	Dpid srcDpid = new Dpid(HexString.toLong(srcDpidStr));
+	Port srcPort = new Port(Short.parseShort(srcPortStr));
+	Dpid dstDpid = new Dpid(HexString.toLong(dstDpidStr));
+	Port dstPort = new Port(Short.parseShort(dstPortStr));
+	SwitchPort srcSwitchPort = new SwitchPort(srcDpid, srcPort);
+	SwitchPort dstSwitchPort = new SwitchPort(dstDpid, dstPort);
+	DataPathEndpoints dataPathEndpoints =
+	    new DataPathEndpoints(srcSwitchPort, dstSwitchPort);
+
+	flowService.getFlow(installerId, dataPathEndpoints, result);
 
         return result;
     }
diff --git a/src/main/java/net/floodlightcontroller/mastership/IMastershipService.java b/src/main/java/net/floodlightcontroller/mastership/IMastershipService.java
index 83800c3..cc0ddf4 100644
--- a/src/main/java/net/floodlightcontroller/mastership/IMastershipService.java
+++ b/src/main/java/net/floodlightcontroller/mastership/IMastershipService.java
@@ -1,7 +1,10 @@
 package net.floodlightcontroller.mastership;
 
+import java.util.Collection;
+
 import net.floodlightcontroller.core.module.IFloodlightService;
 
+//Will change to something like IRegistryService
 public interface IMastershipService extends IFloodlightService {
 	
 	// Callback for all mastership changes. 
@@ -24,4 +27,21 @@
 	public void setMastershipId (String id);
 	public String getMastershipId ();
 	
+	/**
+	 * Register a controller to the ONOS cluster
+	 * @param controller A string identifying the controller and (possibly) how to talk to it.
+	 * (We will have to develop a convention for this - most likely hostname:port)
+	 */
+	public void registerController(String controllerId) throws Exception;
+	
+	/**
+	 * Get all controllers in the cluster
+	 * @return
+	 */
+	public Collection<String> getAllControllers() throws Exception;
+	
+	
+	public String getControllerForSwitch(long dpid) throws Exception;
+	
+	public Collection<Long> getSwitchesControlledByController(String controllerId);
 }
diff --git a/src/main/java/net/floodlightcontroller/mastership/MastershipManager.java b/src/main/java/net/floodlightcontroller/mastership/MastershipManager.java
index 46b533e..bff588b 100644
--- a/src/main/java/net/floodlightcontroller/mastership/MastershipManager.java
+++ b/src/main/java/net/floodlightcontroller/mastership/MastershipManager.java
@@ -1,10 +1,12 @@
 package net.floodlightcontroller.mastership;
 
 import java.io.IOException;
+import java.io.UnsupportedEncodingException;
 import java.net.UnknownHostException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import net.floodlightcontroller.core.module.FloodlightModuleContext;
@@ -12,6 +14,7 @@
 import net.floodlightcontroller.core.module.IFloodlightModule;
 import net.floodlightcontroller.core.module.IFloodlightService;
 
+import org.apache.zookeeper.CreateMode;
 import org.apache.zookeeper.WatchedEvent;
 import org.apache.zookeeper.Watcher.Event.KeeperState;
 import org.openflow.util.HexString;
@@ -22,6 +25,9 @@
 import com.netflix.curator.framework.CuratorFramework;
 import com.netflix.curator.framework.CuratorFrameworkFactory;
 import com.netflix.curator.framework.api.CuratorWatcher;
+import com.netflix.curator.framework.recipes.cache.ChildData;
+import com.netflix.curator.framework.recipes.cache.PathChildrenCache;
+import com.netflix.curator.framework.recipes.cache.PathChildrenCache.StartMode;
 import com.netflix.curator.framework.recipes.leader.LeaderLatch;
 import com.netflix.curator.framework.recipes.leader.Participant;
 import com.netflix.curator.retry.ExponentialBackoffRetry;
@@ -34,9 +40,12 @@
 	//TODO read this from configuration
 	protected String connectionString = "localhost:2181";
 	private final String namespace = "onos";
-	private final String switchLatchesPath = "/switchmastership";
+	private final String switchLatchesPath = "/switches";
 	
 	protected CuratorFramework client;
+	
+	private final String controllerPath = "/controllers";
+	protected PathChildrenCache controllerCache;
 
 	protected Map<String, LeaderLatch> switchLatches;
 	protected Map<String, MastershipCallback> switchCallbacks;
@@ -52,7 +61,7 @@
 		}
 		
 		@Override
-		public void process(WatchedEvent event) throws Exception {
+		public synchronized void process(WatchedEvent event) throws Exception {
 			log.debug("Watch Event: {}", event);
 
 			LeaderLatch latch = switchLatches.get(dpid);
@@ -68,6 +77,7 @@
 			}
 			
 			try {
+				
 				Participant leader = latch.getLeader();
 
 				if (leader.getId().equals(mastershipId) && !isLeader){
@@ -96,6 +106,7 @@
 			//client.getChildren().usingWatcher(this).forPath(latchPath);
 		}
 	}
+
 	
 	@Override
 	public void acquireMastership(long dpid, MastershipCallback cb) throws Exception {
@@ -142,11 +153,12 @@
 		try {
 			latch.close();
 		} catch (IOException e) {
-			
+			//I think it's OK not to do anything here. Either the node got deleted correctly,
+			//or the connection went down and the node got deleted.
+		} finally {
+			switchLatches.remove(dpidStr);
+			switchCallbacks.remove(dpidStr);
 		}
-		
-		switchLatches.remove(dpidStr);
-		switchCallbacks.remove(dpidStr);
 	}
 
 	@Override
@@ -176,6 +188,77 @@
 		return mastershipId;
 	}
 	
+	@Override
+	public Collection<String> getAllControllers() throws Exception {
+		log.debug("Getting all controllers");
+		
+		List<String> controllers = new ArrayList<String>();
+		for (ChildData data : controllerCache.getCurrentData()){
+
+			String d = null;
+			try {
+				d = new String(data.getData(), "UTF-8");
+			} catch (UnsupportedEncodingException e) {
+				throw new Exception("Error encoding string", e);
+			}
+
+			controllers.add(d);
+		}
+		return controllers;
+	}
+
+	@Override
+	public void registerController(String id) throws Exception {
+		byte bytes[] = null;
+		try {
+			bytes = id.getBytes("UTF-8");
+		} catch (UnsupportedEncodingException e1) {
+			throw new Exception("Error encoding string", e1);
+		}
+		
+		String path = controllerPath + "/" + id;
+		
+		log.info("Registering controller with id {}", id);
+		
+		//Create ephemeral node with my id
+		try {
+			client.create().withProtection().withMode(CreateMode.EPHEMERAL)
+					.forPath(path, bytes);
+		} catch (Exception e) {
+			throw new Exception("Error contacting the Zookeeper service", e);
+		}
+	}
+	
+	@Override
+	public String getControllerForSwitch(long dpid) throws Exception {
+		// TODO Work out how we should store this controller/switch data.
+		// The leader latch might be a index to the /controllers collections
+		// which holds more info on the controller (how to talk to it for example).
+		
+		
+		String strDpid = HexString.toHexString(dpid);
+		LeaderLatch latch = switchLatches.get(strDpid);
+		
+		if (latch == null){
+			log.warn("Tried to get controller for non-existent switch");
+			return null;
+		}
+		
+		Participant leader = null;
+		try {
+			leader = latch.getLeader();
+		} catch (Exception e) {
+			throw new Exception("Error contacting the Zookeeper service", e);
+		}
+		
+		return leader.getId();
+	}
+	
+	@Override
+	public Collection<Long> getSwitchesControlledByController(String controllerId) {
+		// TODO Auto-generated method stub
+		return null;
+	}
 	
 	/*
 	 * IFloodlightModule
@@ -183,7 +266,8 @@
 	
 	@Override
 	public Collection<Class<? extends IFloodlightService>> getModuleServices() {
-		Collection<Class<? extends IFloodlightService>> l = new ArrayList<Class<? extends IFloodlightService>>();
+		Collection<Class<? extends IFloodlightService>> l = 
+				new ArrayList<Class<? extends IFloodlightService>>();
 		l.add(IMastershipService.class);
 		return l;
 	}
@@ -204,7 +288,7 @@
 	
 	@Override
 	public void init (FloodlightModuleContext context) throws FloodlightModuleException {
-
+		/*
 		try {
 			String localHostname = java.net.InetAddress.getLocalHost().getHostName();
 			mastershipId = localHostname;
@@ -224,58 +308,21 @@
 		
 		client = client.usingNamespace(namespace);
 		
-		return;
+		controllerCache = new PathChildrenCache(client, controllerPath, true);
+		
+		try {
+			controllerCache.start(StartMode.BUILD_INITIAL_CACHE);
+			
+			
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	*/
 	}
 	
 	@Override
 	public void startUp (FloodlightModuleContext context) {
 		// Nothing to be done on startup
 	}
-	
-	public static void main(String args[]){
-		FloodlightModuleContext fmc = new FloodlightModuleContext();
-		MastershipManager mm = new MastershipManager();
-		
-		String id = null;
-		if (args.length > 0){
-			id = args[0];
-			log.info("Using unique id: {}", id);
-		}
-		
-		try {
-			mm.init(fmc);
-			mm.startUp(fmc);
-			
-			if (id != null){
-				mm.setMastershipId(id);
-			}
-				
-			mm.acquireMastership(1L, 
-				new MastershipCallback(){
-					@Override
-					public void changeCallback(long dpid, boolean isMaster) {
-						if (isMaster){
-							log.debug("Callback for becoming master for {}", HexString.toHexString(dpid));
-						}
-						else {
-							log.debug("Callback for losing mastership for {}", HexString.toHexString(dpid));
-						}
-					}
-				});
-			
-			//"Server" loop
-			while (true) {
-				Thread.sleep(60000);
-			}
-			
-		} catch (FloodlightModuleException e) {
-			e.printStackTrace();
-		} catch (InterruptedException e) {
-			e.printStackTrace();
-		} catch (Exception e) {
-			e.printStackTrace();
-		}
-		
-		log.debug("is master: {}", mm.amMaster(1L));
-	}
 }
diff --git a/src/main/java/net/floodlightcontroller/mastership/MastershipRunner.java b/src/main/java/net/floodlightcontroller/mastership/MastershipRunner.java
new file mode 100644
index 0000000..a28a9c5
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/mastership/MastershipRunner.java
@@ -0,0 +1,70 @@
+package net.floodlightcontroller.mastership;
+
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.core.module.FloodlightModuleException;
+import net.floodlightcontroller.mastership.IMastershipService.MastershipCallback;
+
+import org.openflow.util.HexString;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Used for lightweight testing of the mastership module without having
+ * to load up the entire ONOS.
+ * @author jono
+ *
+ */
+public class MastershipRunner {
+	protected static Logger log = LoggerFactory.getLogger(MastershipRunner.class);
+
+	public static void main(String args[]){
+		FloodlightModuleContext fmc = new FloodlightModuleContext();
+		MastershipManager mm = new MastershipManager();
+		
+		String id = null;
+		if (args.length > 0){
+			id = args[0];
+			log.info("Using unique id: {}", id);
+		}
+		
+		try {
+			mm.init(fmc);
+			mm.startUp(fmc);
+			
+			if (id != null){
+				mm.setMastershipId(id);
+			}
+				
+			mm.acquireMastership(1L, 
+				new MastershipCallback(){
+					@Override
+					public void changeCallback(long dpid, boolean isMaster) {
+						if (isMaster){
+							log.debug("Callback for becoming master for {}", HexString.toHexString(dpid));
+						}
+						else {
+							log.debug("Callback for losing mastership for {}", HexString.toHexString(dpid));
+						}
+					}
+				});
+			
+			mm.registerController(id);
+			
+			Thread.sleep(5000);
+			
+			//"Server" loop
+			while (true) {
+				Thread.sleep(60000);
+			}
+			
+		} catch (FloodlightModuleException e) {
+			e.printStackTrace();
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		
+		log.debug("is master: {}", mm.amMaster(1L));
+	}
+}
diff --git a/src/main/java/net/floodlightcontroller/mastership/RegistryException.java b/src/main/java/net/floodlightcontroller/mastership/RegistryException.java
new file mode 100644
index 0000000..134117c
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/mastership/RegistryException.java
@@ -0,0 +1,34 @@
+package net.floodlightcontroller.mastership;
+
+public class RegistryException extends Exception {
+
+	private static final long serialVersionUID = -8276300722010217913L;
+
+	/*
+	public RegistryException() {
+		// TODO Auto-generated constructor stub
+	}
+
+	public RegistryException(String message) {
+		super(message);
+		// TODO Auto-generated constructor stub
+	}
+
+	public RegistryException(Throwable cause) {
+		super(cause);
+		// TODO Auto-generated constructor stub
+	}
+
+	public RegistryException(String message, Throwable cause) {
+		super(message, cause);
+		// TODO Auto-generated constructor stub
+	}
+
+	public RegistryException(String message, Throwable cause,
+			boolean enableSuppression, boolean writableStackTrace) {
+		super(message, cause, enableSuppression, writableStackTrace);
+		// TODO Auto-generated constructor stub
+	}
+	*/
+
+}
diff --git a/src/main/java/net/floodlightcontroller/routing/TopoRouteService.java b/src/main/java/net/floodlightcontroller/routing/TopoRouteService.java
index 2c50d29..6d50602 100644
--- a/src/main/java/net/floodlightcontroller/routing/TopoRouteService.java
+++ b/src/main/java/net/floodlightcontroller/routing/TopoRouteService.java
@@ -1,10 +1,17 @@
 package net.floodlightcontroller.routing;
 
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 
 import net.floodlightcontroller.core.internal.SwitchStorageImpl;
+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.floodlightcontroller.core.INetMapTopologyService.ITopoRouteService;
 import net.floodlightcontroller.topology.NodePortTuple;
 
@@ -18,137 +25,184 @@
 import javax.script.ScriptException;
 import com.tinkerpop.gremlin.groovy.jsr223.GremlinGroovyScriptEngine;
 
-public class TopoRouteService implements ITopoRouteService {
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-	ThreadLocal<SwitchStorageImpl> store = new ThreadLocal<SwitchStorageImpl>() {
-	    @Override
-	    protected SwitchStorageImpl initialValue() {
-		SwitchStorageImpl swStore = new SwitchStorageImpl();
-		// NOTE: This is the file path from global properties
-		swStore.init("/tmp/cassandra.titan");
-		return swStore;
-	    }
-	};
+public class TopoRouteService implements IFloodlightModule, ITopoRouteService {
 
-	SwitchStorageImpl swStore = store.get();
+    /** The logger. */
+    private static Logger logger =
+	LoggerFactory.getLogger(TopoRouteService.class);
 
+    @Override
+    public Collection<Class<? extends IFloodlightService>> getModuleServices() {
+        Collection<Class<? extends IFloodlightService>> l = 
+            new ArrayList<Class<? extends IFloodlightService>>();
+        l.add(ITopoRouteService.class);
+        return l;
+    }
+
+    @Override
+    public Map<Class<? extends IFloodlightService>, IFloodlightService> 
+			       getServiceImpls() {
+        Map<Class<? extends IFloodlightService>,
+        IFloodlightService> m = 
+            new HashMap<Class<? extends IFloodlightService>,
+                IFloodlightService>();
+        m.put(ITopoRouteService.class, this);
+        return m;
+    }
+
+    @Override
+    public Collection<Class<? extends IFloodlightService>> 
+                                                    getModuleDependencies() {
+	Collection<Class<? extends IFloodlightService>> l =
+	    new ArrayList<Class<? extends IFloodlightService>>();
+	// TODO: Add the appropriate dependencies
+	// l.add(IRestApiService.class);
+        return l;
+    }
+
+    @Override
+    public void init(FloodlightModuleContext context)
+	throws FloodlightModuleException {
+	// TODO: Add the appropriate initialization
+    }
+
+    @Override
+    public void startUp(FloodlightModuleContext context) {
+	// TODO: Add the approprate setup
+    }
+
+    ThreadLocal<SwitchStorageImpl> store = new ThreadLocal<SwitchStorageImpl>() {
 	@Override
-	public List<NodePortTuple> getShortestPath(NodePortTuple src,
-			NodePortTuple dest) {
-	    List<NodePortTuple> result_list = new ArrayList<NodePortTuple>();
+	protected SwitchStorageImpl initialValue() {
+	    SwitchStorageImpl swStore = new SwitchStorageImpl();
+	    // NOTE: This is the file path from global properties
+	    swStore.init("/tmp/cassandra.titan");
+	    return swStore;
+	}
+    };
 
-	    TitanGraph titanGraph = swStore.graph;
+    SwitchStorageImpl swStore = store.get();
 
-	    String dpid_src = HexString.toHexString(src.getNodeId());
-	    String dpid_dest = HexString.toHexString(dest.getNodeId());
+    @Override
+    public List<NodePortTuple> getShortestPath(NodePortTuple src,
+					       NodePortTuple dest) {
+	List<NodePortTuple> result_list = new ArrayList<NodePortTuple>();
 
-	    //
-	    // Implement the Shortest Path between two vertices by using
-	    // the following Gremlin CLI code:
-	    //   v_src.as("x").out("on").out("link").in("on").dedup().loop("x"){it.object.dpid != v_dest.dpid}.path(){it.dpid}{it.number}{it.number}
-	    // The equivalent code used here is:
-	    //   results = []; v_src.as("x").out("on").out("link").in("on").dedup().loop("x"){it.object.dpid != v_dest.dpid}.path().fill(results)
-	    //
+	TitanGraph titanGraph = swStore.graph;
 
-	    String gremlin = "v_src.as(\"x\").out(\"on\").out(\"link\").in(\"on\").dedup().loop(\"x\"){it.object.dpid != v_dest.dpid}.path().fill(results)";
+	String dpid_src = HexString.toHexString(src.getNodeId());
+	String dpid_dest = HexString.toHexString(dest.getNodeId());
 
-	    // Get the source vertex
-	    Iterator<Vertex> iter = titanGraph.getVertices("dpid", dpid_src).iterator();
-	    if (! iter.hasNext())
-		return null;		// Source vertex not found
-	    Vertex v_src = iter.next();
+	//
+	// Implement the Shortest Path between two vertices by using
+	// the following Gremlin CLI code:
+	//   v_src.as("x").out("on").out("link").in("on").dedup().loop("x"){it.object.dpid != v_dest.dpid}.path(){it.dpid}{it.number}{it.number}
+	// The equivalent code used here is:
+	//   results = []; v_src.as("x").out("on").out("link").in("on").dedup().loop("x"){it.object.dpid != v_dest.dpid}.path().fill(results)
+	//
 
-	    // Get the destination vertex
-	    iter = titanGraph.getVertices("dpid", dpid_dest).iterator();
-	    if (! iter.hasNext())
-		return null;		// Destination vertex not found
-	    Vertex v_dest = iter.next();
+	String gremlin = "v_src.as(\"x\").out(\"on\").out(\"link\").in(\"on\").dedup().loop(\"x\"){it.object.dpid != v_dest.dpid}.path().fill(results)";
 
-	    //
-	    // Test whether we are computing a path from/to the same DPID.
-	    // If "yes", then just list the "src" and "dest" in the return
-	    // result.
-	    // NOTE: The return value will change in the future to return
-	    // a single hop/entry instead of two. Currently, we need
-	    // both entries to capture the source and destination ports.
-	    //
-	    if (dpid_src.equals(dpid_dest)) {
-		result_list.add(new NodePortTuple(src));
-		result_list.add(new NodePortTuple(dest));
-		return result_list;
-	    }
+	// Get the source vertex
+	Iterator<Vertex> iter = titanGraph.getVertices("dpid", dpid_src).iterator();
+	if (! iter.hasNext())
+	    return null;		// Source vertex not found
+	Vertex v_src = iter.next();
 
-	    //
-	    // Implement the Gremlin script and run it
-	    //
-	    ScriptEngine engine = new GremlinGroovyScriptEngine();
+	// Get the destination vertex
+	iter = titanGraph.getVertices("dpid", dpid_dest).iterator();
+	if (! iter.hasNext())
+	    return null;		// Destination vertex not found
+	Vertex v_dest = iter.next();
 
-	    ArrayList<ArrayList<Vertex>> results = new ArrayList<ArrayList<Vertex>>();
-	    engine.getBindings(ScriptContext.ENGINE_SCOPE).put("g", titanGraph);
-	    engine.getBindings(ScriptContext.ENGINE_SCOPE).put("v_src", v_src);
-	    engine.getBindings(ScriptContext.ENGINE_SCOPE).put("v_dest", v_dest);
-	    engine.getBindings(ScriptContext.ENGINE_SCOPE).put("results", results);
+	//
+	// Test whether we are computing a path from/to the same DPID.
+	// If "yes", then just list the "src" and "dest" in the return
+	// result.
+	// NOTE: The return value will change in the future to return
+	// a single hop/entry instead of two. Currently, we need
+	// both entries to capture the source and destination ports.
+	//
+	if (dpid_src.equals(dpid_dest)) {
+	    result_list.add(new NodePortTuple(src));
+	    result_list.add(new NodePortTuple(dest));
+	    return result_list;
+	}
 
-	    try {
-		engine.eval(gremlin);
-	    } catch (ScriptException e) {
-		System.err.println("Caught ScriptException running Gremlin script: " + e.getMessage());
-		return null;
-	    }
+	//
+	// Implement the Gremlin script and run it
+	//
+	ScriptEngine engine = new GremlinGroovyScriptEngine();
 
-	    //
-	    // Loop through the result and return the list
-	    // of <dpid, port> tuples.
-	    //
-	    long nodeId = 0;
-	    short portId = 0;
-	    for (ArrayList<Vertex> lv : results) {
-		int idx = 0;
-		for (Vertex v: lv) {
-		    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);
+	ArrayList<ArrayList<Vertex>> results = new ArrayList<ArrayList<Vertex>>();
+	engine.getBindings(ScriptContext.ENGINE_SCOPE).put("g", titanGraph);
+	engine.getBindings(ScriptContext.ENGINE_SCOPE).put("v_src", v_src);
+	engine.getBindings(ScriptContext.ENGINE_SCOPE).put("v_dest", v_dest);
+	engine.getBindings(ScriptContext.ENGINE_SCOPE).put("results", results);
 
-			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);
-		    }
-		    if (idx == 0) {
-			idx++;
-			continue;
-		    }
-		    int mod = (idx - 1) % 3;
-		    if ((mod == 0) || (mod == 2))  {
-			result_list.add(new NodePortTuple(nodeId, portId));
-		    }
-		    idx++;
-		}
-	    }
-	    if (result_list.size() > 0)
-		return result_list;
-
+	try {
+	    engine.eval(gremlin);
+	} catch (ScriptException e) {
+	    System.err.println("Caught ScriptException running Gremlin script: " + e.getMessage());
 	    return null;
 	}
 
-	@Override
-	public Boolean routeExists(NodePortTuple src, NodePortTuple dest) {
-		List<NodePortTuple> route = getShortestPath(src, dest);
-		if (route != null)
-		    return true;
-		return false;
+	//
+	// Loop through the result and return the list
+	// of <dpid, port> tuples.
+	//
+	long nodeId = 0;
+	short portId = 0;
+	for (ArrayList<Vertex> lv : results) {
+	    int idx = 0;
+	    for (Vertex v: lv) {
+		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);
+		}
+		if (idx == 0) {
+		    idx++;
+		    continue;
+		}
+		int mod = (idx - 1) % 3;
+		if ((mod == 0) || (mod == 2))  {
+		    result_list.add(new NodePortTuple(nodeId, portId));
+		}
+		idx++;
+	    }
 	}
+	if (result_list.size() > 0)
+	    return result_list;
+
+	return null;
+    }
+
+    @Override
+    public Boolean routeExists(NodePortTuple src, NodePortTuple dest) {
+	List<NodePortTuple> route = getShortestPath(src, dest);
+	if (route != null)
+	    return true;
+	return false;
+    }
 }
diff --git a/src/main/java/net/floodlightcontroller/routing/TopoRouteServiceImpl.java b/src/main/java/net/floodlightcontroller/routing/TopoRouteServiceImpl.java
deleted file mode 100644
index 2ba6097..0000000
--- a/src/main/java/net/floodlightcontroller/routing/TopoRouteServiceImpl.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package net.floodlightcontroller.routing;
-
-import java.util.List;
-
-import net.floodlightcontroller.core.INetMapTopologyService.ITopoRouteService;
-import net.floodlightcontroller.topology.NodePortTuple;
-
-public class TopoRouteServiceImpl implements ITopoRouteService {
-
-	@Override
-	public List<NodePortTuple> getShortestPath(NodePortTuple src,
-			NodePortTuple dest) {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	@Override
-	public Boolean routeExists(NodePortTuple src, NodePortTuple dest) {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-}
diff --git a/src/main/java/net/floodlightcontroller/topology/web/RouteResource.java b/src/main/java/net/floodlightcontroller/topology/web/RouteResource.java
index fd9d201..3fa7510 100644
--- a/src/main/java/net/floodlightcontroller/topology/web/RouteResource.java
+++ b/src/main/java/net/floodlightcontroller/topology/web/RouteResource.java
@@ -2,11 +2,10 @@
 
 import java.util.List;
 
+import net.floodlightcontroller.core.INetMapTopologyService.ITopoRouteService;
 import net.floodlightcontroller.routing.IRoutingService;
 import net.floodlightcontroller.routing.Route;
-import net.floodlightcontroller.routing.TopoRouteService;
 import net.floodlightcontroller.topology.NodePortTuple;
-import net.floodlightcontroller.core.INetMapTopologyService.ITopoRouteService;
 
 import org.openflow.util.HexString;
 import org.restlet.resource.Get;
@@ -20,14 +19,11 @@
 
     @Get("json")
     public List<NodePortTuple> retrieve() {
-	/*
-        IRoutingService routing = 
-                (IRoutingService)getContext().getAttributes().
-                    get(IRoutingService.class.getCanonicalName());
-	*/
-	ITopoRouteService onos_routing = new TopoRouteService();
-	if (onos_routing == null) {
-	    log.debug("ONOS Route Service not found");
+        ITopoRouteService topoRouteService = 
+                (ITopoRouteService)getContext().getAttributes().
+                    get(ITopoRouteService.class.getCanonicalName());
+	if (topoRouteService == null) {
+	    log.debug("Topology Route Service not found");
 	    return null;
 	}
         
@@ -43,16 +39,9 @@
         long longDstDpid = HexString.toLong(dstDpid);
         short shortDstPort = Short.parseShort(dstPort);
         
-	/*
-        Route result = routing.getRoute(longSrcDpid, shortSrcPort, longDstDpid, shortDstPort);
-        
-        if (result!=null) {
-            return routing.getRoute(longSrcDpid, shortSrcPort, longDstDpid, shortDstPort).getPath();
-        }
-	*/
 	List<NodePortTuple> result =
-	    onos_routing.getShortestPath(new NodePortTuple(longSrcDpid, shortSrcPort),
-					 new NodePortTuple(longDstDpid, shortDstPort));
+	    topoRouteService.getShortestPath(new NodePortTuple(longSrcDpid, shortSrcPort),
+					     new NodePortTuple(longDstDpid, shortDstPort));
 	if ((result != null) && (result.size() > 0)) {
 	    return result;
 	} else {
diff --git a/src/main/java/net/floodlightcontroller/util/CallerId.java b/src/main/java/net/floodlightcontroller/util/CallerId.java
index 898da31..200b9e0 100644
--- a/src/main/java/net/floodlightcontroller/util/CallerId.java
+++ b/src/main/java/net/floodlightcontroller/util/CallerId.java
@@ -1,8 +1,14 @@
 package net.floodlightcontroller.util;
 
+import net.floodlightcontroller.util.serializers.CallerIdSerializer;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
 /**
  * The class representing a Caller ID for an ONOS component.
  */
+@JsonSerialize(using=CallerIdSerializer.class)
 public class CallerId {
     private String value;
 
diff --git a/src/main/java/net/floodlightcontroller/util/DataPath.java b/src/main/java/net/floodlightcontroller/util/DataPath.java
index 2374fbe..ad6cdb8 100644
--- a/src/main/java/net/floodlightcontroller/util/DataPath.java
+++ b/src/main/java/net/floodlightcontroller/util/DataPath.java
@@ -4,10 +4,15 @@
 
 import net.floodlightcontroller.util.SwitchPort;
 import net.floodlightcontroller.util.FlowEntry;
+import net.floodlightcontroller.util.serializers.DataPathSerializer;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
 
 /**
  * The class representing the Data Path.
  */
+@JsonSerialize(using=DataPathSerializer.class)
 public class DataPath {
     private SwitchPort srcPort;		// The source port
     private SwitchPort dstPort;		// The destination port
@@ -70,12 +75,20 @@
     /**
      * Convert the data path to a string.
      *
+     * The string has the following form:
+     * [src=01:01:01:01:01:01:01:01/1111 flowEntry=<entry1> flowEntry=<entry2> flowEntry=<entry3> dst=02:02:02:02:02:02:02:02/2222]
+     *
      * @return the data path as a string.
      */
     @Override
     public String toString() {
-	String ret = "";
-	// TODO: Implement it!
+	String ret = "[src=" + this.srcPort.toString();
+
+	for (FlowEntry fe : flowEntries) {
+	    ret += " flowEntry=" + fe.toString();
+	}
+	ret += " dst=" + this.dstPort.toString() + "]";
+
 	return ret;
     }
 }
diff --git a/src/main/java/net/floodlightcontroller/util/DataPathEndpoints.java b/src/main/java/net/floodlightcontroller/util/DataPathEndpoints.java
index 5c9e02c..92cf2dd 100644
--- a/src/main/java/net/floodlightcontroller/util/DataPathEndpoints.java
+++ b/src/main/java/net/floodlightcontroller/util/DataPathEndpoints.java
@@ -1,10 +1,15 @@
 package net.floodlightcontroller.util;
 
 import net.floodlightcontroller.util.SwitchPort;
+import net.floodlightcontroller.util.serializers.DataPathEndpointsSerializer;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
 
 /**
  * The class representing the Data Path Endpoints.
  */
+@JsonSerialize(using=DataPathEndpointsSerializer.class)
 public class DataPathEndpoints {
     private SwitchPort srcPort;		// The source port
     private SwitchPort dstPort;		// The destination port
@@ -61,12 +66,15 @@
     /**
      * Convert the data path endpoints to a string.
      *
+     * The string has the following form:
+     * [src=01:01:01:01:01:01:01:01/1111 dst=02:02:02:02:02:02:02:02/2222]
+     *
      * @return the data path endpoints as a string.
      */
     @Override
     public String toString() {
-	String ret = "";
-	// TODO: Implement it!
+	String ret = "[src=" + this.srcPort.toString() +
+	    " dst=" + this.dstPort.toString() + "]";
 	return ret;
     }
 }
diff --git a/src/main/java/net/floodlightcontroller/util/Dpid.java b/src/main/java/net/floodlightcontroller/util/Dpid.java
index 3a8d1e8..7787953 100644
--- a/src/main/java/net/floodlightcontroller/util/Dpid.java
+++ b/src/main/java/net/floodlightcontroller/util/Dpid.java
@@ -1,8 +1,15 @@
 package net.floodlightcontroller.util;
 
+import org.openflow.util.HexString;
+import net.floodlightcontroller.util.serializers.DpidSerializer;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
 /**
  * The class representing a network switch DPID.
  */
+@JsonSerialize(using=DpidSerializer.class)
 public class Dpid {
     static public long UNKNOWN = 0;
 
@@ -41,14 +48,12 @@
     }
 
     /**
-     * Convert the DPID value to a ':' separated hex string.
+     * Convert the DPID value to a ':' separated hexadecimal string.
      *
-     * @return the DPID value as a ':' separated hex string.
+     * @return the DPID value as a ':' separated hexadecimal string.
      */
     @Override
     public String toString() {
-	String ret = "";
-	// TODO: Implement it!
-	return ret;
+	return HexString.toHexString(this.value);
     }
 }
diff --git a/src/main/java/net/floodlightcontroller/util/FlowEntry.java b/src/main/java/net/floodlightcontroller/util/FlowEntry.java
index e9c4bbe..42ec935 100644
--- a/src/main/java/net/floodlightcontroller/util/FlowEntry.java
+++ b/src/main/java/net/floodlightcontroller/util/FlowEntry.java
@@ -5,6 +5,10 @@
 import net.floodlightcontroller.util.FlowEntryId;
 import net.floodlightcontroller.util.FlowEntryMatch;
 import net.floodlightcontroller.util.Port;
+import net.floodlightcontroller.util.serializers.FlowEntrySerializer;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
 
 /**
  * The Flow Entry state as set by the user (via the ONOS API).
@@ -34,6 +38,7 @@
  * NOTE: The specification is incomplete. E.g., the entry needs to
  * support multiple in-ports and multiple out-ports.
  */
+@JsonSerialize(using=FlowEntrySerializer.class)
 public class FlowEntry {
     private FlowEntryId flowEntryId;		// The Flow Entry ID
     private FlowEntryMatch flowEntryMatch;	// The Flow Entry Match
@@ -213,12 +218,25 @@
     /**
      * Convert the flow entry to a string.
      *
+     * The string has the following form:
+     *  [flowEntryId=XXX flowEntryMatch=XXX flowEntryActions=XXX dpid=XXX
+     *   inPort=XXX outPort=XXX flowEntryUserState=XXX flowEntrySwitchState=XXX
+     *   flowEntryErrorState=XXX]
      * @return the flow entry as a string.
      */
     @Override
     public String toString() {
-	String ret = "";
-	// TODO: Implement it!
+	String ret = "[flowEntryId=" + this.flowEntryId.toString();
+	ret += " flowEntryMatch=" + this.flowEntryMatch.toString();
+	ret += " flowEntryActions=" + this.flowEntryActions.toString();
+	ret += " dpid=" + this.dpid.toString();
+	ret += " inPort=" + this.inPort.toString();
+	ret += " outPort=" + this.outPort.toString();
+	ret += " flowEntryUserState=" + this.flowEntryUserState;
+	ret += " flowEntrySwitchState=" + this.flowEntrySwitchState;
+	ret += " flowEntryErrorState=" + this.flowEntryErrorState.toString();
+	ret += "]";
+
 	return ret;
     }
 }
diff --git a/src/main/java/net/floodlightcontroller/util/FlowEntryActions.java b/src/main/java/net/floodlightcontroller/util/FlowEntryActions.java
index 90f42fb..b683d2c 100644
--- a/src/main/java/net/floodlightcontroller/util/FlowEntryActions.java
+++ b/src/main/java/net/floodlightcontroller/util/FlowEntryActions.java
@@ -1,5 +1,10 @@
 package net.floodlightcontroller.util;
 
+import net.floodlightcontroller.util.serializers.FlowEntryActionsSerializer;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
 /**
  * The class representing the Flow Entry set of actions.
  *
@@ -8,6 +13,7 @@
  * NOTE: This is just an empty placeholder (for now). The implied action is
  * forwarding on a single port.
  */
+@JsonSerialize(using=FlowEntryActionsSerializer.class)
 public class FlowEntryActions {
 
     /**
diff --git a/src/main/java/net/floodlightcontroller/util/FlowEntryErrorState.java b/src/main/java/net/floodlightcontroller/util/FlowEntryErrorState.java
index 63c103d..f9ca8ba 100644
--- a/src/main/java/net/floodlightcontroller/util/FlowEntryErrorState.java
+++ b/src/main/java/net/floodlightcontroller/util/FlowEntryErrorState.java
@@ -1,8 +1,14 @@
 package net.floodlightcontroller.util;
 
+import net.floodlightcontroller.util.serializers.FlowEntryErrorStateSerializer;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
 /**
  * The class representing the Flow Entry error state.
  */
+@JsonSerialize(using=FlowEntryErrorStateSerializer.class)
 public class FlowEntryErrorState {
     private short type;	// The error type (e.g., see OF-1.3.1 spec, pp. 95)
     private short code;	// The error code (e.g., see OF-1.3.1 spec, pp. 95)
@@ -54,12 +60,14 @@
     /**
      * Convert the error type and code to a string.
      *
+     * The string has the following form:
+     * [type=1 code=2]
+     *
      * @return the error type and code as a string.
      */
     @Override
     public String toString() {
-	String ret = "";
-	// TODO: Implement it!
+	String ret = "[type=" + this.type + " code=" + code + "]";
 	return ret;
     }
 }
diff --git a/src/main/java/net/floodlightcontroller/util/FlowEntryId.java b/src/main/java/net/floodlightcontroller/util/FlowEntryId.java
index 4736ed5..bf1fc7d 100644
--- a/src/main/java/net/floodlightcontroller/util/FlowEntryId.java
+++ b/src/main/java/net/floodlightcontroller/util/FlowEntryId.java
@@ -1,8 +1,14 @@
 package net.floodlightcontroller.util;
 
+import net.floodlightcontroller.util.serializers.FlowEntryIdSerializer;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
 /**
  * The class representing a Flow Entry ID.
  */
+@JsonSerialize(using=FlowEntryIdSerializer.class)
 public class FlowEntryId {
     private long value;
 
@@ -39,14 +45,12 @@
     }
 
     /**
-     * Convert the Flow Entry ID value to a string.
+     * Convert the Flow Entry ID value to a hexadecimal string.
      *
-     * @return the Flow Entry ID value to a string.
+     * @return the Flow Entry ID value to a hexadecimal string.
      */
     @Override
     public String toString() {
-	String ret = "";
-	// TODO: Implement it!
-	return ret;
+	return Long.toHexString(this.value);
     }
 }
diff --git a/src/main/java/net/floodlightcontroller/util/FlowEntryMatch.java b/src/main/java/net/floodlightcontroller/util/FlowEntryMatch.java
index a8f43f5..0e3775e 100644
--- a/src/main/java/net/floodlightcontroller/util/FlowEntryMatch.java
+++ b/src/main/java/net/floodlightcontroller/util/FlowEntryMatch.java
@@ -2,6 +2,10 @@
 
 import net.floodlightcontroller.util.MACAddress;
 import net.floodlightcontroller.util.IPv4Net;
+import net.floodlightcontroller.util.serializers.FlowEntryMatchSerializer;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
 
 /**
  * The class representing the Flow Entry Matching filter.
@@ -15,6 +19,7 @@
  * more matching fields, we need to indicate which fields need to be
  * matched, etc.
  */
+@JsonSerialize(using=FlowEntryMatchSerializer.class)
 public class FlowEntryMatch {
     private MACAddress srcMac;		// Matching source MAC address
     private MACAddress dstMac;		// Matching destination MAC address
@@ -94,12 +99,18 @@
     /**
      * Convert the matching filter to a string.
      *
+     * The string has the following form:
+     *  [srcMac=XXX dstMac=XXX srcIPv4Net=XXX dstIPv4Net=XXX]
+     *
      * @return the matching filter as a string.
      */
     @Override
     public String toString() {
-	String ret = "";
-	// TODO: Implement it!
+	String ret = "[srcMac=" + this.srcMac.toString();
+	ret += " dstMac=" + this.dstMac.toString();
+	ret += " srcIPv4Net=" + this.srcIPv4Net.toString();
+	ret += " dstIPv4Net=" + this.dstIPv4Net.toString();
+	ret += "]";
 	return ret;
     }
 }
diff --git a/src/main/java/net/floodlightcontroller/util/FlowId.java b/src/main/java/net/floodlightcontroller/util/FlowId.java
index 827c1d9..a8beaa0 100644
--- a/src/main/java/net/floodlightcontroller/util/FlowId.java
+++ b/src/main/java/net/floodlightcontroller/util/FlowId.java
@@ -1,8 +1,14 @@
 package net.floodlightcontroller.util;
 
+import net.floodlightcontroller.util.serializers.FlowIdSerializer;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
 /**
  * The class representing a Flow ID.
  */
+@JsonSerialize(using=FlowIdSerializer.class)
 public class FlowId {
     private long value;
 
@@ -39,14 +45,12 @@
     }
 
     /**
-     * Convert the Flow ID value to a string.
+     * Convert the Flow ID value to a hexadecimal string.
      *
-     * @return the Flow ID value to a string.
+     * @return the Flow ID value to a hexadecimal string.
      */
     @Override
     public String toString() {
-	String ret = "";
-	// TODO: Implement it!
-	return ret;
+	return "0x" + Long.toHexString(this.value);
     }
 }
diff --git a/src/main/java/net/floodlightcontroller/util/FlowPath.java b/src/main/java/net/floodlightcontroller/util/FlowPath.java
index 46a1f82..f91bb4a 100644
--- a/src/main/java/net/floodlightcontroller/util/FlowPath.java
+++ b/src/main/java/net/floodlightcontroller/util/FlowPath.java
@@ -3,10 +3,15 @@
 import net.floodlightcontroller.util.CallerId;
 import net.floodlightcontroller.util.DataPath;
 import net.floodlightcontroller.util.FlowId;
+import net.floodlightcontroller.util.serializers.FlowPathSerializer;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
 
 /**
  * The class representing the Flow Path.
  */
+@JsonSerialize(using=FlowPathSerializer.class)
 public class FlowPath {
     private FlowId flowId;		// The Flow ID
     private CallerId installerId;	// The Caller ID of the path installer
@@ -19,6 +24,13 @@
     }
 
     /**
+     * Constructor from a string.
+     */
+    public FlowPath(String str) {
+	// TODO: Implement it.
+    }
+
+    /**
      * Get the flow path Flow ID.
      *
      * @return the flow path Flow ID.
@@ -69,12 +81,17 @@
     /**
      * Convert the flow path to a string.
      *
+     * The string has the following form:
+     *  [flowId=XXX installerId=XXX dataPath=XXX]
+     *
      * @return the flow path as a string.
      */
     @Override
     public String toString() {
-	String ret = "";
-	// TODO: Implement it!
+	String ret = "[flowId=" + this.flowId.toString();
+	ret += " installerId=" + this.installerId.toString();
+	ret += " dataPath=" + this.dataPath.toString();
+	ret += "]";
 	return ret;
     }
 }
diff --git a/src/main/java/net/floodlightcontroller/util/IPv4.java b/src/main/java/net/floodlightcontroller/util/IPv4.java
index b4fc787..3f4f350 100644
--- a/src/main/java/net/floodlightcontroller/util/IPv4.java
+++ b/src/main/java/net/floodlightcontroller/util/IPv4.java
@@ -1,8 +1,14 @@
 package net.floodlightcontroller.util;
 
+import net.floodlightcontroller.util.serializers.IPv4Serializer;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
 /**
  * The class representing an IPv4 address.
  */
+@JsonSerialize(using=IPv4Serializer.class)
 public class IPv4 {
     private int value;
 
@@ -45,8 +51,9 @@
      */
     @Override
     public String toString() {
-	String ret = "";
-	// TODO: Implement it!
-	return ret;
+	return ((this.value >> 24) & 0xFF) + "." +
+	    ((this.value >> 16) & 0xFF) + "." +
+	    ((this.value >> 8) & 0xFF) + "." +
+	    (this.value & 0xFF);
     }
 }
diff --git a/src/main/java/net/floodlightcontroller/util/IPv4Net.java b/src/main/java/net/floodlightcontroller/util/IPv4Net.java
index 6c4c651..f64ccb8 100644
--- a/src/main/java/net/floodlightcontroller/util/IPv4Net.java
+++ b/src/main/java/net/floodlightcontroller/util/IPv4Net.java
@@ -1,10 +1,15 @@
 package net.floodlightcontroller.util;
 
 import net.floodlightcontroller.util.IPv4;
+import net.floodlightcontroller.util.serializers.IPv4NetSerializer;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
 
 /**
  * The class representing an IPv4 network address.
  */
+@JsonSerialize(using=IPv4NetSerializer.class)
 public class IPv4Net {
     private IPv4 address;		// The IPv4 address
     private short prefixLen;		// The prefix length
@@ -59,8 +64,6 @@
      */
     @Override
     public String toString() {
-	String ret = "";
-	// TODO: Implement it!
-	return ret;
+	return this.address.toString() + "/" + this.prefixLen;
     }
 }
diff --git a/src/main/java/net/floodlightcontroller/util/IPv6.java b/src/main/java/net/floodlightcontroller/util/IPv6.java
index dfa071b..d4461c0 100644
--- a/src/main/java/net/floodlightcontroller/util/IPv6.java
+++ b/src/main/java/net/floodlightcontroller/util/IPv6.java
@@ -1,8 +1,15 @@
 package net.floodlightcontroller.util;
 
+import org.openflow.util.HexString;
+import net.floodlightcontroller.util.serializers.IPv6Serializer;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
 /**
  * The class representing an IPv6 address.
  */
+@JsonSerialize(using=IPv6Serializer.class)
 public class IPv6 {
     private long valueHigh;	// The higher (more significant) 64 bits
     private long valueLow;	// The lower (less significant) 64 bits
@@ -60,8 +67,7 @@
      */
     @Override
     public String toString() {
-	String ret = "";
-	// TODO: Implement it!
-	return ret;
+	return HexString.toHexString(this.valueHigh) + ":" +
+	    HexString.toHexString(this.valueLow);
     }
 }
diff --git a/src/main/java/net/floodlightcontroller/util/IPv6Net.java b/src/main/java/net/floodlightcontroller/util/IPv6Net.java
index 85de4f7..1942293 100644
--- a/src/main/java/net/floodlightcontroller/util/IPv6Net.java
+++ b/src/main/java/net/floodlightcontroller/util/IPv6Net.java
@@ -1,10 +1,15 @@
 package net.floodlightcontroller.util;
 
 import net.floodlightcontroller.util.IPv6;
+import net.floodlightcontroller.util.serializers.IPv6NetSerializer;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
 
 /**
  * The class representing an IPv6 network address.
  */
+@JsonSerialize(using=IPv6NetSerializer.class)
 public class IPv6Net {
     private IPv6 address;		// The IPv6 address
     private short prefixLen;		// The prefix length
@@ -59,8 +64,6 @@
      */
     @Override
     public String toString() {
-	String ret = "";
-	// TODO: Implement it!
-	return ret;
+	return this.address.toString() + "/" + this.prefixLen;
     }
 }
diff --git a/src/main/java/net/floodlightcontroller/util/Port.java b/src/main/java/net/floodlightcontroller/util/Port.java
index 8fbb727..0bfb07a 100644
--- a/src/main/java/net/floodlightcontroller/util/Port.java
+++ b/src/main/java/net/floodlightcontroller/util/Port.java
@@ -1,8 +1,14 @@
 package net.floodlightcontroller.util;
 
+import net.floodlightcontroller.util.serializers.PortSerializer;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
 /**
  * The class representing a network port of a switch.
  */
+@JsonSerialize(using=PortSerializer.class)
 public class Port {
     private short value;
 
@@ -45,8 +51,6 @@
      */
     @Override
     public String toString() {
-	String ret = "";
-	// TODO: Implement it!
-	return ret;
+	return Short.toString(this.value);
     }
 }
diff --git a/src/main/java/net/floodlightcontroller/util/SwitchPort.java b/src/main/java/net/floodlightcontroller/util/SwitchPort.java
index 31061bc..462cdfb 100644
--- a/src/main/java/net/floodlightcontroller/util/SwitchPort.java
+++ b/src/main/java/net/floodlightcontroller/util/SwitchPort.java
@@ -2,10 +2,15 @@
 
 import net.floodlightcontroller.util.Dpid;
 import net.floodlightcontroller.util.Port;
+import net.floodlightcontroller.util.serializers.SwitchPortSerializer;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
 
 /**
  * The class representing a Switch-Port.
  */
+@JsonSerialize(using=SwitchPortSerializer.class)
 public class SwitchPort {
     private Dpid dpid;		// The DPID of the switch
     private Port port;		// The port of the switch
@@ -55,12 +60,13 @@
     /**
      * Convert the Switch-Port value to a string.
      *
+     * The string has the following form:
+     *  01:02:03:04:05:06:07:08/1234
+     *
      * @return the Switch-Port value as a string.
      */
     @Override
     public String toString() {
-	String ret = "";
-	// TODO: Implement it!
-	return ret;
+	return this.dpid.toString() + "/" + this.port;
     }
 }
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/CallerIdSerializer.java b/src/main/java/net/floodlightcontroller/util/serializers/CallerIdSerializer.java
new file mode 100644
index 0000000..9935324
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/util/serializers/CallerIdSerializer.java
@@ -0,0 +1,23 @@
+package net.floodlightcontroller.util.serializers;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.map.JsonSerializer;
+import org.codehaus.jackson.map.SerializerProvider;
+
+import net.floodlightcontroller.util.CallerId;
+
+/**
+ * Serialize a Caller ID as a string.
+ */
+public class CallerIdSerializer extends JsonSerializer<CallerId> {
+
+    @Override
+    public void serialize(CallerId callerId, JsonGenerator jGen,
+			  SerializerProvider serializer)
+	throws IOException, JsonProcessingException {
+	jGen.writeString(callerId.toString());
+    }
+}
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/DataPathEndpointsSerializer.java b/src/main/java/net/floodlightcontroller/util/serializers/DataPathEndpointsSerializer.java
new file mode 100644
index 0000000..e05c21d
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/util/serializers/DataPathEndpointsSerializer.java
@@ -0,0 +1,26 @@
+package net.floodlightcontroller.util.serializers;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.map.JsonSerializer;
+import org.codehaus.jackson.map.SerializerProvider;
+
+import net.floodlightcontroller.util.DataPathEndpoints;
+
+/**
+ * Serialize a DataPathEndpoints as a string.
+ */
+public class DataPathEndpointsSerializer extends JsonSerializer<DataPathEndpoints> {
+
+    @Override
+    public void serialize(DataPathEndpoints dataPathEndpoints,
+			  JsonGenerator jGen, SerializerProvider serializer)
+	throws IOException, JsonProcessingException {
+	jGen.writeStartObject();
+	jGen.writeObjectField("srcPort", dataPathEndpoints.srcPort());
+	jGen.writeObjectField("dstPort", dataPathEndpoints.dstPort());
+	jGen.writeEndObject();
+    }
+}
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/DataPathSerializer.java b/src/main/java/net/floodlightcontroller/util/serializers/DataPathSerializer.java
new file mode 100644
index 0000000..d150c37
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/util/serializers/DataPathSerializer.java
@@ -0,0 +1,32 @@
+package net.floodlightcontroller.util.serializers;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.map.JsonSerializer;
+import org.codehaus.jackson.map.SerializerProvider;
+
+import net.floodlightcontroller.util.DataPath;
+import net.floodlightcontroller.util.FlowEntry;
+
+/**
+ * Serialize a DataPath as a string.
+ */
+public class DataPathSerializer extends JsonSerializer<DataPath> {
+
+    @Override
+    public void serialize(DataPath dataPath,
+			  JsonGenerator jGen, SerializerProvider serializer)
+	throws IOException, JsonProcessingException {
+	jGen.writeStartObject();
+	jGen.writeObjectField("srcPort", dataPath.srcPort());
+	jGen.writeArrayFieldStart("flowEntries");
+	for (FlowEntry fe: dataPath.flowEntries()) {
+	    jGen.writeObject(fe);
+	}
+	jGen.writeEndArray();
+	jGen.writeObjectField("dstPort", dataPath.dstPort());
+	jGen.writeEndObject();
+    }
+}
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/DpidSerializer.java b/src/main/java/net/floodlightcontroller/util/serializers/DpidSerializer.java
new file mode 100644
index 0000000..2b71690
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/util/serializers/DpidSerializer.java
@@ -0,0 +1,23 @@
+package net.floodlightcontroller.util.serializers;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.map.JsonSerializer;
+import org.codehaus.jackson.map.SerializerProvider;
+
+import net.floodlightcontroller.util.Dpid;
+
+/**
+ * Serialize a DPID as a string.
+ */
+public class DpidSerializer extends JsonSerializer<Dpid> {
+
+    @Override
+    public void serialize(Dpid dpid, JsonGenerator jGen,
+			  SerializerProvider serializer)
+	throws IOException, JsonProcessingException {
+	jGen.writeString(dpid.toString());
+    }
+}
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/FlowEntryActionsSerializer.java b/src/main/java/net/floodlightcontroller/util/serializers/FlowEntryActionsSerializer.java
new file mode 100644
index 0000000..bd5970d
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/util/serializers/FlowEntryActionsSerializer.java
@@ -0,0 +1,24 @@
+package net.floodlightcontroller.util.serializers;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.map.JsonSerializer;
+import org.codehaus.jackson.map.SerializerProvider;
+
+import net.floodlightcontroller.util.FlowEntryActions;
+
+/**
+ * Serialize a FlowEntryActions as a string.
+ */
+public class FlowEntryActionsSerializer extends JsonSerializer<FlowEntryActions> {
+
+    @Override
+    public void serialize(FlowEntryActions flowEntryActions,
+			  JsonGenerator jGen,
+			  SerializerProvider serializer)
+	throws IOException, JsonProcessingException {
+	jGen.writeObject(flowEntryActions);
+    }
+}
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/FlowEntryErrorStateSerializer.java b/src/main/java/net/floodlightcontroller/util/serializers/FlowEntryErrorStateSerializer.java
new file mode 100644
index 0000000..2518e86
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/util/serializers/FlowEntryErrorStateSerializer.java
@@ -0,0 +1,26 @@
+package net.floodlightcontroller.util.serializers;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.map.JsonSerializer;
+import org.codehaus.jackson.map.SerializerProvider;
+
+import net.floodlightcontroller.util.FlowEntryErrorState;
+
+/**
+ * Serialize a Flow Entry Error State as a string.
+ */
+public class FlowEntryErrorStateSerializer extends JsonSerializer<FlowEntryErrorState> {
+
+    @Override
+    public void serialize(FlowEntryErrorState flowEntryErrorState,
+			  JsonGenerator jGen, SerializerProvider serializer)
+	throws IOException, JsonProcessingException {
+	jGen.writeStartObject();
+	jGen.writeNumberField("type", flowEntryErrorState.type());
+	jGen.writeNumberField("code", flowEntryErrorState.code());
+	jGen.writeEndObject();
+    }
+}
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/FlowEntryIdSerializer.java b/src/main/java/net/floodlightcontroller/util/serializers/FlowEntryIdSerializer.java
new file mode 100644
index 0000000..4b6583c
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/util/serializers/FlowEntryIdSerializer.java
@@ -0,0 +1,23 @@
+package net.floodlightcontroller.util.serializers;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.map.JsonSerializer;
+import org.codehaus.jackson.map.SerializerProvider;
+
+import net.floodlightcontroller.util.FlowEntryId;
+
+/**
+ * Serialize a Flow Entry ID as a hexadecimal string.
+ */
+public class FlowEntryIdSerializer extends JsonSerializer<FlowEntryId> {
+
+    @Override
+    public void serialize(FlowEntryId flowEntryId, JsonGenerator jGen,
+			  SerializerProvider serializer)
+	throws IOException, JsonProcessingException {
+	jGen.writeString(flowEntryId.toString());
+    }
+}
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/FlowEntryMatchSerializer.java b/src/main/java/net/floodlightcontroller/util/serializers/FlowEntryMatchSerializer.java
new file mode 100644
index 0000000..0de3b08
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/util/serializers/FlowEntryMatchSerializer.java
@@ -0,0 +1,28 @@
+package net.floodlightcontroller.util.serializers;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.map.JsonSerializer;
+import org.codehaus.jackson.map.SerializerProvider;
+
+import net.floodlightcontroller.util.FlowEntryMatch;
+
+/**
+ * Serialize a FlowEntryMatch as a string.
+ */
+public class FlowEntryMatchSerializer extends JsonSerializer<FlowEntryMatch> {
+
+    @Override
+    public void serialize(FlowEntryMatch flowEntryMatch,
+			  JsonGenerator jGen, SerializerProvider serializer)
+	throws IOException, JsonProcessingException {
+	jGen.writeStartObject();
+	jGen.writeObjectField("srcMac", flowEntryMatch.srcMac());
+	jGen.writeObjectField("dstMac", flowEntryMatch.dstMac());
+	jGen.writeObjectField("srcIPv4Net", flowEntryMatch.srcIPv4Net());
+	jGen.writeObjectField("dstIPv4Net", flowEntryMatch.dstIPv4Net());
+	jGen.writeEndObject();
+    }
+}
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/FlowEntrySerializer.java b/src/main/java/net/floodlightcontroller/util/serializers/FlowEntrySerializer.java
new file mode 100644
index 0000000..9912d55
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/util/serializers/FlowEntrySerializer.java
@@ -0,0 +1,37 @@
+package net.floodlightcontroller.util.serializers;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.map.JsonSerializer;
+import org.codehaus.jackson.map.SerializerProvider;
+
+import net.floodlightcontroller.util.FlowEntry;
+
+/**
+ * Serialize a FlowEntry as a string.
+ */
+public class FlowEntrySerializer extends JsonSerializer<FlowEntry> {
+
+    @Override
+    public void serialize(FlowEntry flowEntry,
+			  JsonGenerator jGen, SerializerProvider serializer)
+	throws IOException, JsonProcessingException {
+	jGen.writeStartObject();
+	jGen.writeObjectField("flowEntryId", flowEntry.flowEntryId());
+	jGen.writeObjectField("flowEntryMatch", flowEntry.flowEntryMatch());
+	jGen.writeObjectField("flowEntryActions",
+			      flowEntry.flowEntryActions());
+	jGen.writeObjectField("dpid", flowEntry.dpid());
+	jGen.writeObjectField("inPort", flowEntry.inPort());
+	jGen.writeObjectField("outPort", flowEntry.outPort());
+	jGen.writeObjectField("flowEntryUserState",
+			      flowEntry.flowEntryUserState());
+	jGen.writeObjectField("flowEntrySwitchState",
+			      flowEntry.flowEntrySwitchState());
+	jGen.writeObjectField("flowEntryErrorState",
+			      flowEntry.flowEntryErrorState());
+	jGen.writeEndObject();
+    }
+}
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/FlowIdSerializer.java b/src/main/java/net/floodlightcontroller/util/serializers/FlowIdSerializer.java
new file mode 100644
index 0000000..0e69273
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/util/serializers/FlowIdSerializer.java
@@ -0,0 +1,23 @@
+package net.floodlightcontroller.util.serializers;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.map.JsonSerializer;
+import org.codehaus.jackson.map.SerializerProvider;
+
+import net.floodlightcontroller.util.FlowId;
+
+/**
+ * Serialize a Flow ID as a hexadecimal string.
+ */
+public class FlowIdSerializer extends JsonSerializer<FlowId> {
+
+    @Override
+    public void serialize(FlowId flowId, JsonGenerator jGen,
+			  SerializerProvider serializer)
+	throws IOException, JsonProcessingException {
+	jGen.writeString(flowId.toString());
+    }
+}
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/FlowPathSerializer.java b/src/main/java/net/floodlightcontroller/util/serializers/FlowPathSerializer.java
new file mode 100644
index 0000000..a6a5405
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/util/serializers/FlowPathSerializer.java
@@ -0,0 +1,27 @@
+package net.floodlightcontroller.util.serializers;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.map.JsonSerializer;
+import org.codehaus.jackson.map.SerializerProvider;
+
+import net.floodlightcontroller.util.FlowPath;
+
+/**
+ * Serialize a FlowPath as a string.
+ */
+public class FlowPathSerializer extends JsonSerializer<FlowPath> {
+
+    @Override
+    public void serialize(FlowPath flowPath,
+			  JsonGenerator jGen, SerializerProvider serializer)
+	throws IOException, JsonProcessingException {
+	jGen.writeStartObject();
+	jGen.writeObjectField("flowId", flowPath.flowId());
+	jGen.writeObjectField("installerId", flowPath.installerId());
+	jGen.writeObjectField("dataPath", flowPath.dataPath());
+	jGen.writeEndObject();
+    }
+}
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/IPv4NetSerializer.java b/src/main/java/net/floodlightcontroller/util/serializers/IPv4NetSerializer.java
new file mode 100644
index 0000000..fc71dd3
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/util/serializers/IPv4NetSerializer.java
@@ -0,0 +1,23 @@
+package net.floodlightcontroller.util.serializers;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.map.JsonSerializer;
+import org.codehaus.jackson.map.SerializerProvider;
+
+import net.floodlightcontroller.util.IPv4Net;
+
+/**
+ * Serialize an IPv4Net address as a string.
+ */
+public class IPv4NetSerializer extends JsonSerializer<IPv4Net> {
+
+    @Override
+    public void serialize(IPv4Net ipv4Net, JsonGenerator jGen,
+			  SerializerProvider serializer)
+	throws IOException, JsonProcessingException {
+	jGen.writeString(ipv4Net.toString());
+    }
+}
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/IPv4Serializer.java b/src/main/java/net/floodlightcontroller/util/serializers/IPv4Serializer.java
new file mode 100644
index 0000000..68e952c
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/util/serializers/IPv4Serializer.java
@@ -0,0 +1,23 @@
+package net.floodlightcontroller.util.serializers;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.map.JsonSerializer;
+import org.codehaus.jackson.map.SerializerProvider;
+
+import net.floodlightcontroller.util.IPv4;
+
+/**
+ * Serialize an IPv4 address as a string.
+ */
+public class IPv4Serializer extends JsonSerializer<IPv4> {
+
+    @Override
+    public void serialize(IPv4 ipv4, JsonGenerator jGen,
+			  SerializerProvider serializer)
+	throws IOException, JsonProcessingException {
+	jGen.writeString(ipv4.toString());
+    }
+}
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/IPv6NetSerializer.java b/src/main/java/net/floodlightcontroller/util/serializers/IPv6NetSerializer.java
new file mode 100644
index 0000000..0f59dc2
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/util/serializers/IPv6NetSerializer.java
@@ -0,0 +1,23 @@
+package net.floodlightcontroller.util.serializers;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.map.JsonSerializer;
+import org.codehaus.jackson.map.SerializerProvider;
+
+import net.floodlightcontroller.util.IPv6Net;
+
+/**
+ * Serialize an IPv6Net address as a string.
+ */
+public class IPv6NetSerializer extends JsonSerializer<IPv6Net> {
+
+    @Override
+    public void serialize(IPv6Net ipv6Net, JsonGenerator jGen,
+			  SerializerProvider serializer)
+	throws IOException, JsonProcessingException {
+	jGen.writeString(ipv6Net.toString());
+    }
+}
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/IPv6Serializer.java b/src/main/java/net/floodlightcontroller/util/serializers/IPv6Serializer.java
new file mode 100644
index 0000000..dabbfa4
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/util/serializers/IPv6Serializer.java
@@ -0,0 +1,23 @@
+package net.floodlightcontroller.util.serializers;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.map.JsonSerializer;
+import org.codehaus.jackson.map.SerializerProvider;
+
+import net.floodlightcontroller.util.IPv6;
+
+/**
+ * Serialize an IPv6 address as a string.
+ */
+public class IPv6Serializer extends JsonSerializer<IPv6> {
+
+    @Override
+    public void serialize(IPv6 ipv6, JsonGenerator jGen,
+			  SerializerProvider serializer)
+	throws IOException, JsonProcessingException {
+	jGen.writeString(ipv6.toString());
+    }
+}
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/PortSerializer.java b/src/main/java/net/floodlightcontroller/util/serializers/PortSerializer.java
new file mode 100644
index 0000000..e79c600
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/util/serializers/PortSerializer.java
@@ -0,0 +1,23 @@
+package net.floodlightcontroller.util.serializers;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.map.JsonSerializer;
+import org.codehaus.jackson.map.SerializerProvider;
+
+import net.floodlightcontroller.util.Port;
+
+/**
+ * Serialize a Port as a string.
+ */
+public class PortSerializer extends JsonSerializer<Port> {
+
+    @Override
+    public void serialize(Port port, JsonGenerator jGen,
+			  SerializerProvider serializer)
+	throws IOException, JsonProcessingException {
+	jGen.writeNumber(port.value());
+    }
+}
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/SwitchPortSerializer.java b/src/main/java/net/floodlightcontroller/util/serializers/SwitchPortSerializer.java
new file mode 100644
index 0000000..8abbb52
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/util/serializers/SwitchPortSerializer.java
@@ -0,0 +1,26 @@
+package net.floodlightcontroller.util.serializers;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.map.JsonSerializer;
+import org.codehaus.jackson.map.SerializerProvider;
+
+import net.floodlightcontroller.util.SwitchPort;
+
+/**
+ * Serialize a SwitchPort as a string.
+ */
+public class SwitchPortSerializer extends JsonSerializer<SwitchPort> {
+
+    @Override
+    public void serialize(SwitchPort switchPort,
+			  JsonGenerator jGen, SerializerProvider serializer)
+	throws IOException, JsonProcessingException {
+	jGen.writeStartObject();
+	jGen.writeObjectField("dpid", switchPort.dpid());
+	jGen.writeObjectField("port", switchPort.port());
+	jGen.writeEndObject();
+    }
+}
diff --git a/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule b/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
index 02edc8e..e683c79 100644
--- a/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
+++ b/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
@@ -25,3 +25,5 @@
 net.floodlightcontroller.firewall.Firewall
 net.floodlightcontroller.mastership.MastershipManager
 net.floodlightcontroller.onoslistener.OnosPublisher
+net.floodlightcontroller.flowcache.FlowManager
+net.floodlightcontroller.routing.TopoRouteService