Merge branch 'master' of https://github.com/OPENNETWORKINGLAB/ONOS
diff --git a/mastership-test.sh b/mastership-test.sh
index 10474cf..209ffb7 100755
--- a/mastership-test.sh
+++ b/mastership-test.sh
@@ -1,2 +1,2 @@
 #java -Dlogback.configurationFile=logback.xml -cp target/floodlight-only.jar:lib/*:lib/titan/* net.onrc.onos.registry.controller.RegistryRunner $1
-java -cp target/floodlight-only.jar:lib/*:lib/titan/* net.floodlightcontroller.core.Main -cf onos.properties
+java -Dlogback.configurationFile=logback.xml -cp target/floodlight-only.jar:lib/*:lib/titan/* net.floodlightcontroller.core.Main -cf onos.properties
diff --git a/onos.properties b/onos.properties
new file mode 100644
index 0000000..498fce5
--- /dev/null
+++ b/onos.properties
@@ -0,0 +1,19 @@
+floodlight.modules = net.floodlightcontroller.storage.memory.MemoryStorageSource,\
+net.floodlightcontroller.core.FloodlightProvider,\
+net.floodlightcontroller.threadpool.ThreadPool,\
+net.floodlightcontroller.devicemanager.internal.DeviceManagerImpl,\
+net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher,\
+net.floodlightcontroller.firewall.Firewall,\
+net.floodlightcontroller.forwarding.Forwarding,\
+net.floodlightcontroller.jython.JythonDebugInterface,\
+net.floodlightcontroller.counter.CounterStore,\
+net.floodlightcontroller.perfmon.PktInProcessingTime,\
+net.floodlightcontroller.ui.web.StaticWebRoutable,\
+net.floodlightcontroller.onoslistener.OnosPublisher, \
+net.onrc.onos.registry.controller.ZookeeperRegistry
+net.floodlightcontroller.restserver.RestApiServer.port = 8080
+net.floodlightcontroller.core.FloodlightProvider.openflowport = 6633
+net.floodlightcontroller.jython.JythonDebugInterface.port = 6655
+net.floodlightcontroller.forwarding.Forwarding.idletimeout = 5
+net.floodlightcontroller.forwarding.Forwarding.hardtimeout = 0
+net.floodlightcontroller.onoslistener.OnosPublisher.dbconf = /tmp/cassandra.titan
diff --git a/src/main/java/net/floodlightcontroller/core/INetMapTopologyObjects.java b/src/main/java/net/floodlightcontroller/core/INetMapTopologyObjects.java
index 1cf6f7b..4af1deb 100644
--- a/src/main/java/net/floodlightcontroller/core/INetMapTopologyObjects.java
+++ b/src/main/java/net/floodlightcontroller/core/INetMapTopologyObjects.java
@@ -74,7 +74,8 @@
 		@Incidence(label="on",direction = Direction.IN)
 		public ISwitchObject getSwitch();
 		
-		@JsonIgnore
+		
+		@JsonProperty("devices")
 		@Adjacency(label="host")
 		public Iterable<IDeviceObject> getDevices();
 		
@@ -119,8 +120,16 @@
 		@GremlinGroovy("_().in('host').in('on')")
 		public Iterable<ISwitchObject> getSwitch();
 		
+/*		@JsonProperty("dpid")
+		@GremlinGroovy("_().in('host').in('on').next().getProperty('dpid')")
+		public Iterable<String> getSwitchDPID();
+		
+		@JsonProperty("number")
+		@GremlinGroovy("_().in('host').transform{it.number}")
+		public Iterable<Short> getPortNumber();
+		
 		@JsonProperty("AttachmentPoint")
 		@GremlinGroovy("_().in('host').in('on').path(){it.number}{it.dpid}")
-		public List<SwitchPort> getAttachmentPoints();
+		public Iterable<SwitchPort> getAttachmentPoints();*/
 	}
 }
diff --git a/src/main/java/net/floodlightcontroller/core/INetMapTopologyService.java b/src/main/java/net/floodlightcontroller/core/INetMapTopologyService.java
index a3eb830..b16e4a9 100644
--- a/src/main/java/net/floodlightcontroller/core/INetMapTopologyService.java
+++ b/src/main/java/net/floodlightcontroller/core/INetMapTopologyService.java
@@ -8,6 +8,8 @@
 import net.floodlightcontroller.core.INetMapTopologyObjects.ISwitchObject;
 import net.floodlightcontroller.routing.Link;
 import net.floodlightcontroller.topology.NodePortTuple;
+import net.floodlightcontroller.util.DataPath;
+import net.floodlightcontroller.util.SwitchPort;
 
 public interface INetMapTopologyService extends INetMapService {
 
@@ -31,8 +33,8 @@
 	}
 	
 	public interface ITopoRouteService extends IFloodlightService {
-		List<NodePortTuple> getShortestPath(NodePortTuple src, NodePortTuple dest);
-		Boolean routeExists(NodePortTuple src, NodePortTuple dest);
+	    DataPath getShortestPath(SwitchPort src, SwitchPort dest);
+	    Boolean routeExists(SwitchPort src, SwitchPort dest);
 	}
 	
 	public interface ITopoFlowService {
diff --git a/src/main/java/net/floodlightcontroller/core/internal/Controller.java b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
index 78b93ed..20ad566 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/Controller.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
@@ -22,8 +22,9 @@
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.SocketAddress;
-import java.util.ArrayList;
+import java.net.UnknownHostException;
 import java.nio.channels.ClosedChannelException;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
@@ -52,13 +53,13 @@
 import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IHAListener;
 import net.floodlightcontroller.core.IInfoProvider;
-import net.floodlightcontroller.core.INetMapStorage.DM_OPERATION;
-import net.floodlightcontroller.core.IOFMessageListener;
 import net.floodlightcontroller.core.IListener.Command;
+import net.floodlightcontroller.core.INetMapStorage.DM_OPERATION;
+import net.floodlightcontroller.core.INetMapTopologyService.ITopoRouteService;
+import net.floodlightcontroller.core.IOFMessageListener;
 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;
@@ -77,6 +78,8 @@
 import net.floodlightcontroller.storage.StorageException;
 import net.floodlightcontroller.threadpool.IThreadPoolService;
 import net.onrc.onos.registry.controller.IControllerRegistryService;
+import net.onrc.onos.registry.controller.IControllerRegistryService.ControlChangeCallback;
+import net.onrc.onos.registry.controller.RegistryException;
 
 import org.jboss.netty.bootstrap.ServerBootstrap;
 import org.jboss.netty.buffer.ChannelBuffer;
@@ -109,9 +112,9 @@
 import org.openflow.protocol.OFMessage;
 import org.openflow.protocol.OFPacketIn;
 import org.openflow.protocol.OFPhysicalPort;
-import org.openflow.protocol.OFPortStatus;
 import org.openflow.protocol.OFPhysicalPort.OFPortConfig;
 import org.openflow.protocol.OFPhysicalPort.OFPortState;
+import org.openflow.protocol.OFPortStatus;
 import org.openflow.protocol.OFPortStatus.OFPortReason;
 import org.openflow.protocol.OFSetConfig;
 import org.openflow.protocol.OFStatisticsRequest;
@@ -193,7 +196,7 @@
     protected IThreadPoolService threadPool;
     protected IFlowService flowService;
     protected ITopoRouteService topoRouteService;
-    protected IControllerRegistryService masterHelper;
+    protected IControllerRegistryService registryService;
     
     // Configuration options
     protected int openFlowPort = 6633;
@@ -405,7 +408,7 @@
     }
 
 	public void setMastershipService(IControllerRegistryService serviceImpl) {
-		this.masterHelper = serviceImpl;		
+		this.registryService = serviceImpl;		
 	}
 	
     @Override
@@ -464,6 +467,63 @@
         return new OFChannelHandler(state);
     }
     
+    protected class RoleChangeCallback implements ControlChangeCallback {
+		@Override
+		public void controlChanged(long dpid, boolean hasControl) {
+			log.info("Role change callback for switch {}, hasControl {}", 
+					HexString.toHexString(dpid), hasControl);
+			
+			synchronized(roleChanger){
+				OFSwitchImpl sw = null;
+				for (OFSwitchImpl connectedSw : connectedSwitches){
+					if (connectedSw.getId() == dpid){
+						sw = connectedSw;
+						break;
+					}
+				}
+				if (sw == null){
+					log.warn("Switch {} not found in connected switches",
+							HexString.toHexString(dpid));
+					return;
+				}
+				
+				Role role = null;
+				
+				if (sw.getRole() == null){
+					if (hasControl){
+						role = Role.MASTER;
+					}
+					else {
+						role = Role.SLAVE;
+					}
+				}
+				else if (hasControl && sw.getRole() == Role.SLAVE) {
+					// Send a MASTER role request to the switch.
+					// If this is the first role request, 
+                    // this is a probe that we'll use to determine if the switch
+                    // actually supports the role request message. If it does we'll
+                    // get back a role reply message. If it doesn't we'll get back an
+                    // OFError message. 
+                    // If role is MASTER we will promote switch to active
+                    // list when we receive the switch's role reply messages
+					role = Role.MASTER;
+				}
+				else if (!hasControl && sw.getRole() == Role.MASTER) {
+					//Send a SLAVE role request to the switch
+					role = Role.SLAVE;
+				}
+				
+				if (role != null) {
+					log.debug("Sending role request {} msg to {}", role, sw);
+	                Collection<OFSwitchImpl> swList = new ArrayList<OFSwitchImpl>(1);
+	                swList.add(sw);
+	                roleChanger.submitRequest(swList, role);
+				}
+			}
+			
+		}
+    }
+    
     /**
      * Channel handler deals with the switch connection and dispatches
      * switch messages to the appropriate locations.
@@ -511,6 +571,7 @@
                     removeSwitch(sw);
                 }
                 synchronized(roleChanger) {
+                	registryService.releaseControl(sw.getId());
                     connectedSwitches.remove(sw);
                 }
                 sw.setConnected(false);
@@ -763,6 +824,22 @@
                     connectedSwitches.add(sw);
                     
                     if (role != null) {
+                    	//Put the switch in SLAVE mode until we know we have control
+                    	log.debug("Setting new switch {} to SLAVE", sw.getStringId());
+                    	Collection<OFSwitchImpl> swList = new ArrayList<OFSwitchImpl>(1);
+                    	swList.add(sw);
+                    	roleChanger.submitRequest(swList, Role.SLAVE);
+                    	
+                    	//Request control of the switch from the global registry
+                    	try {
+							registryService.requestControl(sw.getId(), 
+									new RoleChangeCallback());
+						} catch (RegistryException e) {
+							log.debug("Registry error: {}", e.getMessage());
+						}
+                    	
+                    	
+                    	
                         // Send a role request if role support is enabled for the controller
                         // This is a probe that we'll use to determine if the switch
                         // actually supports the role request message. If it does we'll
@@ -770,12 +847,14 @@
                         // OFError message. 
                         // If role is MASTER we will promote switch to active
                         // list when we receive the switch's role reply messages
+                        /*
                         log.debug("This controller's role is {}, " + 
                                 "sending initial role request msg to {}",
                                 role, sw);
                         Collection<OFSwitchImpl> swList = new ArrayList<OFSwitchImpl>(1);
                         swList.add(sw);
                         roleChanger.submitRequest(swList, role);
+                        */
                     } 
                     else {
                         // Role supported not enabled on controller (for now)
@@ -2057,6 +2136,16 @@
         if (controllerId != null) {
             this.controllerId = controllerId;
         }
+        else {
+        	//Try to get the hostname of the machine and use that for controller ID
+        	try {
+    			String hostname = java.net.InetAddress.getLocalHost().getHostName();
+    			this.controllerId = hostname;
+    		} catch (UnknownHostException e) {
+    			// Can't get hostname, we'll just use the default
+    		}
+        }
+        
         log.debug("ControllerId set to {}", this.controllerId);
     }
 
@@ -2097,7 +2186,9 @@
         this.factory = new BasicFactory();
         this.providerMap = new HashMap<String, List<IInfoProvider>>();
         setConfigParams(configParams);
-        this.role = getInitialRole(configParams);
+        //this.role = getInitialRole(configParams);
+        //Set the controller's role to MASTER so it always tries to do role requests.
+        this.role = Role.MASTER;
         this.roleChanger = new RoleChanger();
         initVendorMessages();
         this.systemStartTime = System.currentTimeMillis();
