diff --git a/src/main/java/net/floodlightcontroller/core/web/ControllerSwitchesResource.java b/src/main/java/net/floodlightcontroller/core/web/ControllerSwitchesResource.java
index 63d361fcd9a3fc73500c48a770aa0cf9c6a9410b..423b8c1f6de9421fa78ba0d9733573db250dcf36 100644
--- a/src/main/java/net/floodlightcontroller/core/web/ControllerSwitchesResource.java
+++ b/src/main/java/net/floodlightcontroller/core/web/ControllerSwitchesResource.java
@@ -18,25 +18,59 @@
 package net.floodlightcontroller.core.web;
 
 import java.util.Set;
+import java.util.HashSet;
 
 import net.floodlightcontroller.core.internal.IOFSwitchService;
+import net.floodlightcontroller.core.IOFSwitch;
 
 import org.projectfloodlight.openflow.types.DatapathId;
 import org.restlet.resource.Get;
 import org.restlet.resource.ServerResource;
+import net.floodlightcontroller.core.web.serializers.DPIDSerializer;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+
 /**
  * Get a list of switches connected to the controller
  * @author readams
  */
 public class ControllerSwitchesResource extends ServerResource {
-	
-	public static final String DPID_ERROR = "Invalid switch DPID string. Must be a 64-bit value in the form 00:11:22:33:44:55:66:77.";
-	
+    
+    public static final String DPID_ERROR = "Invalid switch DPID string. Must be a 64-bit value in the form 00:11:22:33:44:55:66:77.";
+    public static class DatapathIDJsonSerializerWrapper {
+        private final DatapathId dpid;
+        private final String inetAddress; 
+        private final long connectedSince;
+        public DatapathIDJsonSerializerWrapper(DatapathId dpid, String inetAddress, long connectedSince) {
+            this.dpid = dpid;
+            this.inetAddress = inetAddress;
+            this.connectedSince = connectedSince;
+        }
+        
+        @JsonSerialize(using=DPIDSerializer.class)
+        public DatapathId getSwitchDPID() {
+            return dpid;
+        }
+        public String getInetAddress() {
+            return inetAddress;
+        }
+        public long getConnectedSince() {
+            return connectedSince;
+        }
+
+
+
+    }
+
     @Get("json")
-    public Set<DatapathId> retrieve(){
+    public Set<DatapathIDJsonSerializerWrapper> retrieve(){
         IOFSwitchService switchService = 
             (IOFSwitchService) getContext().getAttributes().
                 get(IOFSwitchService.class.getCanonicalName());
-        return switchService.getAllSwitchDpids();
+        Set<DatapathIDJsonSerializerWrapper> dpidSets = new HashSet<DatapathIDJsonSerializerWrapper>();
+        for(IOFSwitch sw: switchService.getAllSwitchMap().values()) {
+            dpidSets.add(new DatapathIDJsonSerializerWrapper(sw.getId(), sw.getInetAddress().toString(),  sw.getConnectedSince().getTime()));
+
+        }
+        return dpidSets;
     }
 }
diff --git a/src/main/java/net/floodlightcontroller/core/web/SwitchResourceBase.java b/src/main/java/net/floodlightcontroller/core/web/SwitchResourceBase.java
index 75e99083591fe2bc25597ddf119c5a1d8dac320b..1609818f4bc836e3b8cfb0e9a0e9d968105af368 100644
--- a/src/main/java/net/floodlightcontroller/core/web/SwitchResourceBase.java
+++ b/src/main/java/net/floodlightcontroller/core/web/SwitchResourceBase.java
@@ -127,6 +127,8 @@ public class SwitchResourceBase extends ServerResource {
 			case METER_CONFIG:
 			case METER_FEATURES:
 			case PORT_DESC:
+				req = sw.getOFFactory().buildPortDescStatsRequest()
+				.build();
 			case TABLE_FEATURES:
 			default:
 				log.error("Stats Request Type {} not implemented yet", statType.name());
@@ -174,4 +176,4 @@ public class SwitchResourceBase extends ServerResource {
 		return getSwitchFeaturesReply(DatapathId.of(switchId));
 	}
 
-}
\ No newline at end of file
+}
diff --git a/src/main/java/net/floodlightcontroller/core/web/SwitchStatisticsResource.java b/src/main/java/net/floodlightcontroller/core/web/SwitchStatisticsResource.java
index a6e7ad5e3d1145e9eed765f3333a735506a46aad..a100ddaf0b01fe1867e9d5738beaeca3ece335f1 100644
--- a/src/main/java/net/floodlightcontroller/core/web/SwitchStatisticsResource.java
+++ b/src/main/java/net/floodlightcontroller/core/web/SwitchStatisticsResource.java
@@ -91,7 +91,7 @@ public class SwitchStatisticsResource extends SwitchResourceBase {
 				result.setStatType(OFStatsType.EXPERIMENTER);
 				break;
 			case OFStatsTypeStrings.PORT_DESC:
-				values = getSwitchFeaturesReply(switchId);
+				values = getSwitchStatistics(switchId, OFStatsType.PORT_DESC);
 				result.setStatType(OFStatsType.PORT_DESC);
 				break;
 			case OFStatsTypeStrings.GROUP:
diff --git a/src/main/java/net/floodlightcontroller/core/web/serializers/StatsReplySerializer.java b/src/main/java/net/floodlightcontroller/core/web/serializers/StatsReplySerializer.java
index e9766245a8e25905470715aed9ef8eff563ba75d..16012307a7c0a9763e2c5892cd4933de828cf671 100644
--- a/src/main/java/net/floodlightcontroller/core/web/serializers/StatsReplySerializer.java
+++ b/src/main/java/net/floodlightcontroller/core/web/serializers/StatsReplySerializer.java
@@ -35,465 +35,602 @@ import net.floodlightcontroller.util.MatchUtils;
 
 import org.projectfloodlight.openflow.protocol.OFFlowStatsReply;
 import org.projectfloodlight.openflow.protocol.OFFlowStatsEntry;
+import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
+import org.projectfloodlight.openflow.protocol.OFPortStatsReply;
+import org.projectfloodlight.openflow.protocol.OFPortStatsEntry;
+import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply;
+import org.projectfloodlight.openflow.protocol.OFPortDesc;
+import org.projectfloodlight.openflow.protocol.OFPortFeatures;
+
+//Use the loxigen's serializer
+import org.projectfloodlight.openflow.protocol.ver13.OFPortFeaturesSerializerVer13;
+import org.projectfloodlight.openflow.protocol.ver12.OFPortFeaturesSerializerVer12;
+import org.projectfloodlight.openflow.protocol.ver11.OFPortFeaturesSerializerVer11;
+import org.projectfloodlight.openflow.protocol.ver10.OFPortFeaturesSerializerVer10;
+import org.projectfloodlight.openflow.protocol.ver13.OFPortStateSerializerVer13;
+import org.projectfloodlight.openflow.protocol.ver12.OFPortStateSerializerVer12;
+import org.projectfloodlight.openflow.protocol.ver11.OFPortStateSerializerVer11;
+import org.projectfloodlight.openflow.protocol.ver10.OFPortStateSerializerVer10;
+import org.projectfloodlight.openflow.protocol.ver13.OFPortConfigSerializerVer13;
+import org.projectfloodlight.openflow.protocol.ver12.OFPortConfigSerializerVer12;
+import org.projectfloodlight.openflow.protocol.ver11.OFPortConfigSerializerVer11;
+import org.projectfloodlight.openflow.protocol.ver10.OFPortConfigSerializerVer10;
+
+import org.projectfloodlight.openflow.protocol.OFAggregateStatsReply;
 import org.projectfloodlight.openflow.protocol.OFVersion;
 import org.projectfloodlight.openflow.protocol.match.*;
 import org.projectfloodlight.openflow.protocol.oxm.*;
 import org.projectfloodlight.openflow.protocol.instruction.*;
 import org.projectfloodlight.openflow.protocol.action.*;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 /**
  * Serialize a DPID as colon-separated hexadecimal
  */
 public class StatsReplySerializer extends JsonSerializer<StatsReply> {
-	@SuppressWarnings("unchecked")
-	@Override
-	public void serialize(StatsReply reply, JsonGenerator jGen, SerializerProvider serializer) throws IOException, JsonProcessingException {
-		// Return a nice error to user if the request we're about to serialize was bad
-		if (reply.getValues() == null) {
-			jGen.writeStartObject();
-			jGen.writeObjectFieldStart("ERROR");
-			jGen.writeStringField("1)", "Invalid DPID and/or stats/features request, or");
-			jGen.writeStringField("2)", "The switch might also be disconncted from the controller");
-			jGen.writeEndObject();
-			jGen.writeObjectFieldStart("Valid OFStatsTypes are");
-			jGen.writeStringField("1)", OFStatsTypeStrings.AGGREGATE);
-			jGen.writeStringField("2)", OFStatsTypeStrings.DESC);
-			jGen.writeStringField("3)", OFStatsTypeStrings.EXPERIMENTER);
-			jGen.writeStringField("4)", OFStatsTypeStrings.FEATURES);
-			jGen.writeStringField("5)", OFStatsTypeStrings.FLOW);
-			jGen.writeStringField("6)", OFStatsTypeStrings.GROUP);
-			jGen.writeStringField("7)", OFStatsTypeStrings.GROUP_DESC);
-			jGen.writeStringField("8)", OFStatsTypeStrings.GROUP_FEATURES);  
-			jGen.writeStringField("9)", OFStatsTypeStrings.METER);  
-			jGen.writeStringField("A)", OFStatsTypeStrings.METER_CONFIG); 
-			jGen.writeStringField("B)", OFStatsTypeStrings.PORT);
-			jGen.writeStringField("C)", OFStatsTypeStrings.PORT_DESC);
-			jGen.writeStringField("D)", OFStatsTypeStrings.QUEUE);
-			jGen.writeStringField("E)", OFStatsTypeStrings.TABLE);
-			jGen.writeStringField("F)", OFStatsTypeStrings.TABLE_FEATURES);
-			jGen.writeEndObject(); 
-			jGen.writeEndObject();
-			return;
-		}
-		
-		jGen.configure(Feature.WRITE_NUMBERS_AS_STRINGS, true); // IMHO this just looks nicer and is easier to read if everything is quoted
-		jGen.writeStartObject();
-		jGen.writeStringField("dpid", reply.getDatapathId().toString());
-		switch (reply.getStatType()) {
-		case PORT:
-			// handle port
-			break;
-		case QUEUE:
-			// handle queue
-			break;
-		case FLOW:
-			// handle flow. Can safely cast to List<OFFlowStatsReply>.
-			serializeFlowReply((List<OFFlowStatsReply>) reply.getValues(), jGen);
-			break;
-		case AGGREGATE:
-			// handle aggregate
-			break;
-		case DESC:
-			// handle desc
-			break;
-		case TABLE:
-			// handle table
-			break;
-		case TABLE_FEATURES:
-			// handle features
-			break;
-			// TODO need to handle new OF1.1+ stats reply types
-		case EXPERIMENTER:
-			break;
-		case GROUP:
-			break;
-		case GROUP_DESC:
-			break;
-		case GROUP_FEATURES:
-			break;
-		case METER:
-			break;
-		case METER_CONFIG:
-			break;
-		case METER_FEATURES:
-			break;
-		case PORT_DESC:
-			break;
-		default:
-			 break;
-		}   
-		jGen.writeEndObject();
-	}
+    protected static Logger logger = LoggerFactory.getLogger(StatsReplySerializer.class);
+    @SuppressWarnings("unchecked")
+    @Override
+    public void serialize(StatsReply reply, JsonGenerator jGen, SerializerProvider serializer) throws IOException, JsonProcessingException {
+        // Return a nice error to user if the request we're about to serialize was bad
+        if (reply.getValues() == null) {
+            jGen.writeStartObject();
+            jGen.writeObjectFieldStart("ERROR");
+            jGen.writeStringField("1)", "Invalid DPID and/or stats/features request, or");
+            jGen.writeStringField("2)", "The switch might also be disconncted from the controller");
+            jGen.writeEndObject();
+            jGen.writeObjectFieldStart("Valid OFStatsTypes are");
+            jGen.writeStringField("1)", OFStatsTypeStrings.AGGREGATE);
+            jGen.writeStringField("2)", OFStatsTypeStrings.DESC);
+            jGen.writeStringField("3)", OFStatsTypeStrings.EXPERIMENTER);
+            jGen.writeStringField("4)", OFStatsTypeStrings.FEATURES);
+            jGen.writeStringField("5)", OFStatsTypeStrings.FLOW);
+            jGen.writeStringField("6)", OFStatsTypeStrings.GROUP);
+            jGen.writeStringField("7)", OFStatsTypeStrings.GROUP_DESC);
+            jGen.writeStringField("8)", OFStatsTypeStrings.GROUP_FEATURES);  
+            jGen.writeStringField("9)", OFStatsTypeStrings.METER);  
+            jGen.writeStringField("A)", OFStatsTypeStrings.METER_CONFIG); 
+            jGen.writeStringField("B)", OFStatsTypeStrings.PORT);
+            jGen.writeStringField("C)", OFStatsTypeStrings.PORT_DESC);
+            jGen.writeStringField("D)", OFStatsTypeStrings.QUEUE);
+            jGen.writeStringField("E)", OFStatsTypeStrings.TABLE);
+            jGen.writeStringField("F)", OFStatsTypeStrings.TABLE_FEATURES);
+            jGen.writeEndObject(); 
+            jGen.writeEndObject();
+            return;
+        }
+        
+        jGen.configure(Feature.WRITE_NUMBERS_AS_STRINGS, true); // IMHO this just looks nicer and is easier to read if everything is quoted
+        jGen.writeStartObject();
+        jGen.writeStringField("dpid", reply.getDatapathId().toString());
+        switch (reply.getStatType()) {
+        case PORT:
+            // handle port
+            serializePortReply((List<OFPortStatsReply>) reply.getValues(), jGen);
+            break;
+        case QUEUE:
+            // handle queue
+            break;
+        case FLOW:
+            // handle flow. Can safely cast to List<OFFlowStatsReply>.
+            serializeFlowReply((List<OFFlowStatsReply>) reply.getValues(), jGen);
+            break;
+        case AGGREGATE:
+            // handle aggregate
+            serializeAggregateReply((List<OFAggregateStatsReply>) reply.getValues(), jGen);
+            break;
+        case DESC:
+            // handle desc
+            serializeDescReply((List<OFDescStatsReply>) reply.getValues(), jGen);
+            break;
+        case TABLE:
+            // handle table
+            break;
+        case TABLE_FEATURES:
+            // handle features
+            break;
+            // TODO need to handle new OF1.1+ stats reply types
+        case EXPERIMENTER:
+            break;
+        case GROUP:
+            break;
+        case GROUP_DESC:
+            break;
+        case GROUP_FEATURES:
+            break;
+        case METER:
+            break;
+        case METER_CONFIG:
+            break;
+        case METER_FEATURES:
+            break;
+        case PORT_DESC:
+            serializePortDescReply((List<OFPortDescStatsReply>) reply.getValues(), jGen);
+            break;
+        default:
+             break;
+        }   
+        jGen.writeEndObject();
+    }
+
+    public void serializePortReply(List<OFPortStatsReply> portReplies, JsonGenerator jGen) throws IOException, JsonProcessingException{
+        OFPortStatsReply portReply = portReplies.get(0); // we will get only one PortReply and it will contains many OFPortStatsEntry ?
+        jGen.writeStringField("version", portReply.getVersion().toString()); //return the enum name
+        jGen.writeFieldName("port");
+        jGen.writeStartArray();
+        for(OFPortStatsEntry entry : portReply.getEntries()) {
+            jGen.writeStartObject();
+            jGen.writeStringField("portNumber",entry.getPortNo().toString());
+            jGen.writeNumberField("receivePackets", entry.getRxPackets().getValue());
+            jGen.writeNumberField("transmitPackets", entry.getTxPackets().getValue());
+            jGen.writeNumberField("receiveBytes", entry.getRxBytes().getValue());
+            jGen.writeNumberField("transmitBytes", entry.getTxBytes().getValue());
+            jGen.writeNumberField("receiveDropped", entry.getRxDropped().getValue());
+            jGen.writeNumberField("transmitDropped", entry.getTxDropped().getValue());
+            jGen.writeNumberField("receiveErrors", entry.getRxErrors().getValue());
+            jGen.writeNumberField("transmitErrors", entry.getTxErrors().getValue());
+            jGen.writeNumberField("receiveFrameErrors", entry.getRxFrameErr().getValue());
+            jGen.writeNumberField("receiveOverrunErrors", entry.getRxOverErr().getValue());
+            jGen.writeNumberField("receiveCRCErrors", entry.getRxCrcErr().getValue());
+            jGen.writeNumberField("collisions", entry.getCollisions().getValue());
+            if (OFVersion.OF_13 == entry.getVersion()) {
+                jGen.writeNumberField("durationSec", entry.getDurationSec());
+                jGen.writeNumberField("durationNsec", entry.getDurationNsec());
+            }
+            jGen.writeEndObject();
+        }
+        jGen.writeEndArray();
+    }
+    public void serializeFlowReply(List<OFFlowStatsReply> flowReplies, JsonGenerator jGen) throws IOException, JsonProcessingException{
+        int flowCount = 0;
+        for (OFFlowStatsReply flowReply : flowReplies) { // for each flow stats reply
+            //Dose the switch will reply multiple OFFlowStatsReply ?
+            //Or we juse need to use the first item of the list.
+            List<OFFlowStatsEntry> entries = flowReply.getEntries();
+            jGen.writeFieldName("flows");
+            jGen.writeStartArray();
+            for (OFFlowStatsEntry entry : entries) { // for each flow
+                jGen.writeStartObject();
+                // list flow stats/info
+                jGen.writeStringField("version", entry.getVersion().toString()); // return the enum name
+                jGen.writeNumberField("cookie", entry.getCookie().getValue());
+                jGen.writeNumberField("tableId", entry.getTableId().getValue());
+                jGen.writeNumberField("packetCount", entry.getPacketCount().getValue());
+                jGen.writeNumberField("byteCount", entry.getByteCount().getValue());
+                jGen.writeNumberField("durationSeconds", entry.getDurationSec());
+                jGen.writeNumberField("priority", entry.getPriority());
+                jGen.writeNumberField("idleTimeoutSec", entry.getIdleTimeout());
+                jGen.writeNumberField("hardTimeoutSec", entry.getHardTimeout());
+                jGen.writeNumberField("flags", entry.getFlags());
+                // list flow matches
+                jGen.writeObjectFieldStart("match");
+                Iterator<MatchField<?>> mi = entry.getMatch().getMatchFields().iterator(); // get iter to any match field type
+                Match m = entry.getMatch();
+
+                while (mi.hasNext()) {
+                    MatchField<?> mf = mi.next();
+                    switch (mf.id) {
+                    case IN_PORT:
+                        jGen.writeNumberField(MatchUtils.STR_IN_PORT, m.get(MatchField.IN_PORT).getPortNumber());
+                        break;
+                    case IN_PHY_PORT:
+                        jGen.writeNumberField(MatchUtils.STR_IN_PHYS_PORT, m.get(MatchField.IN_PHY_PORT).getPortNumber());
+                        break;
+                    case ARP_OP:
+                        jGen.writeNumberField(MatchUtils.STR_ARP_OPCODE, m.get(MatchField.ARP_OP).getOpcode());
+                        break;
+                    case ARP_SHA:
+                        jGen.writeStringField(MatchUtils.STR_ARP_SHA, m.get(MatchField.ARP_SHA).toString());
+                        break;
+                    case ARP_SPA:
+                        jGen.writeStringField(MatchUtils.STR_ARP_SPA, m.get(MatchField.ARP_SPA).toString());
+                        break;
+                    case ARP_THA:
+                        jGen.writeStringField(MatchUtils.STR_ARP_DHA, m.get(MatchField.ARP_THA).toString());
+                        break;
+                    case ARP_TPA:
+                        jGen.writeStringField(MatchUtils.STR_ARP_DPA, m.get(MatchField.ARP_TPA).toString());
+                        break;
+                    case ETH_TYPE:
+                        jGen.writeNumberField(MatchUtils.STR_DL_TYPE, m.get(MatchField.ETH_TYPE).getValue());
+                        break;
+                    case ETH_SRC:
+                        jGen.writeStringField(MatchUtils.STR_DL_SRC, m.get(MatchField.ETH_SRC).toString());
+                        break;
+                    case ETH_DST:
+                        jGen.writeStringField(MatchUtils.STR_DL_DST, m.get(MatchField.ETH_DST).toString());
+                        break;
+                    case VLAN_VID:
+                        jGen.writeNumberField(MatchUtils.STR_DL_VLAN, m.get(MatchField.VLAN_VID).getVlan());
+                        break;
+                    case VLAN_PCP:
+                        jGen.writeNumberField(MatchUtils.STR_DL_VLAN_PCP, m.get(MatchField.VLAN_PCP).getValue());
+                        break;
+                    case ICMPV4_TYPE:
+                        jGen.writeNumberField(MatchUtils.STR_ICMP_TYPE, m.get(MatchField.ICMPV4_TYPE).getType());
+                        break;
+                    case ICMPV4_CODE:
+                        jGen.writeNumberField(MatchUtils.STR_ICMP_CODE, m.get(MatchField.ICMPV4_CODE).getCode());
+                        break;
+                    case ICMPV6_TYPE:
+                        jGen.writeNumberField(MatchUtils.STR_ICMPV6_TYPE, m.get(MatchField.ICMPV6_TYPE).getValue());
+                        break;
+                    case ICMPV6_CODE:
+                        jGen.writeNumberField(MatchUtils.STR_ICMPV6_CODE, m.get(MatchField.ICMPV6_CODE).getValue());
+                        break;
+                    case IP_DSCP:
+                        jGen.writeNumberField(MatchUtils.STR_NW_DSCP, m.get(MatchField.IP_DSCP).getDscpValue());
+                        break;
+                    case IP_ECN:
+                        jGen.writeNumberField(MatchUtils.STR_NW_ECN, m.get(MatchField.IP_ECN).getEcnValue());
+                        break;
+                    case IP_PROTO:
+                        jGen.writeNumberField(MatchUtils.STR_NW_PROTO, m.get(MatchField.IP_PROTO).getIpProtocolNumber());
+                        break;
+                    case IPV4_SRC:
+                        jGen.writeStringField(MatchUtils.STR_NW_SRC, m.get(MatchField.IPV4_SRC).toString());
+                        break;
+                    case IPV4_DST:
+                        jGen.writeStringField(MatchUtils.STR_NW_DST, m.get(MatchField.IPV4_DST).toString());
+                        break;
+                    case IPV6_SRC:
+                        jGen.writeStringField(MatchUtils.STR_IPV6_SRC, m.get(MatchField.IPV6_SRC).toString());
+                        break;
+                    case IPV6_DST:
+                        jGen.writeStringField(MatchUtils.STR_IPV6_DST, m.get(MatchField.IPV6_DST).toString());
+                        break;
+                    case IPV6_FLABEL:
+                        jGen.writeNumberField(MatchUtils.STR_IPV6_FLOW_LABEL, m.get(MatchField.IPV6_FLABEL).getIPv6FlowLabelValue());
+                        break;
+                    case IPV6_ND_SLL:
+                        jGen.writeNumberField(MatchUtils.STR_IPV6_ND_SSL, m.get(MatchField.IPV6_ND_SLL).getLong());
+                        break;
+                    case IPV6_ND_TARGET:
+                        jGen.writeNumberField(MatchUtils.STR_IPV6_ND_TARGET, m.get(MatchField.IPV6_ND_TARGET).getZeroCompressStart());
+                        break;
+                    case IPV6_ND_TLL:
+                        jGen.writeNumberField(MatchUtils.STR_IPV6_ND_TTL, m.get(MatchField.IPV6_ND_TLL).getLong());
+                        break;
+                    case METADATA:
+                        jGen.writeNumberField(MatchUtils.STR_METADATA, m.get(MatchField.METADATA).getValue().getValue());
+                        break;
+                    case MPLS_LABEL:
+                        jGen.writeNumberField(MatchUtils.STR_MPLS_LABEL, m.get(MatchField.MPLS_LABEL).getValue());
+                        break;
+                    case MPLS_TC:
+                        jGen.writeNumberField(MatchUtils.STR_MPLS_TC, m.get(MatchField.MPLS_TC).getValue());
+                        break;
+                    case SCTP_SRC:
+                        jGen.writeNumberField(MatchUtils.STR_SCTP_SRC, m.get(MatchField.SCTP_SRC).getPort());
+                        break;
+                    case SCTP_DST:
+                        jGen.writeNumberField(MatchUtils.STR_SCTP_DST, m.get(MatchField.SCTP_DST).getPort());
+                        break;
+                    case TCP_SRC:
+                        jGen.writeNumberField(MatchUtils.STR_TCP_SRC, m.get(MatchField.TCP_SRC).getPort());
+                        break;
+                    case TCP_DST:
+                        jGen.writeNumberField(MatchUtils.STR_TCP_DST, m.get(MatchField.TCP_DST).getPort());
+                        break;
+                    case UDP_SRC:
+                        jGen.writeNumberField(MatchUtils.STR_UDP_SRC, m.get(MatchField.UDP_SRC).getPort());
+                        break;
+                    case UDP_DST:
+                        jGen.writeNumberField(MatchUtils.STR_UDP_DST, m.get(MatchField.UDP_DST).getPort());
+                        break;
+                    default:
+                        // either a BSN or unknown match type
+                        break;
+                    } // end switch of match type
+                } // end while over non-wildcarded matches
 
-	public void serializeFlowReply(List<OFFlowStatsReply> flowReplies, JsonGenerator jGen) throws IOException, JsonProcessingException{
-		int flowCount = 0;
-		for (OFFlowStatsReply flowReply : flowReplies) { // for each flow stats reply
-			List<OFFlowStatsEntry> entries = flowReply.getEntries();
-			for (OFFlowStatsEntry entry : entries) { // for each flow
-				// list flow stats/info
-				jGen.writeObjectFieldStart("flow" + Integer.toString(flowCount++)); // need to have different object names or JSON parser might only show the last one
-				jGen.writeStringField("version", entry.getVersion().toString()); // return the enum name
-				jGen.writeNumberField("cookie", entry.getCookie().getValue());
-				jGen.writeNumberField("table_id", entry.getTableId().getValue());
-				jGen.writeNumberField("packet_count", entry.getPacketCount().getValue());
-				jGen.writeNumberField("byte_count", entry.getByteCount().getValue());
-				jGen.writeNumberField("duration_sec", entry.getDurationSec());
-				jGen.writeNumberField("priority", entry.getPriority());
-				jGen.writeNumberField("idle_timeout_sec", entry.getIdleTimeout());
-				jGen.writeNumberField("hard_timeout_sec", entry.getHardTimeout());
-				jGen.writeNumberField("flags", entry.getFlags());
-				// list flow matches
-				jGen.writeObjectFieldStart("match");
-				Iterator<MatchField<?>> mi = entry.getMatch().getMatchFields().iterator(); // get iter to any match field type
-				Match m = entry.getMatch();
+                jGen.writeEndObject(); // end match
 
-				while (mi.hasNext()) {
-					MatchField<?> mf = mi.next();
-					switch (mf.id) {
-					case IN_PORT:
-						jGen.writeNumberField(MatchUtils.STR_IN_PORT, m.get(MatchField.IN_PORT).getPortNumber());
-						break;
-					case IN_PHY_PORT:
-						jGen.writeNumberField(MatchUtils.STR_IN_PHYS_PORT, m.get(MatchField.IN_PHY_PORT).getPortNumber());
-						break;
-					case ARP_OP:
-						jGen.writeNumberField(MatchUtils.STR_ARP_OPCODE, m.get(MatchField.ARP_OP).getOpcode());
-						break;
-					case ARP_SHA:
-						jGen.writeStringField(MatchUtils.STR_ARP_SHA, m.get(MatchField.ARP_SHA).toString());
-						break;
-					case ARP_SPA:
-						jGen.writeStringField(MatchUtils.STR_ARP_SPA, m.get(MatchField.ARP_SPA).toString());
-						break;
-					case ARP_THA:
-						jGen.writeStringField(MatchUtils.STR_ARP_DHA, m.get(MatchField.ARP_THA).toString());
-						break;
-					case ARP_TPA:
-						jGen.writeStringField(MatchUtils.STR_ARP_DPA, m.get(MatchField.ARP_TPA).toString());
-						break;
-					case ETH_TYPE:
-						jGen.writeNumberField(MatchUtils.STR_DL_TYPE, m.get(MatchField.ETH_TYPE).getValue());
-						break;
-					case ETH_SRC:
-						jGen.writeStringField(MatchUtils.STR_DL_SRC, m.get(MatchField.ETH_SRC).toString());
-						break;
-					case ETH_DST:
-						jGen.writeStringField(MatchUtils.STR_DL_DST, m.get(MatchField.ETH_DST).toString());
-						break;
-					case VLAN_VID:
-						jGen.writeNumberField(MatchUtils.STR_DL_VLAN, m.get(MatchField.VLAN_VID).getVlan());
-						break;
-					case VLAN_PCP:
-						jGen.writeNumberField(MatchUtils.STR_DL_VLAN_PCP, m.get(MatchField.VLAN_PCP).getValue());
-						break;
-					case ICMPV4_TYPE:
-						jGen.writeNumberField(MatchUtils.STR_ICMP_TYPE, m.get(MatchField.ICMPV4_TYPE).getType());
-						break;
-					case ICMPV4_CODE:
-						jGen.writeNumberField(MatchUtils.STR_ICMP_CODE, m.get(MatchField.ICMPV4_CODE).getCode());
-						break;
-					case ICMPV6_TYPE:
-						jGen.writeNumberField(MatchUtils.STR_ICMPV6_TYPE, m.get(MatchField.ICMPV6_TYPE).getValue());
-						break;
-					case ICMPV6_CODE:
-						jGen.writeNumberField(MatchUtils.STR_ICMPV6_CODE, m.get(MatchField.ICMPV6_CODE).getValue());
-						break;
-					case IP_DSCP:
-						jGen.writeNumberField(MatchUtils.STR_NW_DSCP, m.get(MatchField.IP_DSCP).getDscpValue());
-						break;
-					case IP_ECN:
-						jGen.writeNumberField(MatchUtils.STR_NW_ECN, m.get(MatchField.IP_ECN).getEcnValue());
-						break;
-					case IP_PROTO:
-						jGen.writeNumberField(MatchUtils.STR_NW_PROTO, m.get(MatchField.IP_PROTO).getIpProtocolNumber());
-						break;
-					case IPV4_SRC:
-						jGen.writeStringField(MatchUtils.STR_NW_SRC, m.get(MatchField.IPV4_SRC).toString());
-						break;
-					case IPV4_DST:
-						jGen.writeStringField(MatchUtils.STR_NW_DST, m.get(MatchField.IPV4_DST).toString());
-						break;
-					case IPV6_SRC:
-						jGen.writeStringField(MatchUtils.STR_IPV6_SRC, m.get(MatchField.IPV6_SRC).toString());
-						break;
-					case IPV6_DST:
-						jGen.writeStringField(MatchUtils.STR_IPV6_DST, m.get(MatchField.IPV6_DST).toString());
-						break;
-					case IPV6_FLABEL:
-						jGen.writeNumberField(MatchUtils.STR_IPV6_FLOW_LABEL, m.get(MatchField.IPV6_FLABEL).getIPv6FlowLabelValue());
-						break;
-					case IPV6_ND_SLL:
-						jGen.writeNumberField(MatchUtils.STR_IPV6_ND_SSL, m.get(MatchField.IPV6_ND_SLL).getLong());
-						break;
-					case IPV6_ND_TARGET:
-						jGen.writeNumberField(MatchUtils.STR_IPV6_ND_TARGET, m.get(MatchField.IPV6_ND_TARGET).getZeroCompressStart());
-						break;
-					case IPV6_ND_TLL:
-						jGen.writeNumberField(MatchUtils.STR_IPV6_ND_TTL, m.get(MatchField.IPV6_ND_TLL).getLong());
-						break;
-					case METADATA:
-						jGen.writeNumberField(MatchUtils.STR_METADATA, m.get(MatchField.METADATA).getValue().getValue());
-						break;
-					case MPLS_LABEL:
-						jGen.writeNumberField(MatchUtils.STR_MPLS_LABEL, m.get(MatchField.MPLS_LABEL).getValue());
-						break;
-					case MPLS_TC:
-						jGen.writeNumberField(MatchUtils.STR_MPLS_TC, m.get(MatchField.MPLS_TC).getValue());
-						break;
-					case SCTP_SRC:
-						jGen.writeNumberField(MatchUtils.STR_SCTP_SRC, m.get(MatchField.SCTP_SRC).getPort());
-						break;
-					case SCTP_DST:
-						jGen.writeNumberField(MatchUtils.STR_SCTP_DST, m.get(MatchField.SCTP_DST).getPort());
-						break;
-					case TCP_SRC:
-						jGen.writeNumberField(MatchUtils.STR_TCP_SRC, m.get(MatchField.TCP_SRC).getPort());
-						break;
-					case TCP_DST:
-						jGen.writeNumberField(MatchUtils.STR_TCP_DST, m.get(MatchField.TCP_DST).getPort());
-						break;
-					case UDP_SRC:
-						jGen.writeNumberField(MatchUtils.STR_UDP_SRC, m.get(MatchField.UDP_SRC).getPort());
-						break;
-					case UDP_DST:
-						jGen.writeNumberField(MatchUtils.STR_UDP_DST, m.get(MatchField.UDP_DST).getPort());
-						break;
-					default:
-						// either a BSN or unknown match type
-						break;
-					} // end switch of match type
-				} // end while over non-wildcarded matches
+                // handle OF1.1+ instructions with actions within
+                if (entry.getVersion() == OFVersion.OF_10) {
+                    serializeActions(jGen, entry.getActions());
+                } else {
+                    List<OFInstruction> instructions = entry.getInstructions();
+                    jGen.writeObjectFieldStart("instructions");
+                    if (instructions.isEmpty()) {
+                        jGen.writeStringField("none", "drop");
+                    } else {
+                        for (OFInstruction i : instructions) {
+                            switch (i.getType()) {
+                            case CLEAR_ACTIONS:
+                                jGen.writeObjectFieldStart(InstructionUtils.STR_CLEAR_ACTIONS);
+                                break;
+                            case WRITE_METADATA:
+                                jGen.writeStartObject();
+                                jGen.writeNumberField(InstructionUtils.STR_WRITE_METADATA, ((OFInstructionWriteMetadata)i).getMetadata().getValue());
+                                jGen.writeNumberField(InstructionUtils.STR_WRITE_METADATA + "_mask", ((OFInstructionWriteMetadata)i).getMetadataMask().getValue());
+                                break;
+                            case EXPERIMENTER:
+                                jGen.writeStartObject();
+                                jGen.writeNumberField(InstructionUtils.STR_EXPERIMENTER, ((OFInstructionExperimenter)i).getExperimenter());
+                                break;
+                            case GOTO_TABLE:
+                                jGen.writeStartObject();
+                                jGen.writeNumberField(InstructionUtils.STR_GOTO_TABLE, ((OFInstructionGotoTable)i).getTableId().getValue());
+                                break;
+                            case METER:
+                                jGen.writeStartObject();
+                                jGen.writeNumberField(InstructionUtils.STR_GOTO_METER, ((OFInstructionMeter)i).getMeterId());
+                                break;
+                            case APPLY_ACTIONS:
+                                jGen.writeObjectFieldStart(InstructionUtils.STR_APPLY_ACTIONS);
+                                serializeActions(jGen, ((OFInstructionApplyActions)i).getActions());
+                                break;
+                            case WRITE_ACTIONS:
+                                jGen.writeObjectFieldStart(InstructionUtils.STR_WRITE_ACTIONS);
+                                serializeActions(jGen, ((OFInstructionWriteActions)i).getActions());
+                            default:
+                                // shouldn't ever get here
+                                break;
+                            } // end switch on instruction
+                            jGen.writeEndObject(); // end specific instruction
+                        } // end for instructions
+                        jGen.writeEndObject();
+                    } // end process instructions (OF1.1+ only)
+                } // end not-empty instructions (else)
+                jGen.writeEndObject();
+            } // end for each OFFlowStatsReply entry
+            jGen.writeEndArray();
+        } // end for each OFStatsReply
+    } // end method
 
-				jGen.writeEndObject(); // end match
+    /**
+     * Write a JSON string given a list of OFAction. Supports OF1.0 - OF1.3.
+     * This is the only place actions are serialized, for any OF version. Because
+     * some OF version share actions, it makes sense to have them in one place.
+     * @param jsonGenerator
+     * @param actions
+     * @throws IOException
+     * @throws JsonProcessingException
+     */
+    public void serializeActions(JsonGenerator jsonGenerator, List<OFAction> actions) throws IOException, JsonProcessingException {
+        //jsonGenerator.writeStartObject();
+        if (actions.isEmpty()) {
+            jsonGenerator.writeStringField("none", "drop");
+        }
+        for (OFAction a : actions) {
+            switch (a.getType()) {
+            case OUTPUT: //TODO @Ryan need to reference the predefined string constants for each of the actions/oxms
+                jsonGenerator.writeNumberField(ActionUtils.STR_OUTPUT, ((OFActionOutput)a).getPort().getPortNumber());
+                break;
+            /* begin OF1.0 ONLY actions */
+            case SET_VLAN_VID:
+                jsonGenerator.writeNumberField(ActionUtils.STR_VLAN_SET_VID, ((OFActionSetVlanVid)a).getVlanVid().getVlan());
+                break;
+            case SET_VLAN_PCP:
+                jsonGenerator.writeNumberField(ActionUtils.STR_VLAN_SET_PCP, ((OFActionSetVlanPcp)a).getVlanPcp().getValue());
+                break;
+            case SET_QUEUE:
+                jsonGenerator.writeNumberField(ActionUtils.STR_QUEUE_SET, ((OFActionSetQueue)a).getQueueId());
+                break;
+            case SET_DL_SRC:
+                jsonGenerator.writeStringField(ActionUtils.STR_DL_SRC_SET, ((OFActionSetDlSrc)a).getDlAddr().toString());
+                break;
+            case SET_DL_DST:
+                jsonGenerator.writeStringField(ActionUtils.STR_DL_DST_SET, ((OFActionSetDlDst)a).getDlAddr().toString());
+                break;
+            case SET_NW_SRC:
+                jsonGenerator.writeStringField(ActionUtils.STR_NW_SRC_SET, ((OFActionSetNwSrc)a).getNwAddr().toString());
+                break;
+            case SET_NW_DST:
+                jsonGenerator.writeStringField(ActionUtils.STR_NW_DST_SET, ((OFActionSetNwDst)a).getNwAddr().toString());
+                break;
+            case SET_NW_TOS:
+                jsonGenerator.writeNumberField(ActionUtils.STR_NW_TOS_SET, ((OFActionSetNwTos)a).getNwTos());
+                break;    
+            case SET_TP_SRC:
+                jsonGenerator.writeNumberField(ActionUtils.STR_TP_SRC_SET, ((OFActionSetTpSrc)a).getTpPort().getPort());
+                break;
+            case SET_TP_DST:
+                jsonGenerator.writeNumberField(ActionUtils.STR_TP_DST_SET, ((OFActionSetTpDst)a).getTpPort().getPort());
+                break;
+            /* end OF1.0 ONLY actions; begin OF1.1+ actions */
+            case ENQUEUE:
+                jsonGenerator.writeNumberField(ActionUtils.STR_ENQUEUE, ((OFActionEnqueue)a).getPort().getPortNumber());
+                break;
+            case GROUP:
+                jsonGenerator.writeNumberField(ActionUtils.STR_GROUP, ((OFActionGroup)a).getGroup().getGroupNumber());
+                break;
+            case STRIP_VLAN:
+                jsonGenerator.writeString(ActionUtils.STR_VLAN_STRIP);
+                break;
+            case PUSH_VLAN:
+                jsonGenerator.writeNumberField(ActionUtils.STR_VLAN_PUSH, ((OFActionPushVlan)a).getEthertype().getValue());
+                break;
+            case PUSH_MPLS:
+                jsonGenerator.writeNumberField(ActionUtils.STR_MPLS_PUSH, ((OFActionPushMpls)a).getEthertype().getValue());
+                break;
+            case PUSH_PBB:
+                jsonGenerator.writeNumberField(ActionUtils.STR_PBB_PUSH, ((OFActionPushPbb)a).getEthertype().getValue());
+                break;
+            case POP_VLAN:
+                jsonGenerator.writeString(ActionUtils.STR_VLAN_POP);
+                break;
+            case POP_MPLS:
+                jsonGenerator.writeNumberField(ActionUtils.STR_MPLS_POP, ((OFActionPopMpls)a).getEthertype().getValue());
+                break;
+            case POP_PBB:
+                jsonGenerator.writeString(ActionUtils.STR_PBB_POP);
+                break;
+            case COPY_TTL_IN:
+                jsonGenerator.writeString(ActionUtils.STR_TTL_IN_COPY);
+                break;
+            case COPY_TTL_OUT:
+                jsonGenerator.writeString(ActionUtils.STR_TTL_OUT_COPY);
+                break;
+            case DEC_NW_TTL:
+                jsonGenerator.writeString(ActionUtils.STR_NW_TTL_DEC);
+                break;
+            case DEC_MPLS_TTL:
+                jsonGenerator.writeString(ActionUtils.STR_MPLS_TTL_DEC);
+                break;
+            case SET_MPLS_LABEL:
+                jsonGenerator.writeNumberField(ActionUtils.STR_MPLS_LABEL_SET, ((OFActionSetMplsLabel)a).getMplsLabel());
+                break;
+            case SET_MPLS_TC:
+                jsonGenerator.writeNumberField(ActionUtils.STR_MPLS_TC_SET, ((OFActionSetMplsTc)a).getMplsTc());
+                break;
+            case SET_MPLS_TTL:
+                jsonGenerator.writeNumberField(ActionUtils.STR_MPLS_TTL_SET, ((OFActionSetMplsTtl)a).getMplsTtl());
+                break;
+            case SET_NW_ECN:
+                jsonGenerator.writeNumberField(ActionUtils.STR_NW_ECN_SET, ((OFActionSetNwEcn)a).getNwEcn().getEcnValue());
+                break;
+            case SET_NW_TTL:
+                jsonGenerator.writeNumberField(ActionUtils.STR_NW_TTL_SET, ((OFActionSetNwTtl)a).getNwTtl());
+                break;
+            case EXPERIMENTER:
+                jsonGenerator.writeNumberField(ActionUtils.STR_EXPERIMENTER, ((OFActionExperimenter)a).getExperimenter());
+                break;
+            case SET_FIELD:
+                if (((OFActionSetField)a).getField() instanceof OFOxmArpOp) {
+                    jsonGenerator.writeNumberField(MatchUtils.STR_ARP_OPCODE, ((OFOxmArpOp) ((OFActionSetField) a).getField()).getValue().getOpcode());
+                } else if (((OFActionSetField)a).getField() instanceof OFOxmArpSha) {
+                    jsonGenerator.writeStringField(MatchUtils.STR_ARP_SHA, ((OFOxmArpSha) ((OFActionSetField) a).getField()).getValue().toString()); // macaddress formats string already
+                } else if (((OFActionSetField)a).getField() instanceof OFOxmArpTha) {
+                    jsonGenerator.writeStringField(MatchUtils.STR_ARP_DHA, ((OFOxmArpTha) ((OFActionSetField) a).getField()).getValue().toString());
+                } else if (((OFActionSetField)a).getField() instanceof OFOxmArpSpa) {
+                    jsonGenerator.writeStringField(MatchUtils.STR_ARP_SPA, ((OFOxmArpSpa) ((OFActionSetField) a).getField()).getValue().toString()); // ipaddress formats string already
+                } else if (((OFActionSetField)a).getField() instanceof OFOxmArpTpa) {
+                    jsonGenerator.writeStringField(MatchUtils.STR_ARP_DPA, ((OFOxmArpTpa) ((OFActionSetField) a).getField()).getValue().toString()); 
+                } 
+                /* DATA LAYER */
+                else if (((OFActionSetField)a).getField() instanceof OFOxmEthType) {
+                    jsonGenerator.writeNumberField(MatchUtils.STR_DL_TYPE, ((OFOxmEthType) ((OFActionSetField) a).getField()).getValue().getValue());
+                } else if (((OFActionSetField)a).getField() instanceof OFOxmEthSrc) {
+                    jsonGenerator.writeStringField(MatchUtils.STR_DL_SRC, ((OFOxmEthSrc) ((OFActionSetField) a).getField()).getValue().toString());
+                } else if (((OFActionSetField)a).getField() instanceof OFOxmEthDst) {
+                    jsonGenerator.writeStringField(MatchUtils.STR_DL_DST, ((OFOxmEthDst) ((OFActionSetField) a).getField()).getValue().toString()); 
+                } else if (((OFActionSetField)a).getField() instanceof OFOxmVlanVid) {
+                    jsonGenerator.writeNumberField(MatchUtils.STR_DL_VLAN, ((OFOxmVlanVid) ((OFActionSetField) a).getField()).getValue().getVlan()); 
+                } else if (((OFActionSetField)a).getField() instanceof OFOxmVlanPcp) {
+                } 
+                /* ICMP */
+                else if (((OFActionSetField)a).getField() instanceof OFOxmIcmpv4Code) {
+                    jsonGenerator.writeNumberField(MatchUtils.STR_ICMP_CODE, ((OFOxmIcmpv4Code) ((OFActionSetField) a).getField()).getValue().getCode()); 
+                } else if (((OFActionSetField)a).getField() instanceof OFOxmIcmpv4Type) {
+                    jsonGenerator.writeNumberField(MatchUtils.STR_ICMP_TYPE, ((OFOxmIcmpv4Type) ((OFActionSetField) a).getField()).getValue().getType()); 
+                } 
+                /* NETWORK LAYER */
+                else if (((OFActionSetField)a).getField() instanceof OFOxmIpProto) {
+                    jsonGenerator.writeNumberField(MatchUtils.STR_NW_PROTO, ((OFOxmIpProto) ((OFActionSetField) a).getField()).getValue().getIpProtocolNumber()); 
+                } else if (((OFActionSetField)a).getField() instanceof OFOxmIpv4Src) {
+                    jsonGenerator.writeStringField(MatchUtils.STR_NW_SRC, ((OFOxmIpv4Src) ((OFActionSetField) a).getField()).getValue().toString()); 
+                } else if (((OFActionSetField)a).getField() instanceof OFOxmIpv4Dst) {
+                    jsonGenerator.writeStringField(MatchUtils.STR_NW_DST, ((OFOxmIpv4Dst) ((OFActionSetField) a).getField()).getValue().toString()); 
+                } else if (((OFActionSetField)a).getField() instanceof OFOxmIpEcn) {
+                    jsonGenerator.writeNumberField(MatchUtils.STR_NW_ECN, ((OFOxmIpEcn) ((OFActionSetField) a).getField()).getValue().getEcnValue()); 
+                } else if (((OFActionSetField)a).getField() instanceof OFOxmIpDscp) {
+                    jsonGenerator.writeNumberField(MatchUtils.STR_NW_DSCP, ((OFOxmIpDscp) ((OFActionSetField) a).getField()).getValue().getDscpValue()); 
+                } 
+                /* TRANSPORT LAYER, TCP, UDP, and SCTP */
+                else if (((OFActionSetField)a).getField() instanceof OFOxmTcpSrc) {
+                    jsonGenerator.writeNumberField(MatchUtils.STR_TCP_SRC, ((OFOxmTcpSrc) ((OFActionSetField) a).getField()).getValue().getPort()); 
+                } else if (((OFActionSetField)a).getField() instanceof OFOxmTcpDst) {
+                    jsonGenerator.writeNumberField(MatchUtils.STR_TCP_DST, ((OFOxmTcpDst) ((OFActionSetField) a).getField()).getValue().getPort()); 
+                } else if (((OFActionSetField)a).getField() instanceof OFOxmUdpSrc) {
+                    jsonGenerator.writeNumberField(MatchUtils.STR_UDP_SRC, ((OFOxmUdpSrc) ((OFActionSetField) a).getField()).getValue().getPort()); 
+                } else if (((OFActionSetField)a).getField() instanceof OFOxmUdpDst) {
+                    jsonGenerator.writeNumberField(MatchUtils.STR_UDP_DST, ((OFOxmUdpDst) ((OFActionSetField) a).getField()).getValue().getPort()); 
+                } else if (((OFActionSetField)a).getField() instanceof OFOxmSctpSrc) {
+                    jsonGenerator.writeNumberField(MatchUtils.STR_SCTP_SRC, ((OFOxmSctpSrc) ((OFActionSetField) a).getField()).getValue().getPort()); 
+                } else if (((OFActionSetField)a).getField() instanceof OFOxmSctpDst) {
+                    jsonGenerator.writeNumberField(MatchUtils.STR_SCTP_DST, ((OFOxmSctpDst) ((OFActionSetField) a).getField()).getValue().getPort()); 
+                }
+                /* MPLS */
+                else if (((OFActionSetField)a).getField() instanceof OFOxmMplsLabel) {
+                    jsonGenerator.writeNumberField(MatchUtils.STR_MPLS_LABEL, ((OFOxmMplsLabel) ((OFActionSetField) a).getField()).getValue().getValue()); 
+                } else if (((OFActionSetField)a).getField() instanceof OFOxmMplsTc) {
+                    jsonGenerator.writeNumberField(MatchUtils.STR_MPLS_TC, ((OFOxmMplsTc) ((OFActionSetField) a).getField()).getValue().getValue()); 
+                } // MPLS_BOS not implemented in loxi
+                /* METADATA */
+                else if (((OFActionSetField)a).getField() instanceof OFOxmMetadata) {
+                    jsonGenerator.writeNumberField(MatchUtils.STR_METADATA, ((OFOxmMetadata) ((OFActionSetField) a).getField()).getValue().getValue().getValue()); 
+                } else {
+                    logger.error("Could not decode Set-Field action field: {}", ((OFActionSetField) a));
+                    // need to get a logger in here somehow log.error("Could not decode Set-Field action field: {}", ((OFActionSetField) a));
+                }
+            } // end switch over action type
+        } // end for over all actions
+    } // end method
 
-				// handle OF1.1+ instructions with actions within
-				if (entry.getVersion() == OFVersion.OF_10) {
-					serializeActions(jGen, entry.getActions());
-				} else {
-					List<OFInstruction> instructions = entry.getInstructions();
-					jGen.writeObjectFieldStart("instructions");
-					if (instructions.isEmpty()) {
-						jGen.writeStringField("none", "drop");
-					} else {
-						for (OFInstruction i : instructions) {
-							switch (i.getType()) {
-							case CLEAR_ACTIONS:
-								jGen.writeObjectFieldStart(InstructionUtils.STR_CLEAR_ACTIONS);
-								break;
-							case WRITE_METADATA:
-								jGen.writeStartObject();
-								jGen.writeNumberField(InstructionUtils.STR_WRITE_METADATA, ((OFInstructionWriteMetadata)i).getMetadata().getValue());
-								jGen.writeNumberField(InstructionUtils.STR_WRITE_METADATA + "_mask", ((OFInstructionWriteMetadata)i).getMetadataMask().getValue());
-								break;
-							case EXPERIMENTER:
-								jGen.writeStartObject();
-								jGen.writeNumberField(InstructionUtils.STR_EXPERIMENTER, ((OFInstructionExperimenter)i).getExperimenter());
-								break;
-							case GOTO_TABLE:
-								jGen.writeStartObject();
-								jGen.writeNumberField(InstructionUtils.STR_GOTO_TABLE, ((OFInstructionGotoTable)i).getTableId().getValue());
-								break;
-							case METER:
-								jGen.writeStartObject();
-								jGen.writeNumberField(InstructionUtils.STR_GOTO_METER, ((OFInstructionMeter)i).getMeterId());
-								break;
-							case APPLY_ACTIONS:
-								jGen.writeObjectFieldStart(InstructionUtils.STR_APPLY_ACTIONS);
-								serializeActions(jGen, ((OFInstructionApplyActions)i).getActions());
-								break;
-							case WRITE_ACTIONS:
-								jGen.writeObjectFieldStart(InstructionUtils.STR_WRITE_ACTIONS);
-								serializeActions(jGen, ((OFInstructionWriteActions)i).getActions());
-							default:
-								// shouldn't ever get here
-								break;
-							} // end switch on instruction
-							jGen.writeEndObject(); // end specific instruction
-						} // end for instructions
-						jGen.writeEndObject();
-					} // end process instructions (OF1.1+ only)
-				} // end not-empty instructions (else)
-				jGen.writeEndObject();
-			} // end for each OFFlowStatsReply entry
-		} // end for each OFStatsReply
-	} // end method
+    public void serializeDescReply(List<OFDescStatsReply> descReplies, JsonGenerator jGen) throws IOException, JsonProcessingException{
+        OFDescStatsReply descReply = descReplies.get(0); // There are only one descReply from the switch
+        jGen.writeObjectFieldStart("desc"); 
+        jGen.writeStringField("version", descReply.getVersion().toString()); //return the enum name
+        jGen.writeStringField("manufacturerDescription", descReply.getMfrDesc()); 
+        jGen.writeStringField("hardwareDescription", descReply.getHwDesc()); 
+        jGen.writeStringField("softwareDescription", descReply.getSwDesc()); 
+        jGen.writeStringField("serialNumber", descReply.getSerialNum()); 
+        jGen.writeStringField("datapathDescription", descReply.getDpDesc()); 
+        jGen.writeEndObject(); // end match
+    }
+    public void serializeAggregateReply(List<OFAggregateStatsReply> aggregateReplies, JsonGenerator jGen) throws IOException, JsonProcessingException{
+        OFAggregateStatsReply aggregateReply = aggregateReplies.get(0); // There are only one aggregateReply from the switch
+        jGen.writeObjectFieldStart("aggregate"); 
+        jGen.writeStringField("version", aggregateReply.getVersion().toString()); //return the enum name
+        jGen.writeNumberField("flowCount", aggregateReply.getFlowCount());
+        jGen.writeNumberField("packetCount", aggregateReply.getPacketCount().getValue());
+        jGen.writeNumberField("byteCount", aggregateReply.getByteCount().getValue());
+        jGen.writeEndObject(); // end match
+    }
 
-	/**
-	 * Write a JSON string given a list of OFAction. Supports OF1.0 - OF1.3.
-	 * This is the only place actions are serialized, for any OF version. Because
-	 * some OF version share actions, it makes sense to have them in one place.
-	 * @param jsonGenerator
-	 * @param actions
-	 * @throws IOException
-	 * @throws JsonProcessingException
-	 */
-	public void serializeActions(JsonGenerator jsonGenerator, List<OFAction> actions) throws IOException, JsonProcessingException {
-		//jsonGenerator.writeStartObject();
-		if (actions.isEmpty()) {
-			jsonGenerator.writeStringField("none", "drop");
-		}
-		for (OFAction a : actions) {
-			switch (a.getType()) {
-			case OUTPUT: //TODO @Ryan need to reference the predefined string constants for each of the actions/oxms
-				jsonGenerator.writeNumberField(ActionUtils.STR_OUTPUT, ((OFActionOutput)a).getPort().getPortNumber());
-				break;
-			/* begin OF1.0 ONLY actions */
-			case SET_VLAN_VID:
-				jsonGenerator.writeNumberField(ActionUtils.STR_VLAN_SET_VID, ((OFActionSetVlanVid)a).getVlanVid().getVlan());
-				break;
-			case SET_VLAN_PCP:
-				jsonGenerator.writeNumberField(ActionUtils.STR_VLAN_SET_PCP, ((OFActionSetVlanPcp)a).getVlanPcp().getValue());
-				break;
-			case SET_QUEUE:
-				jsonGenerator.writeNumberField(ActionUtils.STR_QUEUE_SET, ((OFActionSetQueue)a).getQueueId());
-				break;
-			case SET_DL_SRC:
-				jsonGenerator.writeStringField(ActionUtils.STR_DL_SRC_SET, ((OFActionSetDlSrc)a).getDlAddr().toString());
-				break;
-			case SET_DL_DST:
-				jsonGenerator.writeStringField(ActionUtils.STR_DL_DST_SET, ((OFActionSetDlDst)a).getDlAddr().toString());
-				break;
-			case SET_NW_SRC:
-				jsonGenerator.writeStringField(ActionUtils.STR_NW_SRC_SET, ((OFActionSetNwSrc)a).getNwAddr().toString());
-				break;
-			case SET_NW_DST:
-				jsonGenerator.writeStringField(ActionUtils.STR_NW_DST_SET, ((OFActionSetNwDst)a).getNwAddr().toString());
-				break;
-			case SET_NW_TOS:
-				jsonGenerator.writeNumberField(ActionUtils.STR_NW_TOS_SET, ((OFActionSetNwTos)a).getNwTos());
-				break;	
-			case SET_TP_SRC:
-				jsonGenerator.writeNumberField(ActionUtils.STR_TP_SRC_SET, ((OFActionSetTpSrc)a).getTpPort().getPort());
-				break;
-			case SET_TP_DST:
-				jsonGenerator.writeNumberField(ActionUtils.STR_TP_DST_SET, ((OFActionSetTpDst)a).getTpPort().getPort());
-				break;
-			/* end OF1.0 ONLY actions; begin OF1.1+ actions */
-			case ENQUEUE:
-				jsonGenerator.writeNumberField(ActionUtils.STR_ENQUEUE, ((OFActionEnqueue)a).getPort().getPortNumber());
-				break;
-			case GROUP:
-				jsonGenerator.writeNumberField(ActionUtils.STR_GROUP, ((OFActionGroup)a).getGroup().getGroupNumber());
-				break;
-			case STRIP_VLAN:
-				jsonGenerator.writeString(ActionUtils.STR_VLAN_STRIP);
-				break;
-			case PUSH_VLAN:
-				jsonGenerator.writeNumberField(ActionUtils.STR_VLAN_PUSH, ((OFActionPushVlan)a).getEthertype().getValue());
-				break;
-			case PUSH_MPLS:
-				jsonGenerator.writeNumberField(ActionUtils.STR_MPLS_PUSH, ((OFActionPushMpls)a).getEthertype().getValue());
-				break;
-			case PUSH_PBB:
-				jsonGenerator.writeNumberField(ActionUtils.STR_PBB_PUSH, ((OFActionPushPbb)a).getEthertype().getValue());
-				break;
-			case POP_VLAN:
-				jsonGenerator.writeString(ActionUtils.STR_VLAN_POP);
-				break;
-			case POP_MPLS:
-				jsonGenerator.writeNumberField(ActionUtils.STR_MPLS_POP, ((OFActionPopMpls)a).getEthertype().getValue());
-				break;
-			case POP_PBB:
-				jsonGenerator.writeString(ActionUtils.STR_PBB_POP);
-				break;
-			case COPY_TTL_IN:
-				jsonGenerator.writeString(ActionUtils.STR_TTL_IN_COPY);
-				break;
-			case COPY_TTL_OUT:
-				jsonGenerator.writeString(ActionUtils.STR_TTL_OUT_COPY);
-				break;
-			case DEC_NW_TTL:
-				jsonGenerator.writeString(ActionUtils.STR_NW_TTL_DEC);
-				break;
-			case DEC_MPLS_TTL:
-				jsonGenerator.writeString(ActionUtils.STR_MPLS_TTL_DEC);
-				break;
-			case SET_MPLS_LABEL:
-				jsonGenerator.writeNumberField(ActionUtils.STR_MPLS_LABEL_SET, ((OFActionSetMplsLabel)a).getMplsLabel());
-				break;
-			case SET_MPLS_TC:
-				jsonGenerator.writeNumberField(ActionUtils.STR_MPLS_TC_SET, ((OFActionSetMplsTc)a).getMplsTc());
-				break;
-			case SET_MPLS_TTL:
-				jsonGenerator.writeNumberField(ActionUtils.STR_MPLS_TTL_SET, ((OFActionSetMplsTtl)a).getMplsTtl());
-				break;
-			case SET_NW_ECN:
-				jsonGenerator.writeNumberField(ActionUtils.STR_NW_ECN_SET, ((OFActionSetNwEcn)a).getNwEcn().getEcnValue());
-				break;
-			case SET_NW_TTL:
-				jsonGenerator.writeNumberField(ActionUtils.STR_NW_TTL_SET, ((OFActionSetNwTtl)a).getNwTtl());
-				break;
-			case EXPERIMENTER:
-				jsonGenerator.writeNumberField(ActionUtils.STR_EXPERIMENTER, ((OFActionExperimenter)a).getExperimenter());
-				break;
-			case SET_FIELD:
-				if (((OFActionSetField)a).getField() instanceof OFOxmArpOp) {
-					jsonGenerator.writeNumberField(MatchUtils.STR_ARP_OPCODE, ((OFOxmArpOp) ((OFActionSetField) a).getField()).getValue().getOpcode());
-				} else if (((OFActionSetField)a).getField() instanceof OFOxmArpSha) {
-					jsonGenerator.writeStringField(MatchUtils.STR_ARP_SHA, ((OFOxmArpSha) ((OFActionSetField) a).getField()).getValue().toString()); // macaddress formats string already
-				} else if (((OFActionSetField)a).getField() instanceof OFOxmArpTha) {
-					jsonGenerator.writeStringField(MatchUtils.STR_ARP_DHA, ((OFOxmArpTha) ((OFActionSetField) a).getField()).getValue().toString());
-				} else if (((OFActionSetField)a).getField() instanceof OFOxmArpSpa) {
-					jsonGenerator.writeStringField(MatchUtils.STR_ARP_SPA, ((OFOxmArpSpa) ((OFActionSetField) a).getField()).getValue().toString()); // ipaddress formats string already
-				} else if (((OFActionSetField)a).getField() instanceof OFOxmArpTpa) {
-					jsonGenerator.writeStringField(MatchUtils.STR_ARP_DPA, ((OFOxmArpTpa) ((OFActionSetField) a).getField()).getValue().toString()); 
-				} 
-				/* DATA LAYER */
-				else if (((OFActionSetField)a).getField() instanceof OFOxmEthType) {
-					jsonGenerator.writeNumberField(MatchUtils.STR_DL_TYPE, ((OFOxmEthType) ((OFActionSetField) a).getField()).getValue().getValue());
-				} else if (((OFActionSetField)a).getField() instanceof OFOxmEthSrc) {
-					jsonGenerator.writeStringField(MatchUtils.STR_DL_SRC, ((OFOxmEthSrc) ((OFActionSetField) a).getField()).getValue().toString());
-				} else if (((OFActionSetField)a).getField() instanceof OFOxmEthDst) {
-					jsonGenerator.writeStringField(MatchUtils.STR_DL_DST, ((OFOxmEthDst) ((OFActionSetField) a).getField()).getValue().toString()); 
-				} else if (((OFActionSetField)a).getField() instanceof OFOxmVlanVid) {
-					jsonGenerator.writeNumberField(MatchUtils.STR_DL_VLAN, ((OFOxmVlanVid) ((OFActionSetField) a).getField()).getValue().getVlan()); 
-				} else if (((OFActionSetField)a).getField() instanceof OFOxmVlanPcp) {
-				} 
-				/* ICMP */
-				else if (((OFActionSetField)a).getField() instanceof OFOxmIcmpv4Code) {
-					jsonGenerator.writeNumberField(MatchUtils.STR_ICMP_CODE, ((OFOxmIcmpv4Code) ((OFActionSetField) a).getField()).getValue().getCode()); 
-				} else if (((OFActionSetField)a).getField() instanceof OFOxmIcmpv4Type) {
-					jsonGenerator.writeNumberField(MatchUtils.STR_ICMP_TYPE, ((OFOxmIcmpv4Type) ((OFActionSetField) a).getField()).getValue().getType()); 
-				} 
-				/* NETWORK LAYER */
-				else if (((OFActionSetField)a).getField() instanceof OFOxmIpProto) {
-					jsonGenerator.writeNumberField(MatchUtils.STR_NW_PROTO, ((OFOxmIpProto) ((OFActionSetField) a).getField()).getValue().getIpProtocolNumber()); 
-				} else if (((OFActionSetField)a).getField() instanceof OFOxmIpv4Src) {
-					jsonGenerator.writeStringField(MatchUtils.STR_NW_SRC, ((OFOxmIpv4Src) ((OFActionSetField) a).getField()).getValue().toString()); 
-				} else if (((OFActionSetField)a).getField() instanceof OFOxmIpv4Dst) {
-					jsonGenerator.writeStringField(MatchUtils.STR_NW_DST, ((OFOxmIpv4Dst) ((OFActionSetField) a).getField()).getValue().toString()); 
-				} else if (((OFActionSetField)a).getField() instanceof OFOxmIpEcn) {
-					jsonGenerator.writeNumberField(MatchUtils.STR_NW_ECN, ((OFOxmIpEcn) ((OFActionSetField) a).getField()).getValue().getEcnValue()); 
-				} else if (((OFActionSetField)a).getField() instanceof OFOxmIpDscp) {
-					jsonGenerator.writeNumberField(MatchUtils.STR_NW_DSCP, ((OFOxmIpDscp) ((OFActionSetField) a).getField()).getValue().getDscpValue()); 
-				} 
-				/* TRANSPORT LAYER, TCP, UDP, and SCTP */
-				else if (((OFActionSetField)a).getField() instanceof OFOxmTcpSrc) {
-					jsonGenerator.writeNumberField(MatchUtils.STR_TCP_SRC, ((OFOxmTcpSrc) ((OFActionSetField) a).getField()).getValue().getPort()); 
-				} else if (((OFActionSetField)a).getField() instanceof OFOxmTcpDst) {
-					jsonGenerator.writeNumberField(MatchUtils.STR_TCP_DST, ((OFOxmTcpDst) ((OFActionSetField) a).getField()).getValue().getPort()); 
-				} else if (((OFActionSetField)a).getField() instanceof OFOxmUdpSrc) {
-					jsonGenerator.writeNumberField(MatchUtils.STR_UDP_SRC, ((OFOxmUdpSrc) ((OFActionSetField) a).getField()).getValue().getPort()); 
-				} else if (((OFActionSetField)a).getField() instanceof OFOxmUdpDst) {
-					jsonGenerator.writeNumberField(MatchUtils.STR_UDP_DST, ((OFOxmUdpDst) ((OFActionSetField) a).getField()).getValue().getPort()); 
-				} else if (((OFActionSetField)a).getField() instanceof OFOxmSctpSrc) {
-					jsonGenerator.writeNumberField(MatchUtils.STR_SCTP_SRC, ((OFOxmSctpSrc) ((OFActionSetField) a).getField()).getValue().getPort()); 
-				} else if (((OFActionSetField)a).getField() instanceof OFOxmSctpDst) {
-					jsonGenerator.writeNumberField(MatchUtils.STR_SCTP_DST, ((OFOxmSctpDst) ((OFActionSetField) a).getField()).getValue().getPort()); 
-				}
-				/* MPLS */
-				else if (((OFActionSetField)a).getField() instanceof OFOxmMplsLabel) {
-					jsonGenerator.writeNumberField(MatchUtils.STR_MPLS_LABEL, ((OFOxmMplsLabel) ((OFActionSetField) a).getField()).getValue().getValue()); 
-				} else if (((OFActionSetField)a).getField() instanceof OFOxmMplsTc) {
-					jsonGenerator.writeNumberField(MatchUtils.STR_MPLS_TC, ((OFOxmMplsTc) ((OFActionSetField) a).getField()).getValue().getValue()); 
-				} // MPLS_BOS not implemented in loxi
-				/* METADATA */
-				else if (((OFActionSetField)a).getField() instanceof OFOxmMetadata) {
-					jsonGenerator.writeNumberField(MatchUtils.STR_METADATA, ((OFOxmMetadata) ((OFActionSetField) a).getField()).getValue().getValue().getValue()); 
-				} else {
-					// need to get a logger in here somehow log.error("Could not decode Set-Field action field: {}", ((OFActionSetField) a));
-				}
-			} // end switch over action type
-		} // end for over all actions
-	} // end method
+    public void serializePortDescReply(List<OFPortDescStatsReply> portDescReplies, JsonGenerator jGen) throws IOException, JsonProcessingException{
+        OFPortDescStatsReply portDescReply = portDescReplies.get(0); // we will get only one PortDescReply and it will contains many OFPortDescStatsEntry ?
+        jGen.writeStringField("version", portDescReply.getVersion().toString()); //return the enum name
+        jGen.writeFieldName("portDesc");
+        jGen.writeStartArray();
+        for(OFPortDesc entry : portDescReply.getEntries()) {
+            jGen.writeStartObject();
+            jGen.writeStringField("portNumber",entry.getPortNo().toString());
+            jGen.writeStringField("hardwareAddress", entry.getHwAddr().toString());
+            jGen.writeStringField("name", entry.getName());
+            switch(entry.getVersion()) {
+                case OF_10:
+                    jGen.writeNumberField("config", OFPortConfigSerializerVer10.toWireValue(entry.getConfig()));
+                    jGen.writeNumberField("state", OFPortStateSerializerVer10.toWireValue(entry.getState()));
+                    jGen.writeNumberField("currentFeatures", OFPortFeaturesSerializerVer10.toWireValue(entry.getCurr()));
+                    jGen.writeNumberField("advertisedFeatures", OFPortFeaturesSerializerVer10.toWireValue(entry.getAdvertised()));
+                    jGen.writeNumberField("supportedFeatures", OFPortFeaturesSerializerVer10.toWireValue(entry.getSupported()));
+                    jGen.writeNumberField("peerFeatures", OFPortFeaturesSerializerVer10.toWireValue(entry.getPeer()));
+                    break;
+                case OF_11:
+                    jGen.writeNumberField("config", OFPortConfigSerializerVer11.toWireValue(entry.getConfig()));
+                    jGen.writeNumberField("state", OFPortStateSerializerVer11.toWireValue(entry.getState()));
+                    jGen.writeNumberField("currentFeatures", OFPortFeaturesSerializerVer11.toWireValue(entry.getCurr()));
+                    jGen.writeNumberField("advertisedFeatures", OFPortFeaturesSerializerVer11.toWireValue(entry.getAdvertised()));
+                    jGen.writeNumberField("supportedFeatures", OFPortFeaturesSerializerVer11.toWireValue(entry.getSupported()));
+                    jGen.writeNumberField("peerFeatures", OFPortFeaturesSerializerVer11.toWireValue(entry.getPeer()));
+                    break;
+                case OF_12:
+                    jGen.writeNumberField("config", OFPortConfigSerializerVer12.toWireValue(entry.getConfig()));
+                    jGen.writeNumberField("state", OFPortStateSerializerVer12.toWireValue(entry.getState()));
+                    jGen.writeNumberField("currentFeatures", OFPortFeaturesSerializerVer12.toWireValue(entry.getCurr()));
+                    jGen.writeNumberField("advertisedFeatures", OFPortFeaturesSerializerVer12.toWireValue(entry.getAdvertised()));
+                    jGen.writeNumberField("supportedFeatures", OFPortFeaturesSerializerVer12.toWireValue(entry.getSupported()));
+                    jGen.writeNumberField("peerFeatures", OFPortFeaturesSerializerVer12.toWireValue(entry.getPeer()));
+                    break;
+                case OF_13:
+                    jGen.writeNumberField("config", OFPortConfigSerializerVer13.toWireValue(entry.getConfig()));
+                    jGen.writeNumberField("state", OFPortStateSerializerVer13.toWireValue(entry.getState()));
+                    jGen.writeNumberField("currentFeatures", OFPortFeaturesSerializerVer13.toWireValue(entry.getCurr()));
+                    jGen.writeNumberField("advertisedFeatures", OFPortFeaturesSerializerVer13.toWireValue(entry.getAdvertised()));
+                    jGen.writeNumberField("supportedFeatures", OFPortFeaturesSerializerVer13.toWireValue(entry.getSupported()));
+                    jGen.writeNumberField("peerFeatures", OFPortFeaturesSerializerVer13.toWireValue(entry.getPeer()));
+                    break;
+            }
+            if (OFVersion.OF_10 != entry.getVersion()) {
+                jGen.writeNumberField("currSpeed",entry.getCurrSpeed());
+                jGen.writeNumberField("maxSpeed",entry.getMaxSpeed());
+            }
+            jGen.writeEndObject();
+        }
+        jGen.writeEndArray();
+    }
 } 
diff --git a/src/main/resources/web/js/models/switchmodel.js b/src/main/resources/web/js/models/switchmodel.js
index 4104dd0dfd898d9e462da0cc04f3fb6808342981..785e1f6464beac7e54ad13cba154ec656eb664d6 100644
--- a/src/main/resources/web/js/models/switchmodel.js
+++ b/src/main/resources/web/js/models/switchmodel.js
@@ -38,8 +38,8 @@ window.Switch = Backbone.Model.extend({
             dataType:"json",
             success:function (data) {
                 //console.log("fetched  switch " + self.id + " desc");
-                //console.log(data[self.id][0]);
-                self.set(data[self.id][0]);
+                //console.log(data['desc']);
+                self.set(data['desc']);
             }
         });
 
@@ -49,8 +49,8 @@ window.Switch = Backbone.Model.extend({
             dataType:"json",
             success:function (data) {
                 //console.log("fetched  switch " + self.id + " aggregate");
-                //console.log(data[self.id][0]);
-                self.set(data[self.id][0]);
+                //console.log(data['aggregate']);
+                self.set(data['aggregate']);
             }
         });
         self.trigger('add');
@@ -73,19 +73,18 @@ window.Switch = Backbone.Model.extend({
             dataType:"json",
             success:function (data) {
                 //console.log("fetched  switch " + self.id + " ports");
-                //console.log(data[self.id]);
                 var old_ids = self.ports.pluck('id');
                 //console.log("old_ids" + old_ids);
 
                 // create port models
-                _.each(data[self.id], function(p) {
+                _.each(data['port'], function(p) {
                     // workaround for REST serialization signed/unsigned bug
                     if(p.portNumber < 0) {p.portNumber = 65536 + p.portNumber};
                     
                     p.id = self.id+'-'+p.portNumber;
                     old_ids = _.without(old_ids, p.id);
                     p.dropped = p.receiveDropped + p.transmitDropped;
-                    p.errors = p.receiveCRCErrors + p.receiveErrors + p.receiveOverrunErrors +
+                    p.errors = p.receiveCRCErrors + p.receiveFrameErrors + p.receiveOverrunErrors +
                         p.receiveFrameErrors + p.transmitErrors;
                     // this is a knda kludgy way to merge models
                     var m = self.ports.get(p.id);
@@ -106,13 +105,13 @@ window.Switch = Backbone.Model.extend({
             }
         }),
         $.ajax({
-            url:hackBase + "/wm/core/switch/" + self.id + '/features/json',
+            url:hackBase + "/wm/core/switch/" + self.id + '/port-desc/json',
             dataType:"json",
             success:function (data) {
                 //console.log("fetched  switch " + self.id + " features");
-                //console.log(data[self.id]);
+                //console.log(data['portDesc']);
                 // update port models
-                _.each(data[self.id].ports, function(p) {
+                _.each(data['portDesc'], function(p) {
                     p.id = self.id+'-'+p.portNumber;
                     if(p.name != p.portNumber) {
                         p.name = p.portNumber + ' (' + p.name + ')';
@@ -167,7 +166,7 @@ window.Switch = Backbone.Model.extend({
             dataType:"json",
             success:function (data) {
                 //console.log("fetched  switch " + self.id + " flows");
-                var flows = data[self.id];
+                var flows = data['flows'];
                 //console.log(flows);
 
                 // create flow models
@@ -177,81 +176,31 @@ window.Switch = Backbone.Model.extend({
 
                     // build human-readable match
                     f.matchHTML = '';
-                    if(!(f.match.wildcards & (1<<0))) { // input port
-                        f.matchHTML += "port=" + f.match.inputPort + ", ";
+                    if(f.hasOwnProperty('match')) {
+                        _.each(f.match, function(value , key) {
+                            f.matchHTML += key + "=" + value +" ";
+                        },f);
                     }
-                    if(!(f.match.wildcards & (1<<1))) { // VLAN ID
-                        f.matchHTML += "VLAN=" + f.match.dataLayerVirtualLan + ", ";
-                    }
-                    if(!(f.match.wildcards & (1<<20))) { // VLAN prio
-                        f.matchHTML += "prio=" + f.match.dataLayerVirtualLanPriorityCodePoint  + ", ";
-                    }
-                    if(!(f.match.wildcards & (1<<2))) { // src MAC
-                        f.matchHTML += "src=<a href='/host/" + f.match.dataLayerSource + "'>" +
-                        f.match.dataLayerSource + "</a>, ";
-                    }
-                    if(!(f.match.wildcards & (1<<3))) { // dest MAC
-                        f.matchHTML += "dest=<a href='/host/" + f.match.dataLayerDestination + "'>" +
-                        f.match.dataLayerDestination + "</a>, ";
-                    }
-                    if(!(f.match.wildcards & (1<<4))) { // Ethertype
-                        // TODO print a human-readable name instead of hex
-                        f.matchHTML += "ethertype=" + f.match.dataLayerType + ", ";
-                    }
-                    if(!(f.match.wildcards & (1<<5))) { // IP protocol
-                        // TODO print a human-readable name
-                        f.matchHTML += "proto=" + f.match.networkProtocol + ", ";
-                    }
-                    if(!(f.match.wildcards & (1<<6))) { // TCP/UDP source port
-                        f.matchHTML += "IP src port=" + f.match.transportSource + ", ";
-                    }
-                    if(!(f.match.wildcards & (1<<7))) { // TCP/UDP dest port
-                        f.matchHTML += "IP dest port=" + f.match.transportDestination  + ", ";
-                    }
-                    if(!(f.match.wildcards & (32<<8))) { // src IP
-                        f.matchHTML += "src=" + f.match.networkSource  + ", ";
-                    }
-                    if(!(f.match.wildcards & (32<<14))) { // dest IP
-                        f.matchHTML += "dest=" + f.match.networkDestination  + ", ";
-                    }
-                    if(!(f.match.wildcards & (1<<21))) { // IP TOS
-                        f.matchHTML += "TOS=" + f.match.networkTypeOfService  + ", ";
-                    }
-                    // remove trailing ", "
                     f.matchHTML = f.matchHTML.substr(0, f.matchHTML.length - 2);
-
-                    // build human-readable action list
-                    f.actionText = _.reduce(f.actions, function (memo, a) {
-                        switch (a.type) {
-                            case "OUTPUT":
-                                return memo + "output " + a.port + ', ';
-                            case "OPAQUE_ENQUEUE":
-                                return memo + "enqueue " + a.port + ':' + a.queueId +  ', ';
-                            case "STRIP_VLAN":
-                                return memo + "strip VLAN, ";
-                            case "SET_VLAN_ID":
-                                return memo + "VLAN=" + a.virtualLanIdentifier + ', ';
-                            case "SET_VLAN_PCP":
-                                return memo + "prio=" + a.virtualLanPriorityCodePoint + ', ';
-                            case "SET_DL_SRC":
-                                return memo + "src=" + a.dataLayerAddress + ', ';
-                            case "SET_DL_DST":
-                                return memo + "dest=" + a.dataLayerAddress + ', ';
-                            case "SET_NW_TOS":
-                                return memo + "TOS=" + a.networkTypeOfService + ', ';
-                            case "SET_NW_SRC":
-                                return memo + "src=" + a.networkAddress + ', ';
-                            case "SET_NW_DST":
-                                return memo + "dest=" + a.networkAddress + ', ';
-                            case "SET_TP_SRC":
-                                return memo + "src port=" + a.transportPort + ', ';
-                            case "SET_TP_DST":
-                                return memo + "dest port=" + a.transportPort + ', ';
+                    
+                    f.applyActionText = '';
+                    f.writeActionText = '';
+                    if(f.hasOwnProperty('instructions')) {
+                        if(f.instructions.hasOwnProperty('apply_actions')) {
+                            _.each(f.instructions.apply_actions, function(value, key) {
+                                f.applyActionText  += key + ":" + value +" ";
+                            },f);
+                        }
+                        if(f.instructions.hasOwnProperty('write_actions')) {
+                            _.each(f.instructions.write_actions, function(value, key) {
+                                f.writeActionText  += key + ":" + value +" ";
+                            },f);
                         }
-                    }, "");
-                    // remove trailing ", "
-                    f.actionText = f.actionText.substr(0, f.actionText.length - 2);
 
+                    }
+                    // build human-readable action list
+                    f.applyActionText = f.applyActionText.substr(0, f.applyActionText.length - 2);
+                    f.writeActionText = f.writeActionText.substr(0, f.writeActionText.length - 2);
                     //console.log(f);
                     self.flows.add(f, {silent: true});
                 });
@@ -278,8 +227,8 @@ window.SwitchCollection = Backbone.Collection.extend({
                 //console.log("old_ids" + old_ids);
                 
                 _.each(data, function(sw) {
-                    old_ids = _.without(old_ids, sw['dpid']);
-                    self.add({id: sw['dpid'], inetAddress: sw.inetAddress,
+                    old_ids = _.without(old_ids, sw['switchDPID']);
+                    self.add({id: sw['switchDPID'], inetAddress: sw.inetAddress,
                               connectedSince: new Date(sw.connectedSince).toLocaleString()})});
                 
                 // old_ids now holds switches that no longer exist; remove them
diff --git a/src/main/resources/web/tpl/flow-list-item.html b/src/main/resources/web/tpl/flow-list-item.html
index 7c099c3e7e0e43c9612412dc7b4220fcbe7b1001..4fb9a3ec87f5058627483d6114807ea7ab5978db 100644
--- a/src/main/resources/web/tpl/flow-list-item.html
+++ b/src/main/resources/web/tpl/flow-list-item.html
@@ -1 +1 @@
-        <td><%= cookie %></td><td><%= priority %></td><td><%= matchHTML %></td><td><%= actionText %></td><td><%= packetCount %></td><td><%= byteCount %></td><td><%= durationSeconds %> s</td><td><%= idleTimeout %> s</td>
+        <td><%= cookie %></td><td><%= priority %></td><td><%= matchHTML %></td><td><%= applyActionText %></td><td><%= writeActionText %></td><td><%= packetCount %></td><td><%= byteCount %></td><td><%= durationSeconds %> s</td><td><%= idleTimeoutSec %> s</td>
diff --git a/src/main/resources/web/tpl/flow-list.html b/src/main/resources/web/tpl/flow-list.html
index 21a30cf8d1b67633cb5869e68e88c51f96db82ec..3c23a292e47c7565566a0dc70ca783e5af91c046 100644
--- a/src/main/resources/web/tpl/flow-list.html
+++ b/src/main/resources/web/tpl/flow-list.html
@@ -2,7 +2,7 @@
     <h1>Flows (<%= nflows %>)</h1>
 </div>
 <table class="table table-striped flow-table">
-    <thead><tr><th>Cookie</th><th>Priority</th><th>Match</th><th>Action</th><th>Packets</th><th>Bytes</th><th>Age</th><th>Timeout</th></tr></thead>
+    <thead><tr><th>Cookie</th><th>Priority</th><th>Match</th><th>Apply Actions</th><th>Write Actions</th><th>Packets</th><th>Bytes</th><th>Age</th><th>Timeout</th></tr></thead>
     <tbody>
         <!-- flows will be inserted here by FlowListView:render -->
     </tbody>
@@ -16,4 +16,4 @@
     <li><a href="">&rarr;</a>
 </ul></div>
  -->
- 
\ No newline at end of file
+