@@ -2112,6 +2203,12 @@
                         "that the system database has failed to start. " +
                         LogMessageDoc.CHECK_CONTROLLER)
     public void startupComponents() {
+    	try {
+			registryService.registerController(controllerId);
+		} catch (RegistryException e2) {
+			log.warn("Registry service error: {}", e2.getMessage());
+		}
+    	
         // Create the table names we use
         storageSource.createTable(CONTROLLER_TABLE_NAME, null);
         storageSource.createTable(SWITCH_TABLE_NAME, null);
diff --git a/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleLoader.java b/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleLoader.java
index 45fe997..5561327 100644
--- a/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleLoader.java
+++ b/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleLoader.java
@@ -85,7 +85,7 @@
 	        	try {
 	        		m = moduleIter.next();
 	        	} catch (ServiceConfigurationError sce) {
-	        		logger.debug("Could not find module");
+	        		logger.debug("Could not find module: {}", sce.getMessage());
 	        		//moduleIter.remove();
 	        		continue;
 	        	}
diff --git a/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java b/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java
index a3c5c01..c110651 100644
--- a/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java
+++ b/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java
@@ -19,6 +19,7 @@
 
 import net.floodlightcontroller.core.module.ModuleLoaderResource;
 import net.floodlightcontroller.linkdiscovery.web.TopoLinksResource;
+import net.floodlightcontroller.devicemanager.web.TopoDevicesResource;
 import net.floodlightcontroller.restserver.RestletRoutable;
 
 import org.restlet.Context;
@@ -63,6 +64,7 @@
         router.attach("/system/uptime/json", SystemUptimeResource.class);
         router.attach("/topology/switches/{filter}/json", TopoSwitchesResource.class);
         router.attach("/topology/links/json", TopoLinksResource.class);
+        router.attach("/topology/devices/json", TopoDevicesResource.class);
         return router;
     }
 }
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceStorageImpl.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceStorageImpl.java
index cfbbb41..64c12dc 100644
--- a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceStorageImpl.java
+++ b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceStorageImpl.java
@@ -9,7 +9,6 @@
 import com.thinkaurelius.titan.core.TitanException;
 import net.floodlightcontroller.core.INetMapTopologyObjects.IDeviceObject;
 import net.floodlightcontroller.core.INetMapTopologyObjects.IPortObject;
-import net.floodlightcontroller.core.INetMapTopologyService.ITopoSwitchService;
 import net.floodlightcontroller.core.internal.SwitchStorageImpl;
 import net.floodlightcontroller.devicemanager.IDevice;
 import net.floodlightcontroller.devicemanager.IDeviceStorage;
@@ -19,10 +18,8 @@
 
 public class DeviceStorageImpl implements IDeviceStorage {
 	
-//	public TitanGraph graph;
 	public GraphDBConnection conn;
 	protected static Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
-	public ITopoSwitchService svc;
 
 	@Override
 	public void init(String conf) {
@@ -91,8 +88,7 @@
 
 	@Override
 	public IDeviceObject getDeviceByMac(String mac) {
-		
-		return null;
+		return conn.utils().searchDevice(conn, mac);
 	}
 
 	@Override
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/web/TopoDevicesResource.java b/src/main/java/net/floodlightcontroller/devicemanager/web/TopoDevicesResource.java
new file mode 100644
index 0000000..db7059f
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/devicemanager/web/TopoDevicesResource.java
@@ -0,0 +1,22 @@
+package net.floodlightcontroller.devicemanager.web;
+
+import java.util.Iterator;
+
+import net.floodlightcontroller.core.INetMapTopologyObjects.IDeviceObject;
+import net.onrc.onos.util.GraphDBConnection;
+
+import org.restlet.resource.Get;
+import org.restlet.resource.ServerResource;
+
+public class TopoDevicesResource extends ServerResource {
+	
+	@Get("json")
+	public Iterator<IDeviceObject> retrieve() {
+		
+		GraphDBConnection conn = GraphDBConnection.getInstance("");
+		
+		return conn.utils().getDevices(conn).iterator();
+		
+	}
+	
+}
diff --git a/src/main/java/net/floodlightcontroller/flowcache/web/AddFlowResource.java b/src/main/java/net/floodlightcontroller/flowcache/web/AddFlowResource.java
index f32d124..feb43d3 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/web/AddFlowResource.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/web/AddFlowResource.java
@@ -1,9 +1,15 @@
 package net.floodlightcontroller.flowcache.web;
 
+import java.io.IOException;
+
 import net.floodlightcontroller.flowcache.IFlowService;
 import net.floodlightcontroller.util.FlowId;
 import net.floodlightcontroller.util.FlowPath;
 
+import org.codehaus.jackson.JsonGenerationException;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.map.JsonMappingException;
+import org.codehaus.jackson.map.ObjectMapper;
 import org.restlet.resource.Get;
 import org.restlet.resource.ServerResource;
 import org.slf4j.Logger;
@@ -26,14 +32,29 @@
             return result;
 	}
 
+	//
 	// Extract the arguments
+	// NOTE: The "flow" is specified in JSON format.
+	//
+	ObjectMapper mapper = new ObjectMapper();
 	String flowPathStr = (String) getRequestAttributes().get("flow");
-	FlowPath flowPath = new FlowPath(flowPathStr);
-
+	FlowPath flowPath = null;
 	log.debug("Add Flow Path: " + flowPathStr);
+	try {
+	    flowPath = mapper.readValue(flowPathStr, FlowPath.class);
+	} catch (JsonGenerationException e) {
+	    e.printStackTrace();
+	} catch (JsonMappingException e) {
+	    e.printStackTrace();
+	} catch (IOException e) {
+	    e.printStackTrace();
+	}
 
-	if (flowService.addFlow(flowPath, result) != true) {
-	    result = new FlowId();	// Error: Empty Flow Id
+	// Process the request
+	if (flowPath != null) {
+	    if (flowService.addFlow(flowPath, result) != true) {
+		result = new FlowId();		// Error: Return 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 cefad18..f418c1e 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/web/DeleteFlowResource.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/web/DeleteFlowResource.java
@@ -27,12 +27,11 @@
 
 	// Extract the arguments
 	String flowIdStr = (String) getRequestAttributes().get("flow-id");
-	FlowId flowId = new FlowId(HexString.toLong(flowIdStr));
-
+	FlowId flowId = new FlowId(flowIdStr);
 	log.debug("Delete Flow Id: " + flowIdStr);
 
+	// Process the request
 	result = flowService.deleteFlow(flowId);
-
-        return result;
+	return result;
     }
 }
diff --git a/src/main/java/net/floodlightcontroller/flowcache/web/GetAllFlowsByEndpointsResource.java b/src/main/java/net/floodlightcontroller/flowcache/web/GetAllFlowsByEndpointsResource.java
index 4e96c0c..c485d91 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/web/GetAllFlowsByEndpointsResource.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/web/GetAllFlowsByEndpointsResource.java
@@ -9,7 +9,6 @@
 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;
@@ -40,9 +39,9 @@
 	log.debug("Get All Flows Endpoints: " + srcDpidStr + "--" +
 		  srcPortStr + "--" + dstDpidStr + "--" + dstPortStr);
 
-	Dpid srcDpid = new Dpid(HexString.toLong(srcDpidStr));
+	Dpid srcDpid = new Dpid(srcDpidStr);
 	Port srcPort = new Port(Short.parseShort(srcPortStr));
-	Dpid dstDpid = new Dpid(HexString.toLong(dstDpidStr));
+	Dpid dstDpid = new Dpid(dstDpidStr);
 	Port dstPort = new Port(Short.parseShort(dstPortStr));
 	SwitchPort srcSwitchPort = new SwitchPort(srcDpid, srcPort);
 	SwitchPort dstSwitchPort = new SwitchPort(dstDpid, dstPort);
diff --git a/src/main/java/net/floodlightcontroller/flowcache/web/GetAllFlowsResource.java b/src/main/java/net/floodlightcontroller/flowcache/web/GetAllFlowsResource.java
index 5bf3a50..deb4d04 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/web/GetAllFlowsResource.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/web/GetAllFlowsResource.java
@@ -30,6 +30,8 @@
 	log.debug("Get All Flows Endpoints");
 
 	flowService.getAllFlows(result);
+	FlowPath flowPath = new FlowPath();
+	result.add(flowPath);
 
         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 2863c79..d5b2730 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/web/GetFlowByIdResource.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/web/GetFlowByIdResource.java
@@ -4,7 +4,6 @@
 import net.floodlightcontroller.util.FlowId;
 import net.floodlightcontroller.util.FlowPath;
 
-import org.openflow.util.HexString;
 import org.restlet.resource.Get;
 import org.restlet.resource.ServerResource;
 import org.slf4j.Logger;
@@ -28,7 +27,7 @@
 
 	// Extract the arguments
 	String flowIdStr = (String) getRequestAttributes().get("flow-id");
-	FlowId flowId = new FlowId(HexString.toLong(flowIdStr));
+	FlowId flowId = new FlowId(flowIdStr);
 
 	log.debug("Get Flow Id: " + flowIdStr);
 
diff --git a/src/main/java/net/floodlightcontroller/flowcache/web/GetFlowByInstallerIdResource.java b/src/main/java/net/floodlightcontroller/flowcache/web/GetFlowByInstallerIdResource.java
index 6b5f7f4..cb4e6ef 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/web/GetFlowByInstallerIdResource.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/web/GetFlowByInstallerIdResource.java
@@ -8,7 +8,6 @@
 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;
@@ -42,9 +41,9 @@
 		  dstDpidStr + "--" + dstPortStr);
 
 	CallerId installerId = new CallerId(installerIdStr);
-	Dpid srcDpid = new Dpid(HexString.toLong(srcDpidStr));
+	Dpid srcDpid = new Dpid(srcDpidStr);
 	Port srcPort = new Port(Short.parseShort(srcPortStr));
-	Dpid dstDpid = new Dpid(HexString.toLong(dstDpidStr));
+	Dpid dstDpid = new Dpid(dstDpidStr);
 	Port dstPort = new Port(Short.parseShort(dstPortStr));
 	SwitchPort srcSwitchPort = new SwitchPort(srcDpid, srcPort);
 	SwitchPort dstSwitchPort = new SwitchPort(dstDpid, dstPort);
diff --git a/src/main/java/net/floodlightcontroller/routing/TopoRouteService.java b/src/main/java/net/floodlightcontroller/routing/TopoRouteService.java
index 6d50602..f979cc7 100644
--- a/src/main/java/net/floodlightcontroller/routing/TopoRouteService.java
+++ b/src/main/java/net/floodlightcontroller/routing/TopoRouteService.java
@@ -13,7 +13,11 @@
 import net.floodlightcontroller.core.module.IFloodlightModule;
 import net.floodlightcontroller.core.module.IFloodlightService;
 import net.floodlightcontroller.core.INetMapTopologyService.ITopoRouteService;
-import net.floodlightcontroller.topology.NodePortTuple;
+import net.floodlightcontroller.util.DataPath;
+import net.floodlightcontroller.util.Dpid;
+import net.floodlightcontroller.util.FlowEntry;
+import net.floodlightcontroller.util.Port;
+import net.floodlightcontroller.util.SwitchPort;
 
 import org.openflow.util.HexString;
 
@@ -87,14 +91,17 @@
     SwitchStorageImpl swStore = store.get();
 
     @Override
-    public List<NodePortTuple> getShortestPath(NodePortTuple src,
-					       NodePortTuple dest) {
-	List<NodePortTuple> result_list = new ArrayList<NodePortTuple>();
+    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);
 
 	TitanGraph titanGraph = swStore.graph;
 
-	String dpid_src = HexString.toHexString(src.getNodeId());
-	String dpid_dest = HexString.toHexString(dest.getNodeId());
+	String dpid_src = src.dpid().toString();
+	String dpid_dest = dest.dpid().toString();
 
 	//
 	// Implement the Shortest Path between two vertices by using
@@ -120,16 +127,18 @@
 
 	//
 	// 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.
+	// If "yes", then just add a single flow entry 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;
+	    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;
 	}
 
 	//
@@ -151,11 +160,13 @@
 	}
 
 	//
-	// Loop through the result and return the list
+	// Loop through the result and collect the list
 	// of <dpid, port> tuples.
 	//
 	long nodeId = 0;
 	short portId = 0;
+	Port inPort = new Port(src.port().value());
+	Port outPort = new Port();
 	for (ArrayList<Vertex> lv : results) {
 	    int idx = 0;
 	    for (Vertex v: lv) {
@@ -181,27 +192,48 @@
 
 		    System.out.println("dpid: " + dpid);
 		}
-		if (idx == 0) {
-		    idx++;
+		idx++;
+		if (idx == 1) {
 		    continue;
 		}
-		int mod = (idx - 1) % 3;
-		if ((mod == 0) || (mod == 2))  {
-		    result_list.add(new NodePortTuple(nodeId, portId));
+		int mod = idx % 3;
+		if (mod == 0) {
+		    // Setup the incoming port
+		    inPort = new Port(portId);
+		    continue;
 		}
-		idx++;
+		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);
 	    }
 	}
-	if (result_list.size() > 0)
-	    return result_list;
+	if (result_data_path.flowEntries().size() > 0)
+	    return result_data_path;
 
 	return null;
     }
 
     @Override
-    public Boolean routeExists(NodePortTuple src, NodePortTuple dest) {
-	List<NodePortTuple> route = getShortestPath(src, dest);
-	if (route != null)
+    public Boolean routeExists(SwitchPort src, SwitchPort dest) {
+	DataPath dataPath = getShortestPath(src, dest);
+	if (dataPath != null)
 	    return true;
 	return false;
     }
diff --git a/src/main/java/net/floodlightcontroller/topology/web/RouteResource.java b/src/main/java/net/floodlightcontroller/topology/web/RouteResource.java
index 3fa7510..20f39d4 100644
--- a/src/main/java/net/floodlightcontroller/topology/web/RouteResource.java
+++ b/src/main/java/net/floodlightcontroller/topology/web/RouteResource.java
@@ -6,6 +6,10 @@
 import net.floodlightcontroller.routing.IRoutingService;
 import net.floodlightcontroller.routing.Route;
 import net.floodlightcontroller.topology.NodePortTuple;
+import net.floodlightcontroller.util.DataPath;
+import net.floodlightcontroller.util.Dpid;
+import net.floodlightcontroller.util.Port;
+import net.floodlightcontroller.util.SwitchPort;
 
 import org.openflow.util.HexString;
 import org.restlet.resource.Get;
@@ -18,7 +22,7 @@
     protected static Logger log = LoggerFactory.getLogger(RouteResource.class);
 
     @Get("json")
-    public List<NodePortTuple> retrieve() {
+    public DataPath retrieve() {
         ITopoRouteService topoRouteService = 
                 (ITopoRouteService)getContext().getAttributes().
                     get(ITopoRouteService.class.getCanonicalName());
@@ -27,22 +31,22 @@
 	    return null;
 	}
         
-        String srcDpid = (String) getRequestAttributes().get("src-dpid");
-        String srcPort = (String) getRequestAttributes().get("src-port");
-        String dstDpid = (String) getRequestAttributes().get("dst-dpid");
-        String dstPort = (String) getRequestAttributes().get("dst-port");
+        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");
 
-        log.debug( srcDpid + "--" + srcPort + "--" + dstDpid + "--" + dstPort);
+        log.debug( srcDpidStr + "--" + srcPortStr + "--" + dstDpidStr + "--" + dstPortStr);
 
-        long longSrcDpid = HexString.toLong(srcDpid);
-        short shortSrcPort = Short.parseShort(srcPort);
-        long longDstDpid = HexString.toLong(dstDpid);
-        short shortDstPort = Short.parseShort(dstPort);
+	Dpid srcDpid = new Dpid(srcDpidStr);
+	Port srcPort = new Port(Short.parseShort(srcPortStr));
+	Dpid dstDpid = new Dpid(dstDpidStr);
+	Port dstPort = new Port(Short.parseShort(dstPortStr));
         
-	List<NodePortTuple> result =
-	    topoRouteService.getShortestPath(new NodePortTuple(longSrcDpid, shortSrcPort),
-					     new NodePortTuple(longDstDpid, shortDstPort));
-	if ((result != null) && (result.size() > 0)) {
+	DataPath result =
+	    topoRouteService.getShortestPath(new SwitchPort(srcDpid, srcPort),
+					     new SwitchPort(dstDpid, dstPort));
+	if (result != null) {
 	    return result;
 	} else {
             log.debug("ERROR! no route found");
diff --git a/src/main/java/net/floodlightcontroller/util/CallerId.java b/src/main/java/net/floodlightcontroller/util/CallerId.java
index 200b9e0..ade0f0d 100644
--- a/src/main/java/net/floodlightcontroller/util/CallerId.java
+++ b/src/main/java/net/floodlightcontroller/util/CallerId.java
@@ -1,14 +1,10 @@
 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;
 
@@ -31,6 +27,7 @@
      *
      * @return the value of the Caller ID.
      */
+    @JsonProperty("value")
     public String value() { return value; }
 
     /**
@@ -38,6 +35,7 @@
      *
      * @param value the value to set.
      */
+    @JsonProperty("value")
     public void setValue(String value) {
 	this.value = value;
     }
diff --git a/src/main/java/net/floodlightcontroller/util/DataPath.java b/src/main/java/net/floodlightcontroller/util/DataPath.java
index ad6cdb8..71e0a2f 100644
--- a/src/main/java/net/floodlightcontroller/util/DataPath.java
+++ b/src/main/java/net/floodlightcontroller/util/DataPath.java
@@ -4,15 +4,12 @@
 
 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
@@ -22,6 +19,7 @@
      * Default constructor.
      */
     public DataPath() {
+	flowEntries = new ArrayList<FlowEntry>();
     }
 
     /**
@@ -29,6 +27,7 @@
      *
      * @return the data path source port.
      */
+    @JsonProperty("srcPort")
     public SwitchPort srcPort() { return srcPort; }
 
     /**
@@ -36,6 +35,7 @@
      *
      * @param srcPort the data path source port to set.
      */
+    @JsonProperty("srcPort")
     public void setSrcPort(SwitchPort srcPort) {
 	this.srcPort = srcPort;
     }
@@ -45,6 +45,7 @@
      *
      * @return the data path destination port.
      */
+    @JsonProperty("dstPort")
     public SwitchPort dstPort() { return dstPort; }
 
     /**
@@ -52,6 +53,7 @@
      *
      * @param dstPort the data path destination port to set.
      */
+    @JsonProperty("dstPort")
     public void setDstPort(SwitchPort dstPort) {
 	this.dstPort = dstPort;
     }
@@ -61,6 +63,7 @@
      *
      * @return the data path flow entries.
      */
+    @JsonProperty("flowEntries")
     public ArrayList<FlowEntry> flowEntries() { return flowEntries; }
 
     /**
@@ -68,6 +71,7 @@
      *
      * @param flowEntries the data path flow entries to set.
      */
+    @JsonProperty("flowEntries")
     public void setFlowEntries(ArrayList<FlowEntry> flowEntries) {
 	this.flowEntries = flowEntries;
     }
diff --git a/src/main/java/net/floodlightcontroller/util/DataPathEndpoints.java b/src/main/java/net/floodlightcontroller/util/DataPathEndpoints.java
index 92cf2dd..3ee88d1 100644
--- a/src/main/java/net/floodlightcontroller/util/DataPathEndpoints.java
+++ b/src/main/java/net/floodlightcontroller/util/DataPathEndpoints.java
@@ -1,15 +1,12 @@
 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
@@ -36,6 +33,7 @@
      *
      * @return the data path source port.
      */
+    @JsonProperty("srcPort")
     public SwitchPort srcPort() { return srcPort; }
 
     /**
@@ -43,6 +41,7 @@
      *
      * @param srcPort the data path source port to set.
      */
+    @JsonProperty("srcPort")
     public void setSrcPort(SwitchPort srcPort) {
 	this.srcPort = srcPort;
     }
@@ -52,6 +51,7 @@
      *
      * @return the data path destination port.
      */
+    @JsonProperty("dstPort")
     public SwitchPort dstPort() { return dstPort; }
 
     /**
@@ -59,6 +59,7 @@
      *
      * @param dstPort the data path destination port to set.
      */
+    @JsonProperty("dstPort")
     public void setDstPort(SwitchPort dstPort) {
 	this.dstPort = dstPort;
     }
diff --git a/src/main/java/net/floodlightcontroller/util/Dpid.java b/src/main/java/net/floodlightcontroller/util/Dpid.java
index 7787953..5af6bea 100644
--- a/src/main/java/net/floodlightcontroller/util/Dpid.java
+++ b/src/main/java/net/floodlightcontroller/util/Dpid.java
@@ -1,14 +1,17 @@
 package net.floodlightcontroller.util;
 
 import org.openflow.util.HexString;
+import net.floodlightcontroller.util.serializers.DpidDeserializer;
 import net.floodlightcontroller.util.serializers.DpidSerializer;
 
 import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonDeserialize;
 import org.codehaus.jackson.map.annotate.JsonSerialize;
 
 /**
  * The class representing a network switch DPID.
  */
+@JsonDeserialize(using=DpidDeserializer.class)
 @JsonSerialize(using=DpidSerializer.class)
 public class Dpid {
     static public long UNKNOWN = 0;
@@ -32,6 +35,15 @@
     }
 
     /**
+     * Constructor from a string.
+     *
+     * @param value the value to use.
+     */
+    public Dpid(String value) {
+	this.value = HexString.toLong(value);
+    }
+
+    /**
      * Get the value of the DPID.
      *
      * @return the value of the DPID.
diff --git a/src/main/java/net/floodlightcontroller/util/FlowEntry.java b/src/main/java/net/floodlightcontroller/util/FlowEntry.java
index 42ec935..dfb8f82 100644
--- a/src/main/java/net/floodlightcontroller/util/FlowEntry.java
+++ b/src/main/java/net/floodlightcontroller/util/FlowEntry.java
@@ -5,10 +5,8 @@
 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).
@@ -38,7 +36,6 @@
  * 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
@@ -64,6 +61,7 @@
      *
      * @return the Flow Entry ID.
      */
+    @JsonProperty("flowEntryId")
     public FlowEntryId flowEntryId() { return flowEntryId; }
 
     /**
@@ -71,6 +69,7 @@
      *
      * @param flowEntryId the Flow Entry ID to set.
      */
+    @JsonProperty("flowEntryId")
     public void setFlowEntryId(FlowEntryId flowEntryId) {
 	this.flowEntryId = flowEntryId;
     }
@@ -80,6 +79,7 @@
      *
      * @return the Flow Entry Match.
      */
+    @JsonProperty("flowEntryMatch")
     public FlowEntryMatch flowEntryMatch() { return flowEntryMatch; }
 
     /**
@@ -87,6 +87,7 @@
      *
      * @param flowEntryMatch the Flow Entry Match to set.
      */
+    @JsonProperty("flowEntryMatch")
     public void setFlowEntryMatch(FlowEntryMatch flowEntryMatch) {
 	this.flowEntryMatch = flowEntryMatch;
     }
@@ -96,6 +97,7 @@
      *
      * @return the Flow Entry Actions.
      */
+    @JsonProperty("flowEntryActions")
     public FlowEntryActions flowEntryActions() { return flowEntryActions; }
 
     /**
@@ -103,6 +105,7 @@
      *
      * @param flowEntryActions the Flow Entry Actions to set.
      */
+    @JsonProperty("flowEntryActions")
     public void setFlowEntryActions(FlowEntryActions flowEntryActions) {
 	this.flowEntryActions = flowEntryActions;
     }
@@ -112,6 +115,7 @@
      *
      * @return the Switch DPID.
      */
+    @JsonProperty("dpid")
     public Dpid dpid() { return dpid; }
 
     /**
@@ -119,6 +123,7 @@
      *
      * @param dpid the Switch DPID to set.
      */
+    @JsonProperty("dpid")
     public void setDpid(Dpid dpid) {
 	this.dpid = dpid;
     }
@@ -128,6 +133,7 @@
      *
      * @return the Switch incoming port.
      */
+    @JsonProperty("inPort")
     public Port inPort() { return inPort; }
 
     /**
@@ -135,6 +141,7 @@
      *
      * @param inPort the Switch incoming port to set.
      */
+    @JsonProperty("inPort")
     public void setInPort(Port inPort) {
 	this.inPort = inPort;
     }
@@ -144,6 +151,7 @@
      *
      * @return the Switch outgoing port.
      */
+    @JsonProperty("outPort")
     public Port outPort() { return outPort; }
 
     /**
@@ -151,6 +159,7 @@
      *
      * @param outPort the Switch outgoing port to set.
      */
+    @JsonProperty("outPort")
     public void setOutPort(Port outPort) {
 	this.outPort = outPort;
     }
@@ -160,6 +169,7 @@
      *
      * @return the Flow Entry User state.
      */
+    @JsonProperty("flowEntryUserState")
     public FlowEntryUserState flowEntryUserState() {
 	return flowEntryUserState;
     }
@@ -169,6 +179,7 @@
      *
      * @param flowEntryUserState the Flow Entry User state to set.
      */
+    @JsonProperty("flowEntryUserState")
     public void setFlowEntryUserState(FlowEntryUserState flowEntryUserState) {
 	this.flowEntryUserState = flowEntryUserState;
     }
@@ -181,6 +192,7 @@
      *
      * @return the Flow Entry Switch state.
      */
+    @JsonProperty("flowEntrySwitchState")
     public FlowEntrySwitchState flowEntrySwitchState() {
 	return flowEntrySwitchState;
     }
@@ -193,6 +205,7 @@
      *
      * @param flowEntrySwitchState the Flow Entry Switch state to set.
      */
+    @JsonProperty("flowEntrySwitchState")
     public void setFlowEntrySwitchState(FlowEntrySwitchState flowEntrySwitchState) {
 	this.flowEntrySwitchState = flowEntrySwitchState;
     }
@@ -202,6 +215,7 @@
      *
      * @return the Flow Entry Error state.
      */
+    @JsonProperty("flowEntryErrorState")
     public FlowEntryErrorState flowEntryErrorState() {
 	return flowEntryErrorState;
     }
@@ -211,6 +225,7 @@
      *
      * @param flowEntryErrorState the Flow Entry Error state to set.
      */
+    @JsonProperty("flowEntryErrorState")
     public void setFlowEntryErrorState(FlowEntryErrorState flowEntryErrorState) {
 	this.flowEntryErrorState = flowEntryErrorState;
     }
diff --git a/src/main/java/net/floodlightcontroller/util/FlowEntryActions.java b/src/main/java/net/floodlightcontroller/util/FlowEntryActions.java
index b683d2c..4d17de8 100644
--- a/src/main/java/net/floodlightcontroller/util/FlowEntryActions.java
+++ b/src/main/java/net/floodlightcontroller/util/FlowEntryActions.java
@@ -1,9 +1,6 @@
 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.
@@ -13,7 +10,6 @@
  * 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 f9ca8ba..bf1708d 100644
--- a/src/main/java/net/floodlightcontroller/util/FlowEntryErrorState.java
+++ b/src/main/java/net/floodlightcontroller/util/FlowEntryErrorState.java
@@ -1,14 +1,10 @@
 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)
@@ -37,16 +33,38 @@
      *
      * @return the error type.
      */
+    @JsonProperty("type")
     public short type() { return type; }
 
     /**
+     * Set the error type.
+     *
+     * @param type the error type to use.
+     */
+    @JsonProperty("type")
+    public void setType(short type) {
+	this.type = type;
+    }
+
+    /**
      * Get the error code.
      *
      * @return the error code.
      */
+    @JsonProperty("code")
     public short code() { return code; }
 
     /**
+     * Set the error code.
+     *
+     * @param code the error code to use.
+     */
+    @JsonProperty("code")
+    public void setCode(short code) {
+	this.code = code;
+    }
+
+    /**
      * Set the values of the error type and code.
      *
      * @param type the error type to use.
diff --git a/src/main/java/net/floodlightcontroller/util/FlowEntryId.java b/src/main/java/net/floodlightcontroller/util/FlowEntryId.java
index bf1fc7d..0874bdb 100644
--- a/src/main/java/net/floodlightcontroller/util/FlowEntryId.java
+++ b/src/main/java/net/floodlightcontroller/util/FlowEntryId.java
@@ -1,13 +1,16 @@
 package net.floodlightcontroller.util;
 
+import net.floodlightcontroller.util.serializers.FlowEntryIdDeserializer;
 import net.floodlightcontroller.util.serializers.FlowEntryIdSerializer;
 
 import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonDeserialize;
 import org.codehaus.jackson.map.annotate.JsonSerialize;
 
 /**
  * The class representing a Flow Entry ID.
  */
+@JsonDeserialize(using=FlowEntryIdDeserializer.class)
 @JsonSerialize(using=FlowEntryIdSerializer.class)
 public class FlowEntryId {
     private long value;
@@ -29,6 +32,15 @@
     }
 
     /**
+     * Constructor from a string.
+     *
+     * @param value the value to use.
+     */
+    public FlowEntryId(String value) {
+	this.value = Long.decode(value);
+    }
+
+    /**
      * Get the value of the Flow Entry ID.
      *
      * @return the value of the Flow Entry ID.
diff --git a/src/main/java/net/floodlightcontroller/util/FlowEntryMatch.java b/src/main/java/net/floodlightcontroller/util/FlowEntryMatch.java
index 0e3775e..9bd3bea 100644
--- a/src/main/java/net/floodlightcontroller/util/FlowEntryMatch.java
+++ b/src/main/java/net/floodlightcontroller/util/FlowEntryMatch.java
@@ -2,10 +2,8 @@
 
 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.
@@ -19,7 +17,6 @@
  * 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
@@ -37,6 +34,7 @@
      *
      * @return the matching source MAC address.
      */
+    @JsonProperty("srcMac")
     public MACAddress srcMac() { return srcMac; }
 
     /**
@@ -44,6 +42,7 @@
      *
      * @param srcMac the matching source MAC address to set.
      */
+    @JsonProperty("srcMac")
     public void setSrcMac(MACAddress srcMac) {
 	this.srcMac = srcMac;
     }
@@ -53,6 +52,7 @@
      *
      * @return the matching destination MAC address.
      */
+    @JsonProperty("dstMac")
     public MACAddress dstMac() { return dstMac; }
 
     /**
@@ -60,6 +60,7 @@
      *
      * @param dstMac the matching destination MAC address to set.
      */
+    @JsonProperty("dstMac")
     public void setDstMac(MACAddress dstMac) {
 	this.dstMac = dstMac;
     }
@@ -69,6 +70,7 @@
      *
      * @return the matching source IPv4 prefix.
      */
+    @JsonProperty("srcIPv4Net")
     public IPv4Net srcIPv4Net() { return srcIPv4Net; }
 
     /**
@@ -76,6 +78,7 @@
      *
      * @param srcIPv4Net the matching source IPv4 prefix to set.
      */
+    @JsonProperty("srcIPv4Net")
     public void setSrcIPv4Net(IPv4Net srcIPv4Net) {
 	this.srcIPv4Net = srcIPv4Net;
     }
@@ -85,6 +88,7 @@
      *
      * @return the matching destination IPv4 prefix.
      */
+    @JsonProperty("dstIPv4Net")
     public IPv4Net dstIPv4Net() { return dstIPv4Net; }
 
     /**
@@ -92,6 +96,7 @@
      *
      * @param srcIPv4Net the matching destination IPv4 prefix to set.
      */
+    @JsonProperty("dstIPv4Net")
     public void setDstIPv4Net(IPv4Net dstIPv4Net) {
 	this.dstIPv4Net = dstIPv4Net;
     }
diff --git a/src/main/java/net/floodlightcontroller/util/FlowId.java b/src/main/java/net/floodlightcontroller/util/FlowId.java
index a8beaa0..297c0c4 100644
--- a/src/main/java/net/floodlightcontroller/util/FlowId.java
+++ b/src/main/java/net/floodlightcontroller/util/FlowId.java
@@ -1,13 +1,16 @@
 package net.floodlightcontroller.util;
 
+import net.floodlightcontroller.util.serializers.FlowIdDeserializer;
 import net.floodlightcontroller.util.serializers.FlowIdSerializer;
 
 import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonDeserialize;
 import org.codehaus.jackson.map.annotate.JsonSerialize;
 
 /**
  * The class representing a Flow ID.
  */
+@JsonDeserialize(using=FlowIdDeserializer.class)
 @JsonSerialize(using=FlowIdSerializer.class)
 public class FlowId {
     private long value;
@@ -29,6 +32,15 @@
     }
 
     /**
+     * Constructor from a string.
+     *
+     * @param value the value to use.
+     */
+    public FlowId(String value) {
+	this.value = Long.decode(value);
+    }
+
+    /**
      * Get the value of the Flow ID.
      *
      * @return the value of the Flow ID.
diff --git a/src/main/java/net/floodlightcontroller/util/FlowPath.java b/src/main/java/net/floodlightcontroller/util/FlowPath.java
index f91bb4a..5b3bbd1 100644
--- a/src/main/java/net/floodlightcontroller/util/FlowPath.java
+++ b/src/main/java/net/floodlightcontroller/util/FlowPath.java
@@ -3,15 +3,12 @@
 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
@@ -24,17 +21,11 @@
     }
 
     /**
-     * Constructor from a string.
-     */
-    public FlowPath(String str) {
-	// TODO: Implement it.
-    }
-
-    /**
      * Get the flow path Flow ID.
      *
      * @return the flow path Flow ID.
      */
+    @JsonProperty("flowId")
     public FlowId flowId() { return flowId; }
 
     /**
@@ -42,6 +33,7 @@
      *
      * @param flowId the flow path Flow ID to set.
      */
+    @JsonProperty("flowId")
     public void setFlowId(FlowId flowId) {
 	this.flowId = flowId;
     }
@@ -51,6 +43,7 @@
      *
      * @return the Caller ID of the flow path installer.
      */
+    @JsonProperty("installerId")
     public CallerId installerId() { return installerId; }
 
     /**
@@ -58,6 +51,7 @@
      *
      * @param installerId the Caller ID of the flow path installer.
      */
+    @JsonProperty("installerId")
     public void setInstallerId(CallerId installerId) {
 	this.installerId = installerId;
     }
@@ -67,6 +61,7 @@
      *
      * @return the flow path's data path.
      */
+    @JsonProperty("dataPath")
     public DataPath dataPath() { return dataPath; }
 
     /**
@@ -74,6 +69,7 @@
      *
      * @param dataPath the flow path's data path to set.
      */
+    @JsonProperty("dataPath")
     public void setDataPath(DataPath dataPath) {
 	this.dataPath = dataPath;
     }
diff --git a/src/main/java/net/floodlightcontroller/util/IPv4.java b/src/main/java/net/floodlightcontroller/util/IPv4.java
index 3f4f350..ef3a1e5 100644
--- a/src/main/java/net/floodlightcontroller/util/IPv4.java
+++ b/src/main/java/net/floodlightcontroller/util/IPv4.java
@@ -1,13 +1,16 @@
 package net.floodlightcontroller.util;
 
+import net.floodlightcontroller.util.serializers.IPv4Deserializer;
 import net.floodlightcontroller.util.serializers.IPv4Serializer;
 
 import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonDeserialize;
 import org.codehaus.jackson.map.annotate.JsonSerialize;
 
 /**
  * The class representing an IPv4 address.
  */
+@JsonDeserialize(using=IPv4Deserializer.class)
 @JsonSerialize(using=IPv4Serializer.class)
 public class IPv4 {
     private int value;
@@ -29,6 +32,24 @@
     }
 
     /**
+     * Constructor from a string.
+     *
+     * @param value the value to use.
+     */
+    public IPv4(String value) {
+        String[] splits = value.split("\\.");
+        if (splits.length != 4)
+            throw new IllegalArgumentException("Specified IPv4 address must contain four " +
+					       "numerical digits separated by '.'");
+
+        int result = 0;
+        for (int i = 0; i < 4; ++i) {
+            result |= Integer.valueOf(splits[i]) << ((3-i)*8);
+        }
+	this.value = result;
+    }
+
+    /**
      * Get the value of the IPv4 address.
      *
      * @return the value of the IPv4 address.
diff --git a/src/main/java/net/floodlightcontroller/util/IPv4Net.java b/src/main/java/net/floodlightcontroller/util/IPv4Net.java
index f64ccb8..824e3e2 100644
--- a/src/main/java/net/floodlightcontroller/util/IPv4Net.java
+++ b/src/main/java/net/floodlightcontroller/util/IPv4Net.java
@@ -1,14 +1,17 @@
 package net.floodlightcontroller.util;
 
 import net.floodlightcontroller.util.IPv4;
+import net.floodlightcontroller.util.serializers.IPv4NetDeserializer;
 import net.floodlightcontroller.util.serializers.IPv4NetSerializer;
 
 import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonDeserialize;
 import org.codehaus.jackson.map.annotate.JsonSerialize;
 
 /**
  * The class representing an IPv4 network address.
  */
+@JsonDeserialize(using=IPv4NetDeserializer.class)
 @JsonSerialize(using=IPv4NetSerializer.class)
 public class IPv4Net {
     private IPv4 address;		// The IPv4 address
@@ -33,6 +36,21 @@
     }
 
     /**
+     * Constructor from a string.
+     *
+     * @param value the value to use.
+     */
+    public IPv4Net(String value) {
+	String[] splits = value.split("/");
+	if (splits.length != 2) {
+	    throw new IllegalArgumentException("Specified IPv4Net address must contain an IPv4 " +
+					       "address and a prefix length separated by '/'");
+	}
+	this.address = new IPv4(splits[0]);
+	this.prefixLen = Short.decode(splits[1]);
+    }
+
+    /**
      * Get the address value of the IPv4Net address.
      *
      * @return the address value of the IPv4Net address.
@@ -40,6 +58,15 @@
     public IPv4 address() { return address; }
 
     /**
+     * Set the address value of the IPv4Net address.
+     *
+     * @param address the address to use.
+     */
+    public void setAddress(IPv4 address) {
+	this.address = address;
+    }
+
+    /**
      * Get the prefix length value of the IPv4Net address.
      *
      * @return the prefix length value of the IPv4Net address.
@@ -47,6 +74,15 @@
     public short prefixLen() { return prefixLen; }
 
     /**
+     * Set the prefix length value of the IPv4Net address.
+     *
+     * @param prefixLen the prefix length to use.
+     */
+    public void setPrefixLen(short prefixLen) {
+	this.prefixLen = prefixLen;
+    }
+
+    /**
      * Set the value of the IPv4Net address.
      *
      * @param address the address to use.
diff --git a/src/main/java/net/floodlightcontroller/util/IPv6.java b/src/main/java/net/floodlightcontroller/util/IPv6.java
index d4461c0..eda4502 100644
--- a/src/main/java/net/floodlightcontroller/util/IPv6.java
+++ b/src/main/java/net/floodlightcontroller/util/IPv6.java
@@ -1,14 +1,17 @@
 package net.floodlightcontroller.util;
 
 import org.openflow.util.HexString;
+import net.floodlightcontroller.util.serializers.IPv6Deserializer;
 import net.floodlightcontroller.util.serializers.IPv6Serializer;
 
 import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonDeserialize;
 import org.codehaus.jackson.map.annotate.JsonSerialize;
 
 /**
  * The class representing an IPv6 address.
  */
+@JsonDeserialize(using=IPv6Deserializer.class)
 @JsonSerialize(using=IPv6Serializer.class)
 public class IPv6 {
     private long valueHigh;	// The higher (more significant) 64 bits
@@ -34,6 +37,17 @@
     }
 
     /**
+     * Constructor from a string.
+     *
+     * @param value the value to use.
+     */
+    public IPv6(String value) {
+	// TODO: Implement it!
+	this.valueHigh = 0;
+	this.valueLow = 0;
+    }
+
+    /**
      * Get the value of the higher (more significant) 64 bits of the address.
      *
      * @return the value of the higher (more significant) 64 bits of the
@@ -42,6 +56,15 @@
     public long valueHigh() { return valueHigh; }
 
     /**
+     * Set the value of the higher (more significant) 64 bits of the address.
+     *
+     * @param valueHigh the higher (more significant) 64 bits of the address.
+     */
+    public void setValueHigh(long valueHigh) {
+	this.valueHigh = valueHigh;
+    }
+
+    /**
      * Get the value of the lower (less significant) 64 bits of the address.
      *
      * @return the value of the lower (less significant) 64 bits of the
@@ -50,6 +73,15 @@
     public long valueLow() { return valueLow; }
 
     /**
+     * Get the value of the lower (less significant) 64 bits of the address.
+     *
+     * @param valueLow the lower (less significant) 64 bits of the address.
+     */
+    public void setValueLow(long valueLow) {
+	this.valueLow = valueLow;
+    }
+
+    /**
      * Set the value of the IPv6 address.
      *
      * @param valueHigh the higher (more significant) 64 bits of the address.
diff --git a/src/main/java/net/floodlightcontroller/util/IPv6Net.java b/src/main/java/net/floodlightcontroller/util/IPv6Net.java
index 1942293..b6f7d67 100644
--- a/src/main/java/net/floodlightcontroller/util/IPv6Net.java
+++ b/src/main/java/net/floodlightcontroller/util/IPv6Net.java
@@ -1,14 +1,17 @@
 package net.floodlightcontroller.util;
 
 import net.floodlightcontroller.util.IPv6;
+import net.floodlightcontroller.util.serializers.IPv6NetDeserializer;
 import net.floodlightcontroller.util.serializers.IPv6NetSerializer;
 
 import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonDeserialize;
 import org.codehaus.jackson.map.annotate.JsonSerialize;
 
 /**
  * The class representing an IPv6 network address.
  */
+@JsonDeserialize(using=IPv6NetDeserializer.class)
 @JsonSerialize(using=IPv6NetSerializer.class)
 public class IPv6Net {
     private IPv6 address;		// The IPv6 address
@@ -33,6 +36,21 @@
     }
 
     /**
+     * Constructor from a string.
+     *
+     * @param value the value to use.
+     */
+    public IPv6Net(String value) {
+	String[] splits = value.split("/");
+	if (splits.length != 2) {
+	    throw new IllegalArgumentException("Specified IPv6Net address must contain an IPv6 " +
+					       "address and a prefix length separated by '/'");
+	}
+	this.address = new IPv6(splits[0]);
+	this.prefixLen = Short.decode(splits[1]);
+    }
+
+    /**
      * Get the address value of the IPv6Net address.
      *
      * @return the address value of the IPv6Net address.
@@ -40,6 +58,15 @@
     public IPv6 address() { return address; }
 
     /**
+     * Set the address value of the IPv6Net address.
+     *
+     * @param address the address to use.
+     */
+    public void setAddress(IPv6 address) {
+	this.address = address;
+    }
+
+    /**
      * Get the prefix length value of the IPv6Net address.
      *
      * @return the prefix length value of the IPv6Net address.
@@ -47,6 +74,15 @@
     public short prefixLen() { return prefixLen; }
 
     /**
+     * Set the prefix length value of the IPv6Net address.
+     *
+     * @param prefixLen the prefix length to use.
+     */
+    public void setPrefixLen(short prefixLen) {
+	this.prefixLen = prefixLen;
+    }
+
+    /**
      * Set the value of the IPv6Net address.
      *
      * @param address the address to use.
diff --git a/src/main/java/net/floodlightcontroller/util/Port.java b/src/main/java/net/floodlightcontroller/util/Port.java
index 0bfb07a..19bbf8f 100644
--- a/src/main/java/net/floodlightcontroller/util/Port.java
+++ b/src/main/java/net/floodlightcontroller/util/Port.java
@@ -1,14 +1,10 @@
 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;
 
@@ -20,6 +16,15 @@
     }
 
     /**
+     * Constructor from another entry.
+     *
+     * @param other the other entry to use.
+     */
+    public Port(Port other) {
+	this.value = other.value();
+    }
+
+    /**
      * Constructor from a long value.
      *
      * @param value the value to use.
@@ -33,6 +38,7 @@
      *
      * @return the value of the port.
      */
+    @JsonProperty("value")
     public short value() { return value; }
 
     /**
@@ -40,6 +46,7 @@
      *
      * @param value the value to set.
      */
+    @JsonProperty("value")
     public void setValue(short value) {
 	this.value = value;
     }
diff --git a/src/main/java/net/floodlightcontroller/util/SwitchPort.java b/src/main/java/net/floodlightcontroller/util/SwitchPort.java
index 462cdfb..027b681 100644
--- a/src/main/java/net/floodlightcontroller/util/SwitchPort.java
+++ b/src/main/java/net/floodlightcontroller/util/SwitchPort.java
@@ -2,15 +2,12 @@
 
 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
@@ -37,16 +34,38 @@
      *
      * @return the DPID value of the Switch-Port.
      */
+    @JsonProperty("dpid")
     public Dpid dpid() { return dpid; }
 
     /**
+     * Set the DPID value of the Switch-Port.
+     *
+     * @param dpid the DPID to use.
+     */
+    @JsonProperty("dpid")
+    public void setDpid(Dpid dpid) {
+	this.dpid = dpid;
+    }
+
+    /**
      * Get the port value of the Switch-Port.
      *
      * @return the port value of the Switch-Port.
      */
+    @JsonProperty("port")
     public Port port() { return port; }
 
     /**
+     * Set the port value of the Switch-Port.
+     *
+     * @param port the port to use.
+     */
+    @JsonProperty("port")
+    public void setPort(Port port) {
+	this.port = port;
+    }
+
+    /**
      * Set the DPID and port values of the Switch-Port.
      *
      * @param dpid the DPID to use.
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/CallerIdSerializer.java b/src/main/java/net/floodlightcontroller/util/serializers/CallerIdSerializer.java
deleted file mode 100644
index 9935324..0000000
--- a/src/main/java/net/floodlightcontroller/util/serializers/CallerIdSerializer.java
+++ /dev/null
@@ -1,23 +0,0 @@
-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
deleted file mode 100644
index e05c21d..0000000
--- a/src/main/java/net/floodlightcontroller/util/serializers/DataPathEndpointsSerializer.java
+++ /dev/null
@@ -1,26 +0,0 @@
-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
deleted file mode 100644
index d150c37..0000000
--- a/src/main/java/net/floodlightcontroller/util/serializers/DataPathSerializer.java
+++ /dev/null
@@ -1,32 +0,0 @@
-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/DpidDeserializer.java b/src/main/java/net/floodlightcontroller/util/serializers/DpidDeserializer.java
new file mode 100644
index 0000000..9297f56
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/util/serializers/DpidDeserializer.java
@@ -0,0 +1,43 @@
+package net.floodlightcontroller.util.serializers;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.JsonParser;
+import org.codehaus.jackson.JsonToken;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.ObjectCodec;
+import org.codehaus.jackson.map.JsonDeserializer;
+import org.codehaus.jackson.map.DeserializationContext;
+
+import net.floodlightcontroller.util.Dpid;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Deserialize a DPID from a string.
+ */
+public class DpidDeserializer extends JsonDeserializer<Dpid> {
+
+    protected static Logger log = LoggerFactory.getLogger(DpidDeserializer.class);
+
+    @Override
+    public Dpid deserialize(JsonParser jp,
+			    DeserializationContext ctxt)
+	throws IOException, JsonProcessingException {
+
+	Dpid dpid = null;
+
+	jp.nextToken();		// Move to JsonToken.START_OBJECT
+	while (jp.nextToken() != JsonToken.END_OBJECT) {
+	    String fieldname = jp.getCurrentName();
+	    if ("value".equals(fieldname)) {
+		String value = jp.getText();
+		log.debug("Fieldname: " + fieldname + " Value: " + value);
+		dpid = new Dpid(value);
+	    }
+	}
+	return dpid;
+    }
+}
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/DpidSerializer.java b/src/main/java/net/floodlightcontroller/util/serializers/DpidSerializer.java
index 2b71690..06fab62 100644
--- a/src/main/java/net/floodlightcontroller/util/serializers/DpidSerializer.java
+++ b/src/main/java/net/floodlightcontroller/util/serializers/DpidSerializer.java
@@ -18,6 +18,8 @@
     public void serialize(Dpid dpid, JsonGenerator jGen,
 			  SerializerProvider serializer)
 	throws IOException, JsonProcessingException {
-	jGen.writeString(dpid.toString());
+	jGen.writeStartObject();
+	jGen.writeStringField("value", dpid.toString());
+	jGen.writeEndObject();
     }
 }
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/FlowEntryActionsSerializer.java b/src/main/java/net/floodlightcontroller/util/serializers/FlowEntryActionsSerializer.java
deleted file mode 100644
index bd5970d..0000000
--- a/src/main/java/net/floodlightcontroller/util/serializers/FlowEntryActionsSerializer.java
+++ /dev/null
@@ -1,24 +0,0 @@
-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
deleted file mode 100644
index 2518e86..0000000
--- a/src/main/java/net/floodlightcontroller/util/serializers/FlowEntryErrorStateSerializer.java
+++ /dev/null
@@ -1,26 +0,0 @@
-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/FlowEntryIdDeserializer.java b/src/main/java/net/floodlightcontroller/util/serializers/FlowEntryIdDeserializer.java
new file mode 100644
index 0000000..e6481d5
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/util/serializers/FlowEntryIdDeserializer.java
@@ -0,0 +1,43 @@
+package net.floodlightcontroller.util.serializers;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.JsonParser;
+import org.codehaus.jackson.JsonToken;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.ObjectCodec;
+import org.codehaus.jackson.map.JsonDeserializer;
+import org.codehaus.jackson.map.DeserializationContext;
+
+import net.floodlightcontroller.util.FlowEntryId;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Deserialize a Flow Entry ID from a string.
+ */
+public class FlowEntryIdDeserializer extends JsonDeserializer<FlowEntryId> {
+
+    protected static Logger log = LoggerFactory.getLogger(FlowEntryIdDeserializer.class);
+
+    @Override
+    public FlowEntryId deserialize(JsonParser jp,
+				   DeserializationContext ctxt)
+	throws IOException, JsonProcessingException {
+
+	FlowEntryId flowEntryId = null;
+
+	jp.nextToken();		// Move to JsonToken.START_OBJECT
+	while (jp.nextToken() != JsonToken.END_OBJECT) {
+	    String fieldname = jp.getCurrentName();
+	    if ("value".equals(fieldname)) {
+		String value = jp.getText();
+		log.debug("Fieldname: " + fieldname + " Value: " + value);
+		flowEntryId = new FlowEntryId(value);
+	    }
+	}
+	return flowEntryId;
+    }
+}
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/FlowEntryMatchSerializer.java b/src/main/java/net/floodlightcontroller/util/serializers/FlowEntryMatchSerializer.java
deleted file mode 100644
index 0de3b08..0000000
--- a/src/main/java/net/floodlightcontroller/util/serializers/FlowEntryMatchSerializer.java
+++ /dev/null
@@ -1,28 +0,0 @@
-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
deleted file mode 100644
index 9912d55..0000000
--- a/src/main/java/net/floodlightcontroller/util/serializers/FlowEntrySerializer.java
+++ /dev/null
@@ -1,37 +0,0 @@
-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/FlowIdDeserializer.java b/src/main/java/net/floodlightcontroller/util/serializers/FlowIdDeserializer.java
new file mode 100644
index 0000000..a7f53d4
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/util/serializers/FlowIdDeserializer.java
@@ -0,0 +1,43 @@
+package net.floodlightcontroller.util.serializers;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.JsonParser;
+import org.codehaus.jackson.JsonToken;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.ObjectCodec;
+import org.codehaus.jackson.map.JsonDeserializer;
+import org.codehaus.jackson.map.DeserializationContext;
+
+import net.floodlightcontroller.util.FlowId;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Deserialize a Flow ID from a string.
+ */
+public class FlowIdDeserializer extends JsonDeserializer<FlowId> {
+
+    protected static Logger log = LoggerFactory.getLogger(FlowIdDeserializer.class);
+
+    @Override
+    public FlowId deserialize(JsonParser jp,
+			      DeserializationContext ctxt)
+	throws IOException, JsonProcessingException {
+
+	FlowId flowId = null;
+
+	jp.nextToken();		// Move to JsonToken.START_OBJECT
+	while (jp.nextToken() != JsonToken.END_OBJECT) {
+	    String fieldname = jp.getCurrentName();
+	    if ("value".equals(fieldname)) {
+		String value = jp.getText();
+		log.debug("Fieldname: " + fieldname + " Value: " + value);
+		flowId = new FlowId(value);
+	    }
+	}
+	return flowId;
+    }
+}
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/FlowIdSerializer.java b/src/main/java/net/floodlightcontroller/util/serializers/FlowIdSerializer.java
index 0e69273..6f1a6f6 100644
--- a/src/main/java/net/floodlightcontroller/util/serializers/FlowIdSerializer.java
+++ b/src/main/java/net/floodlightcontroller/util/serializers/FlowIdSerializer.java
@@ -18,6 +18,8 @@
     public void serialize(FlowId flowId, JsonGenerator jGen,
 			  SerializerProvider serializer)
 	throws IOException, JsonProcessingException {
-	jGen.writeString(flowId.toString());
+	jGen.writeStartObject();
+	jGen.writeStringField("value", flowId.toString());
+	jGen.writeEndObject();
     }
 }
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/FlowPathSerializer.java b/src/main/java/net/floodlightcontroller/util/serializers/FlowPathSerializer.java
deleted file mode 100644
index a6a5405..0000000
--- a/src/main/java/net/floodlightcontroller/util/serializers/FlowPathSerializer.java
+++ /dev/null
@@ -1,27 +0,0 @@
-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/IPv4Deserializer.java b/src/main/java/net/floodlightcontroller/util/serializers/IPv4Deserializer.java
new file mode 100644
index 0000000..7ce7d5c
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/util/serializers/IPv4Deserializer.java
@@ -0,0 +1,43 @@
+package net.floodlightcontroller.util.serializers;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.JsonParser;
+import org.codehaus.jackson.JsonToken;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.ObjectCodec;
+import org.codehaus.jackson.map.JsonDeserializer;
+import org.codehaus.jackson.map.DeserializationContext;
+
+import net.floodlightcontroller.util.IPv4;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Deserialize an IPv4 from a string.
+ */
+public class IPv4Deserializer extends JsonDeserializer<IPv4> {
+
+    protected static Logger log = LoggerFactory.getLogger(IPv4Deserializer.class);
+
+    @Override
+    public IPv4 deserialize(JsonParser jp,
+			    DeserializationContext ctxt)
+	throws IOException, JsonProcessingException {
+
+	IPv4 ipv4 = null;
+
+	jp.nextToken();		// Move to JsonToken.START_OBJECT
+	while (jp.nextToken() != JsonToken.END_OBJECT) {
+	    String fieldname = jp.getCurrentName();
+	    if ("value".equals(fieldname)) {
+		String value = jp.getText();
+		log.debug("Fieldname: " + fieldname + " Value: " + value);
+		ipv4 = new IPv4(value);
+	    }
+	}
+	return ipv4;
+    }
+}
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/IPv4NetDeserializer.java b/src/main/java/net/floodlightcontroller/util/serializers/IPv4NetDeserializer.java
new file mode 100644
index 0000000..e35fc80
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/util/serializers/IPv4NetDeserializer.java
@@ -0,0 +1,43 @@
+package net.floodlightcontroller.util.serializers;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.JsonParser;
+import org.codehaus.jackson.JsonToken;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.ObjectCodec;
+import org.codehaus.jackson.map.JsonDeserializer;
+import org.codehaus.jackson.map.DeserializationContext;
+
+import net.floodlightcontroller.util.IPv4Net;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Deserialize an IPv4Net from a string.
+ */
+public class IPv4NetDeserializer extends JsonDeserializer<IPv4Net> {
+
+    protected static Logger log = LoggerFactory.getLogger(IPv4NetDeserializer.class);
+
+    @Override
+    public IPv4Net deserialize(JsonParser jp,
+			       DeserializationContext ctxt)
+	throws IOException, JsonProcessingException {
+
+	IPv4Net ipv4Net = null;
+
+	jp.nextToken();		// Move to JsonToken.START_OBJECT
+	while (jp.nextToken() != JsonToken.END_OBJECT) {
+	    String fieldname = jp.getCurrentName();
+	    if ("value".equals(fieldname)) {
+		String value = jp.getText();
+		log.debug("Fieldname: " + fieldname + " Value: " + value);
+		ipv4Net = new IPv4Net(value);
+	    }
+	}
+	return ipv4Net;
+    }
+}
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/IPv4NetSerializer.java b/src/main/java/net/floodlightcontroller/util/serializers/IPv4NetSerializer.java
index fc71dd3..5c5e1d0 100644
--- a/src/main/java/net/floodlightcontroller/util/serializers/IPv4NetSerializer.java
+++ b/src/main/java/net/floodlightcontroller/util/serializers/IPv4NetSerializer.java
@@ -18,6 +18,8 @@
     public void serialize(IPv4Net ipv4Net, JsonGenerator jGen,
 			  SerializerProvider serializer)
 	throws IOException, JsonProcessingException {
-	jGen.writeString(ipv4Net.toString());
+	jGen.writeStartObject();
+	jGen.writeStringField("value", ipv4Net.toString());
+	jGen.writeEndObject();
     }
 }
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/IPv4Serializer.java b/src/main/java/net/floodlightcontroller/util/serializers/IPv4Serializer.java
index 68e952c..ba7d825 100644
--- a/src/main/java/net/floodlightcontroller/util/serializers/IPv4Serializer.java
+++ b/src/main/java/net/floodlightcontroller/util/serializers/IPv4Serializer.java
@@ -18,6 +18,8 @@
     public void serialize(IPv4 ipv4, JsonGenerator jGen,
 			  SerializerProvider serializer)
 	throws IOException, JsonProcessingException {
-	jGen.writeString(ipv4.toString());
+	jGen.writeStartObject();
+	jGen.writeStringField("value", ipv4.toString());
+	jGen.writeEndObject();
     }
 }
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/IPv6Deserializer.java b/src/main/java/net/floodlightcontroller/util/serializers/IPv6Deserializer.java
new file mode 100644
index 0000000..6713f93
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/util/serializers/IPv6Deserializer.java
@@ -0,0 +1,43 @@
+package net.floodlightcontroller.util.serializers;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.JsonParser;
+import org.codehaus.jackson.JsonToken;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.ObjectCodec;
+import org.codehaus.jackson.map.JsonDeserializer;
+import org.codehaus.jackson.map.DeserializationContext;
+
+import net.floodlightcontroller.util.IPv6;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Deserialize an IPv6 from a string.
+ */
+public class IPv6Deserializer extends JsonDeserializer<IPv6> {
+
+    protected static Logger log = LoggerFactory.getLogger(IPv6Deserializer.class);
+
+    @Override
+    public IPv6 deserialize(JsonParser jp,
+			    DeserializationContext ctxt)
+	throws IOException, JsonProcessingException {
+
+	IPv6 ipv6 = null;
+
+	jp.nextToken();		// Move to JsonToken.START_OBJECT
+	while (jp.nextToken() != JsonToken.END_OBJECT) {
+	    String fieldname = jp.getCurrentName();
+	    if ("value".equals(fieldname)) {
+		String value = jp.getText();
+		log.debug("Fieldname: " + fieldname + " Value: " + value);
+		ipv6 = new IPv6(value);
+	    }
+	}
+	return ipv6;
+    }
+}
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/IPv6NetDeserializer.java b/src/main/java/net/floodlightcontroller/util/serializers/IPv6NetDeserializer.java
new file mode 100644
index 0000000..596ee50
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/util/serializers/IPv6NetDeserializer.java
@@ -0,0 +1,43 @@
+package net.floodlightcontroller.util.serializers;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.JsonParser;
+import org.codehaus.jackson.JsonToken;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.ObjectCodec;
+import org.codehaus.jackson.map.JsonDeserializer;
+import org.codehaus.jackson.map.DeserializationContext;
+
+import net.floodlightcontroller.util.IPv6Net;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Deserialize an IPv6Net from a string.
+ */
+public class IPv6NetDeserializer extends JsonDeserializer<IPv6Net> {
+
+    protected static Logger log = LoggerFactory.getLogger(IPv6NetDeserializer.class);
+
+    @Override
+    public IPv6Net deserialize(JsonParser jp,
+			       DeserializationContext ctxt)
+	throws IOException, JsonProcessingException {
+
+	IPv6Net ipv6Net = null;
+
+	jp.nextToken();		// Move to JsonToken.START_OBJECT
+	while (jp.nextToken() != JsonToken.END_OBJECT) {
+	    String fieldname = jp.getCurrentName();
+	    if ("value".equals(fieldname)) {
+		String value = jp.getText();
+		log.debug("Fieldname: " + fieldname + " Value: " + value);
+		ipv6Net = new IPv6Net(value);
+	    }
+	}
+	return ipv6Net;
+    }
+}
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/IPv6NetSerializer.java b/src/main/java/net/floodlightcontroller/util/serializers/IPv6NetSerializer.java
index 0f59dc2..fc5d262 100644
--- a/src/main/java/net/floodlightcontroller/util/serializers/IPv6NetSerializer.java
+++ b/src/main/java/net/floodlightcontroller/util/serializers/IPv6NetSerializer.java
@@ -18,6 +18,8 @@
     public void serialize(IPv6Net ipv6Net, JsonGenerator jGen,
 			  SerializerProvider serializer)
 	throws IOException, JsonProcessingException {
-	jGen.writeString(ipv6Net.toString());
+	jGen.writeStartObject();
+	jGen.writeStringField("value", ipv6Net.toString());
+	jGen.writeEndObject();
     }
 }
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/IPv6Serializer.java b/src/main/java/net/floodlightcontroller/util/serializers/IPv6Serializer.java
index dabbfa4..0b08a63 100644
--- a/src/main/java/net/floodlightcontroller/util/serializers/IPv6Serializer.java
+++ b/src/main/java/net/floodlightcontroller/util/serializers/IPv6Serializer.java
@@ -18,6 +18,8 @@
     public void serialize(IPv6 ipv6, JsonGenerator jGen,
 			  SerializerProvider serializer)
 	throws IOException, JsonProcessingException {
-	jGen.writeString(ipv6.toString());
+	jGen.writeStartObject();
+	jGen.writeStringField("value", ipv6.toString());
+	jGen.writeEndObject();
     }
 }
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/PortSerializer.java b/src/main/java/net/floodlightcontroller/util/serializers/PortSerializer.java
deleted file mode 100644
index e79c600..0000000
--- a/src/main/java/net/floodlightcontroller/util/serializers/PortSerializer.java
+++ /dev/null
@@ -1,23 +0,0 @@
-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
deleted file mode 100644
index 8abbb52..0000000
--- a/src/main/java/net/floodlightcontroller/util/serializers/SwitchPortSerializer.java
+++ /dev/null
@@ -1,26 +0,0 @@
-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/java/net/onrc/onos/registry/controller/IControllerRegistryService.java b/src/main/java/net/onrc/onos/registry/controller/IControllerRegistryService.java
index e924f6a..afd9dc6 100644
--- a/src/main/java/net/onrc/onos/registry/controller/IControllerRegistryService.java
+++ b/src/main/java/net/onrc/onos/registry/controller/IControllerRegistryService.java
@@ -8,42 +8,91 @@
 
 public interface IControllerRegistryService extends IFloodlightService {
 	
-	// Callback for all mastership changes. 
-	// Change callback is called when mastership is acquired or released
+	/**
+	 * Callback interface for control change events
+	 *
+	 */
 	public interface ControlChangeCallback {
+		/**
+		 * Called whenever the control changes from the point of view of the
+		 * registry. The callee can check whether they have control or not 
+		 * using the hasControl parameter.
+		 * @param dpid The switch that control has changed for
+		 * @param hasControl Whether the listener now has control or not
+		 */
 		public void controlChanged(long dpid, boolean hasControl);
 	}
 	
-	// Acquire mastership for a switch. 
-	public void requestControl(long dpid, ControlChangeCallback cb) throws RegistryException;
+	/**
+	 * Request for control of a switch. This method does not block. When 
+	 * control for a switch changes, the controlChanged method on the 
+	 * callback object will be called. This happens any time the control
+	 * changes while the request is still active (until releaseControl is
+	 * called)
+	 * @param dpid Switch to request control for
+	 * @param cb Callback that will be used to notify caller of control
+	 * changes
+	 * @throws RegistryException Errors contacting the registry service
+	 */
+	public void requestControl(long dpid, ControlChangeCallback cb) 
+			throws RegistryException;
 	
-	// Release mastership for a switch
+	/**
+	 * Stop trying to take control of a switch. This removes the entry 
+	 * for this controller requesting this switch in the registry.
+	 * If the controller had control when this is called, another controller
+	 * will now gain control of the switch. This call doesn't block.
+	 * @param dpid Switch to release control of
+	 */
 	public void releaseControl(long dpid);
-	
-	// Check if I am the master of a switch. This is a nonblocking call that checks if the caller is a 
+	 
+	/**
+	 * Check whether the controller has control of the switch
+	 * This call doesn't block.
+	 * @param dpid Switch to check control of
+	 * @return 
+	 */
 	public boolean hasControl(long dpid);
 	
-	// Set/Get mastership identifier.
-	// This is typically a unique identifier of the controller that does not change across restarts
+	
+	/**
+	 * Superseded by registerController
+	 * @param id
+	 */
+	@Deprecated
 	public void setMastershipId (String id);
+	
+	/**
+	 * Get the unique ID used to identify this controller in the cluster
+	 * @return
+	 */
 	public String getMastershipId ();
 	
 	/**
-	 * Register a controller to the ONOS cluster
-	 * @param controller A string identifying the controller
+	 * Register a controller to the ONOS cluster. Must be called before
+	 * the registry can be used to take control of any switches.
+	 * @param controller A unique string ID identifying this controller
+	 * in the cluster
+	 * @throws errors connecting to registry service, 
+	 * controllerId already registered
 	 */
 	public void registerController(String controllerId) throws RegistryException;
 	
 	/**
 	 * Get all controllers in the cluster
-	 * @return
+	 * @return Collection of controller IDs
 	 */
 	public Collection<String> getAllControllers() throws RegistryException;
 	
+	/**
+	 * Get all switches in the cluster, along with which controller is
+	 * in control of them (if any) and any other controllers that have
+	 * requested control.
+	 * @return
+	 */
+	public Map<String, List<ControllerRegistryEntry>> getAllSwitches();
 	
 	public String getControllerForSwitch(long dpid) throws RegistryException;
 	
-	public Map<String, List<ControllerRegistryEntry>> getAllSwitches();
-	
 	public Collection<Long> getSwitchesControlledByController(String controllerId);
 }
diff --git a/src/main/java/net/onrc/onos/registry/controller/IMastershipHelper.java b/src/main/java/net/onrc/onos/registry/controller/IMastershipHelper.java
deleted file mode 100644
index 9e07d46..0000000
--- a/src/main/java/net/onrc/onos/registry/controller/IMastershipHelper.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package net.onrc.onos.registry.controller;
-
-public interface IMastershipHelper {
-	
-	// Callback for all mastership changes. 
-	// Change callback is called when mastership is acquired or released
-	public interface MastershipCallback {
-		public void changeCallback(long dpid);
-	}
-	
-	// Set/get mastership identifier. This is used to set the unique identifier of the controller that is asking for mastership.
-	// It needs to be set first before any mastership call can be made
-	public void setMastershipId (String id);
-	public String getMastershipId ();
-	
-	// Request mastership for a switch. Our request for mastership remains in a queue. If we win mastership, the callback
-	// is called. This call is non-blocking and can be called from the packet processing context as well.
-	public void requestMastership(long dpid, MastershipCallback cb);
-	
-	// Release mastership for a switch. If we are the master, then the mastership will be released and given to the next
-	// controller who had requested mastership. If we are not the master our request for mastership will be 
-	// removed from the queue.
-	public void releaseMastership(long dpid);
-	
-	// Check if I am the master of a switch and return true if I am the master. 
-	public boolean amMaster(long dpid);	
-}
diff --git a/src/main/java/net/onrc/onos/registry/controller/MastershipHelper.java b/src/main/java/net/onrc/onos/registry/controller/MastershipHelper.java
deleted file mode 100644
index 2fcd002..0000000
--- a/src/main/java/net/onrc/onos/registry/controller/MastershipHelper.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package net.onrc.onos.registry.controller;
-
-public class MastershipHelper implements IMastershipHelper {
-
-	@Override
-	public void setMastershipId(String id) {
-		// TODO Auto-generated method stub
-
-	}
-
-	@Override
-	public String getMastershipId() {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	@Override
-	public void requestMastership(long dpid, MastershipCallback cb) {
-		// TODO Auto-generated method stub
-		return;
-	}
-
-	@Override
-	public void releaseMastership(long dpid) {
-		// TODO Auto-generated method stub
-
-	}
-
-	@Override
-	public boolean amMaster(long dpid) {
-		// TODO Auto-generated method stub
-		return false;
-	}
-
-}
diff --git a/src/main/java/net/onrc/onos/registry/controller/RegistryException.java b/src/main/java/net/onrc/onos/registry/controller/RegistryException.java
index 3b237c2..fbc68a44 100644
--- a/src/main/java/net/onrc/onos/registry/controller/RegistryException.java
+++ b/src/main/java/net/onrc/onos/registry/controller/RegistryException.java
@@ -9,18 +9,16 @@
 		// 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) {
+		super(message);
+	}
+	
 	public RegistryException(String message, Throwable cause) {
 		super(message, cause);
 	}
diff --git a/src/main/java/net/onrc/onos/registry/controller/StandaloneRegistry.java b/src/main/java/net/onrc/onos/registry/controller/StandaloneRegistry.java
index e3181fe..8a468bc 100644
--- a/src/main/java/net/onrc/onos/registry/controller/StandaloneRegistry.java
+++ b/src/main/java/net/onrc/onos/registry/controller/StandaloneRegistry.java
@@ -32,7 +32,8 @@
 	public void requestControl(long dpid, ControlChangeCallback cb)
 			throws RegistryException {
 		if (controllerId == null) {
-			throw new RuntimeException("Must register a controller before calling requestControl");
+			throw new RuntimeException(
+					"Must register a controller before calling requestControl");
 		}
 		
 		switchCallbacks.put(HexString.toHexString(dpid), cb);
@@ -75,6 +76,10 @@
 	@Override
 	public void registerController(String controllerId)
 			throws RegistryException {
+		if (this.controllerId != null) {
+			throw new RegistryException(
+					"Controller already registered with id " + this.controllerId);
+		}
 		this.controllerId = controllerId;
 	}
 
diff --git a/src/main/java/net/onrc/onos/registry/controller/ZookeeperRegistry.java b/src/main/java/net/onrc/onos/registry/controller/ZookeeperRegistry.java
index 58b8bc7..468bb07 100644
--- a/src/main/java/net/onrc/onos/registry/controller/ZookeeperRegistry.java
+++ b/src/main/java/net/onrc/onos/registry/controller/ZookeeperRegistry.java
@@ -22,6 +22,7 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Charsets;
 import com.netflix.curator.RetryPolicy;
 import com.netflix.curator.framework.CuratorFramework;
 import com.netflix.curator.framework.CuratorFrameworkFactory;
@@ -59,7 +60,9 @@
 	protected Map<String, ControlChangeCallback> switchCallbacks;
 	protected Map<String, PathChildrenCache> switchPathCaches;
 	
-	//protected boolean zookeeperEnabled = false;
+	//Zookeeper performance-related configuration
+	protected static final int sessionTimeout = 2000;
+	protected static final int connectionTimeout = 4000;
 	
 	protected class ParamaterizedCuratorWatcher implements CuratorWatcher {
 		private String dpid;
@@ -132,7 +135,6 @@
 		@Override
 		public void childEvent(CuratorFramework client,
 				PathChildrenCacheEvent event) throws Exception {
-			// TODO Auto-generated method stub
 			log.debug("Root switch path cache got {} event", event.getType());
 			
 			String strSwitch = null;
@@ -171,14 +173,6 @@
 	
 	@Override
 	public void requestControl(long dpid, ControlChangeCallback cb) throws RegistryException {
-		/*
-		if (!zookeeperEnabled) {
-			//If zookeeper connection is disabled all control requests succeed immediately
-			if (cb != null){
-				cb.controlChanged(dpid, true);
-			}
-			return;
-		}*/
 		
 		if (controllerId == null){
 			throw new RuntimeException("Must register a controller before calling requestControl");
@@ -211,7 +205,6 @@
 
 	@Override
 	public void releaseControl(long dpid) {
-		//if (!zookeeperEnabled) return;
 		
 		String dpidStr = HexString.toHexString(dpid);
 		
@@ -234,7 +227,6 @@
 
 	@Override
 	public boolean hasControl(long dpid) {
-		//if (!zookeeperEnabled) return false;
 		
 		LeaderLatch latch = switchLatches.get(HexString.toHexString(dpid));
 		
@@ -264,8 +256,6 @@
 	
 	@Override
 	public Collection<String> getAllControllers() throws RegistryException {
-		//if (!zookeeperEnabled) return null;
-		
 		log.debug("Getting all controllers");
 		
 		List<String> controllers = new ArrayList<String>();
@@ -285,16 +275,14 @@
 
 	@Override
 	public void registerController(String id) throws RegistryException {
-		//if (!zookeeperEnabled) return;
+		if (controllerId != null) {
+			throw new RegistryException(
+					"Controller already registered with id " + controllerId);
+		}
 		
 		controllerId = id;
 		
-		byte bytes[] = null;
-		try {
-			bytes = id.getBytes("UTF-8");
-		} catch (UnsupportedEncodingException e1) {
-			throw new RegistryException("Error encoding string", e1);
-		}
+		byte bytes[] = id.getBytes(Charsets.UTF_8);
 		
 		String path = controllerPath + "/" + id;
 		
@@ -311,12 +299,10 @@
 	
 	@Override
 	public String getControllerForSwitch(long dpid) throws RegistryException {
-		//if (!zookeeperEnabled) return null;
 		// 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);
 		
@@ -357,19 +343,8 @@
 			}
 			
 			for (ChildData d : entry.getValue().getCurrentData()) {
-				/*
-				if (d.getPath().length() < 1){
-					log.info("Switch entry with no leader elections: {}", d.getPath());
-					continue;
-				}
-				*/
-				
-				String controllerId = null;
-				try {
-					controllerId = new String(d.getData(), "UTF-8");
-				} catch (UnsupportedEncodingException e) {
-					log.warn("Encoding exception: {}", e.getMessage());
-				}
+			
+				String controllerId = new String(d.getData(), Charsets.UTF_8);
 				
 				String[] splitted = d.getPath().split("-");
 				int sequenceNumber = Integer.parseInt(splitted[splitted.length - 1]);
@@ -413,56 +388,30 @@
 	
 	@Override
 	public void init (FloodlightModuleContext context) throws FloodlightModuleException {
-		
 		log.info("Initialising the Zookeeper Registry - Zookeeper connection required");
 		
-		restApi = context.getServiceImpl(IRestApiService.class);
-		
-		//We have a config option that determines whether we try and connect to 
-		//zookeeper or not. By default zookeeper connection is disabled. When we don't
-		//have a zookeeper connection we act as though we are the only server in the 
-		//cluster, i.e. all control requests will succeed.
-		/*Map<String, String> configOptions = context.getConfigParams(this);
-		String enableZookeeper = configOptions.get("enableZookeeper");
-		if (enableZookeeper != null) {
-			log.info("Enabling Zookeeper connection");
-			zookeeperEnabled = true;
+		//Read the Zookeeper connection string from the config
+		Map<String, String> configParams = context.getConfigParams(this);
+		String connectionString = configParams.get("connectionString");
+		if (connectionString != null){
+			this.connectionString = connectionString;
 		}
-		else {
-			log.info("Zookeeper connectivity is disabled - running in standalone mode");
-			return;
-		}*/
+		log.info("Setting Zookeeper connection string to {}", this.connectionString);
 		
-		/*
-		try {
-			String localHostname = java.net.InetAddress.getLocalHost().getHostName();
-			controllerId = localHostname;
-			log.debug("Setting controller id to {}", controllerId);
-		} catch (UnknownHostException e) {
-			// TODO Handle this exception
-			e.printStackTrace();
-		}*/
+		restApi = context.getServiceImpl(IRestApiService.class);
 
 		switchLatches = new HashMap<String, LeaderLatch>();
 		switchCallbacks = new HashMap<String, ControlChangeCallback>();
 		switchPathCaches = new HashMap<String, PathChildrenCache>();
 		
 		RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
-		client = CuratorFrameworkFactory.newClient(connectionString, retryPolicy);
+		client = CuratorFrameworkFactory.newClient(this.connectionString, 
+				sessionTimeout, connectionTimeout, retryPolicy);
 		
 		client.start();
 		
 		client = client.usingNamespace(namespace);
-		
-		//Put some data in for testing
-		/*
-		try {
-			registerController("zookeeperController");
-			requestControl(2L, null);
-		} catch (RegistryException e1) {
-			// TODO Auto-generated catch block
-			e1.printStackTrace();
-		}*/
+
 		
 		controllerCache = new PathChildrenCache(client, controllerPath, true);
 		switchCache = new PathChildrenCache(client, switchLatchesPath, true);
diff --git a/src/main/java/net/onrc/onos/util/GraphDBConnection.java b/src/main/java/net/onrc/onos/util/GraphDBConnection.java
index 7c1ea2a..a2a8689 100644
--- a/src/main/java/net/onrc/onos/util/GraphDBConnection.java
+++ b/src/main/java/net/onrc/onos/util/GraphDBConnection.java
@@ -24,7 +24,7 @@
 	   
 	   /* Static 'instance' method */
 	   public static GraphDBConnection getInstance(String conf) {
-		   if (graph == null||graph.isOpen()) {
+		   if (graph == null||graph.isOpen() == Boolean.FALSE) {
 		        graph = TitanFactory.open(conf);		        
 		        // FIXME: Creation on Indexes should be done only once
 		        Set<String> s = graph.getIndexedKeys(Vertex.class);
diff --git a/src/main/java/net/onrc/onos/util/GraphDBUtils.java b/src/main/java/net/onrc/onos/util/GraphDBUtils.java
index 8bb83ea..d01de21 100644
--- a/src/main/java/net/onrc/onos/util/GraphDBUtils.java
+++ b/src/main/java/net/onrc/onos/util/GraphDBUtils.java
@@ -1,7 +1,6 @@
 package net.onrc.onos.util;
 
 import com.thinkaurelius.titan.core.TitanGraph;
-import com.thinkaurelius.titan.graphdb.transaction.VertexIterable;
 import com.tinkerpop.blueprints.Vertex;
 import com.tinkerpop.frames.FramedGraph;
 import com.tinkerpop.frames.FramedVertexIterable;
@@ -10,7 +9,6 @@
 import net.floodlightcontroller.core.INetMapTopologyObjects.IDeviceObject;
 import net.floodlightcontroller.core.INetMapTopologyObjects.IPortObject;
 import net.floodlightcontroller.core.INetMapTopologyObjects.ISwitchObject;
-import net.floodlightcontroller.routing.Link;
 
 public class GraphDBUtils implements IDBUtils {
 
@@ -56,4 +54,10 @@
 		fg.removeVertex(dev.asVertex());		
 	}
 
+	@Override
+	public Iterable<IDeviceObject> getDevices(GraphDBConnection conn) {
+		FramedGraph<TitanGraph> fg = conn.getFramedGraph();	
+		return fg.getVertices("type","device",IDeviceObject.class);
+	}
+
 }
diff --git a/src/main/java/net/onrc/onos/util/IDBUtils.java b/src/main/java/net/onrc/onos/util/IDBUtils.java
index 52dbc70..a27a261 100644
--- a/src/main/java/net/onrc/onos/util/IDBUtils.java
+++ b/src/main/java/net/onrc/onos/util/IDBUtils.java
@@ -10,4 +10,5 @@
 	public IDeviceObject newDevice(GraphDBConnection conn);
 	public void removeDevice(GraphDBConnection conn, IDeviceObject dev);
 	public IPortObject searchPort(GraphDBConnection conn, String dpid, short number);
+	public Iterable<IDeviceObject> getDevices(GraphDBConnection conn);
 }
diff --git a/start-rest.sh b/start-rest.sh
index 28ea0f7..1f801fe 100755
--- a/start-rest.sh
+++ b/start-rest.sh
@@ -36,10 +36,11 @@
 
 function status {
     nr_process=`ps -edalf |grep ${script_name} | grep python | grep -v grep | wc -l` 
-    if [ x${nr_process} == "x" ] ; then
-      nr_process=0
+    if [ x${nr_process} != "x" ] ; then
+      echo "rest server is running"
+    else
+      echo "rest server is not running"
     fi
-    echo "${nr_process} instance of rest server is running"
 }
 
 function start {
diff --git a/web/js/onos-topology.js b/web/js/onos-topology.js
index 61eb9da..4e9dce1 100644
--- a/web/js/onos-topology.js
+++ b/web/js/onos-topology.js
@@ -22,26 +22,26 @@
 
     d3.json(data_source, init);
 
-/* For debugging  */
+/* For debugging  
     $("#more").click( function() {
         $.ajax({
-	    url: 'http://onosnat.onlab.us:8080/topology_more',
+	    url: 'http://gui.onlab.us:8080/topology_more',
 	    success: function(json) {
-		update(json)
+		update(json);
 	    },
 	    dataType: "json"
         });
     });
     $("#less").click( function() {
         $.ajax({
-	    url: 'http://onosnat.onlab.us:8080/topology_less',
+	    url: 'http://gui.onlab.us:8080/topology_less',
 	    success: function(json) {
-		update(json)
+		update(json);
 	    },
 	    dataType: "json"
         });
     });
-/**/
+*/
 
     function compare_link (a, b){
         if (a.source > b.source) {return 1;}
@@ -223,7 +223,7 @@
 	text.enter().append("svg:text")
 	    .attr("x", 8)
 	    .attr("y", ".31em")
-	    .text(function(d) { return d.name.split(":")[6] + d.name.split(":")[7] });
+	    .text(function(d) { return d.name.split(":")[5] + d.name.split(":")[6] + d.name.split(":")[7] });
 
         circle.append("title")
 	    .text(function(d) { return d.name; });
@@ -281,7 +281,7 @@
     }
 
     function init_draw(nodes, links){
-        path = svg.append("svg:g").selectAll("path").data(links)
+        path = svg.append("svg:g").selectAll("path").data(links);
         circle = svg.append("svg:g").selectAll("circle").data(nodes);
 	text = svg.append("svg:g").selectAll("text").data(nodes);
 
@@ -289,7 +289,6 @@
 
 	setInterval(function() {
             $.ajax({
-//		url: 'http://onosnat.onlab.us:8080/topology',
 		url: data_source,
 		success: function(json) {
 		    update(json)
diff --git a/web/shortest_path.py b/web/shortest_path.py
index 5bea182..381d052 100755
--- a/web/shortest_path.py
+++ b/web/shortest_path.py
@@ -34,6 +34,10 @@
     print '%s' % (txt)
 
 # @app.route("/wm/topology/route/<srcdpid>/<srcport>/<destdpid>/<destport>/json")
+#
+# Sample output:
+# {'dstPort': {'port': {'value': 0}, 'dpid': {'value': '00:00:00:00:00:00:00:02'}}, 'srcPort': {'port': {'value': 0}, 'dpid': {'value': '00:00:00:00:00:00:00:01'}}, 'flowEntries': [{'outPort': {'value': 1}, 'flowEntryErrorState': None, 'flowEntryMatch': None, 'flowEntryActions': None, 'inPort': {'value': 0}, 'flowEntryId': None, 'flowEntryUserState': 'FE_USER_UNKNOWN', 'dpid': {'value': '00:00:00:00:00:00:00:01'}, 'flowEntrySwitchState': 'FE_SWITCH_UNKNOWN'}, {'outPort': {'value': 0}, 'flowEntryErrorState': None, 'flowEntryMatch': None, 'flowEntryActions': None, 'inPort': {'value': 9}, 'flowEntryId': None, 'flowEntryUserState': 'FE_USER_UNKNOWN', 'dpid': {'value': '00:00:00:00:00:00:00:02'}, 'flowEntrySwitchState': 'FE_SWITCH_UNKNOWN'}]}
+#
 def shortest_path(v1, p1, v2, p2):
   try:
     command = "curl -s http://%s:%s/wm/topology/route/%s/%s/%s/%s/json" % (ControllerIP, ControllerPort, v1, p1, v2, p2)
@@ -46,10 +50,18 @@
   debug("shortest_path %s" % command)
   debug("parsed %s" % parsedResult)
 
-  for v in parsedResult:
-    dpid = v['switch'];
-    port = v['port'];
-    print "PathEntry: (%s, %s)" % (dpid, port)
+  srcSwitch = parsedResult['srcPort']['dpid']['value'];
+  srcPort = parsedResult['srcPort']['port']['value'];
+  dstSwitch = parsedResult['dstPort']['dpid']['value'];
+  dstPort = parsedResult['dstPort']['port']['value'];
+
+  print "DataPath: (src = %s/%s dst = %s/%s)" % (srcSwitch, srcPort, dstSwitch, dstPort);
+
+  for f in parsedResult['flowEntries']:
+    inPort = f['inPort']['value'];
+    outPort = f['outPort']['value'];
+    dpid = f['dpid']['value']
+    print "FlowEntry: (%s, %s, %s)" % (inPort, dpid, outPort)
 
 
 if __name__ == "__main__":
diff --git a/web/topology_rest.py b/web/topology_rest.py
index 0a6c756..9c820ef 100755
--- a/web/topology_rest.py
+++ b/web/topology_rest.py
@@ -121,19 +121,44 @@
       state = str(v['state'])
       sw = {}
       sw['name']=dpid
-      if str(v['state']) == "ACTIVE":
-        if dpid[-2:-1] == "a":
-         sw['group']=1
-        if dpid[-2:-1] == "b":
-         sw['group']=2
-        if dpid[-2:-1] == "c":
-         sw['group']=3
-      if str(v['state']) == "INACTIVE":
-         sw['group']=0
-
-
+      if state == "ACTIVE":
+#        print state
+        if dpid.split(":")[5] == "0a":
+          sw['group']=1
+        if dpid.split(":")[5] == "0b":
+          sw['group']=2
+        if dpid.split(":")[5] == "0c":
+          sw['group']=3
+      if state == "INACTIVE":
+#        print state
+        sw['group']=0
+#      print sw
       switches.append(sw)
-  
+
+  try:
+    command = "curl -s \'http://%s:%s/wm/registry/controllers/json\'" % (RestIP, RestPort)
+    result = os.popen(command).read()
+    controllers = json.loads(result)
+  except:
+    log_error("xx REST IF has issue: %s" % command)
+    log_error("%s" % result)
+
+  try:
+    command = "curl -s \'http://%s:%s/wm/registry/switches/json\'" % (RestIP, RestPort)
+    result = os.popen(command).read()
+    parsedResult = json.loads(result)
+  except:
+    log_error("REST IF has issue: %s" % command)
+    log_error("%s" % result)
+
+  for key in parsedResult:
+    dpid = key
+    ctrl = parsedResult[dpid][0]['controllerId']
+    sw_id = node_id(switches, dpid)
+    if sw_id != -1:
+      if switches[sw_id]['group'] != 0:
+        switches[sw_id]['group'] = controllers.index(ctrl) + 1
+
   try:
     command = "curl -s \'http://%s:%s/wm/core/topology/links/json\'" % (RestIP, RestPort)
     result = os.popen(command).read()
@@ -158,7 +183,7 @@
   topo['nodes'] = switches
   topo['links'] = links
 
-  pp.pprint(topo)
+#  pp.pprint(topo)
   js = json.dumps(topo)
   resp = Response(js, status=200, mimetype='application/json')
   return resp
@@ -246,15 +271,11 @@
   topo['nodes'] = switches
   topo['links'] = links
 
-  pp.pprint(topo)
+#  pp.pprint(topo)
   js = json.dumps(topo)
   resp = Response(js, status=200, mimetype='application/json')
   return resp
 
-
-
-
-
 @app.route("/wm/core/controller/switches/json")
 def query_switch():
   try:
@@ -281,7 +302,7 @@
         sw['active']=state
         switches_.append(sw)
 
-  pp.pprint(switches_)
+#  pp.pprint(switches_)
   js = json.dumps(switches_)
   resp = Response(js, status=200, mimetype='application/json')
   return resp
@@ -362,7 +383,7 @@
     sys.exit(0)
 
   debug("query_links %s" % command)
-  pp.pprint(parsedResult)
+#  pp.pprint(parsedResult)
   sport = []
   links = []
   for v in parsedResult:
@@ -392,11 +413,88 @@
         link["type"]="internal"
         links.append(link)
 
-  pp.pprint(links)
+#  pp.pprint(links)
   js = json.dumps(links)
   resp = Response(js, status=200, mimetype='application/json')
   return resp
 
+topo_less = { 
+  "nodes" : [ 
+    {"name" : "00:a0", "group" : 1},
+    {"name" : "00:a1", "group" : 1},
+    {"name" : "00:a2", "group" : 1},
+    ],
+  "links" : [
+    {"source" :0, "target": 1},
+    {"source" :1, "target": 0},
+    {"source" :0, "target": 2},
+    {"source" :2, "target": 0},
+    {"source" :1, "target": 2},
+    {"source" :2, "target": 1},
+    ]
+}
+
+topo_more = { 
+  "nodes" : [ 
+    {"name" : "00:a3", "group" : 2},
+    {"name" : "00:a0", "group" : 1},
+    {"name" : "00:a1", "group" : 1},
+    {"name" : "00:a2", "group" : 1},
+    ],
+  "links" : [
+    {"source" :1, "target": 2},
+    {"source" :2, "target": 1},
+    {"source" :1, "target": 3},
+    {"source" :3, "target": 1},
+    {"source" :2, "target": 3},
+    {"source" :3, "target": 2},
+    {"source" :0, "target": 2},
+    ]
+}
+
+@app.route("/topology_more")
+def topology_more():
+  topo = topo_more
+  js = json.dumps(topo)
+  resp = Response(js, status=200, mimetype='application/json')
+  return resp
+
+@app.route("/topology_less")
+def topology_less():
+  topo = topo_less
+  js = json.dumps(topo)
+  resp = Response(js, status=200, mimetype='application/json')
+  return resp
+
+cont_status1 = [
+           {"name":"onos9vpc",  "onos": 1, "cassandra": 1},
+            {"name":"onos10vpc",  "onos": 0, "cassandra": 1},
+            {"name":"onos11vpc",  "onos": 1, "cassandra": 0},
+            {"name":"onos12vpc",  "onos": 1, "cassandra": 0}]
+
+cont_status2 = [
+            {"name":"onos9vpc",  "onos": 0, "cassandra": 1},
+            {"name":"onos10vpc",  "onos": 0, "cassandra": 1},
+            {"name":"onos11vpc",  "onos": 0, "cassandra": 1},
+            {"name":"onos12vpc",  "onos": 0, "cassandra": 1}]
+
+@app.route("/controller_status1")
+def controller_status1():
+  status = cont_status1
+  js = json.dumps(status)
+  resp = Response(js, status=200, mimetype='application/json')
+  pp.pprint(resp)
+  return resp
+
+@app.route("/controller_status2")
+def controller_status2():
+  status = cont_status2
+  js = json.dumps(status)
+  resp = Response(js, status=200, mimetype='application/json')
+  pp.pprint(resp)
+  return resp
+
+
 if __name__ == "__main__":
   if len(sys.argv) > 1 and sys.argv[1] == "-d":
     print "-- query all switches --"