diff --git a/src/main/java/net/floodlightcontroller/core/FloodlightProvider.java b/src/main/java/net/floodlightcontroller/core/FloodlightProvider.java
index 0ee2904..5dbdb3e 100644
--- a/src/main/java/net/floodlightcontroller/core/FloodlightProvider.java
+++ b/src/main/java/net/floodlightcontroller/core/FloodlightProvider.java
@@ -30,6 +30,7 @@
 import net.floodlightcontroller.debugevent.IDebugEventService;
 import net.floodlightcontroller.restserver.IRestApiService;
 import net.floodlightcontroller.threadpool.IThreadPoolService;
+import net.onrc.onos.core.configmanager.INetworkConfigService;
 import net.onrc.onos.core.linkdiscovery.ILinkDiscoveryService;
 import net.onrc.onos.core.registry.IControllerRegistryService;
 
@@ -83,6 +84,8 @@
                context.getServiceImpl(IControllerRegistryService.class));
        controller.setLinkDiscoveryService(
                context.getServiceImpl(ILinkDiscoveryService.class));
+        controller.setNetworkConfigService(
+                context.getServiceImpl(INetworkConfigService.class));
 
        controller.init(context.getConfigParams(this));
     }
diff --git a/src/main/java/net/floodlightcontroller/core/IFloodlightProviderService.java b/src/main/java/net/floodlightcontroller/core/IFloodlightProviderService.java
index 5f73d9a..4447b75 100644
--- a/src/main/java/net/floodlightcontroller/core/IFloodlightProviderService.java
+++ b/src/main/java/net/floodlightcontroller/core/IFloodlightProviderService.java
@@ -23,6 +23,7 @@
 
 import net.floodlightcontroller.core.internal.Controller.Counters;
 import net.floodlightcontroller.core.module.IFloodlightService;
+import net.onrc.onos.core.configmanager.INetworkConfigService;
 import net.onrc.onos.core.packet.Ethernet;
 import net.onrc.onos.core.util.OnosInstanceId;
 
@@ -186,6 +187,28 @@
     public void removeOFSwitchListener(IOFSwitchListener listener);
 
 
+    Set<Long> getAllSwitchDpids();
+
+    IOFSwitch getSwitch(long dpid);
+
+    /**
+     * Record a switch event in in-memory debug-event
+     * 
+     * @param switchDPID
+     * @param reason Reason for this event
+     * @param flushNow see debug-event flushing in IDebugEventService
+     */
+    public void addSwitchEvent(long switchDPID, String reason, boolean flushNow);
+
+    Set<Long> getAllMasterSwitchDpids();
+
+    Set<Long> getAllEqualSwitchDpids();
+
+    IOFSwitch getMasterSwitch(long dpid);
+
+    IOFSwitch getEqualSwitch(long dpid);
+
+    void setAlwaysClearFlowsOnSwActivate(boolean value);
 
     //************************
     //  Utility methods
@@ -235,29 +258,12 @@
      */
     public Counters getCounters();
 
-    void setAlwaysClearFlowsOnSwActivate(boolean value);
+
 
     Map<String, Long> getMemory();
 
     Long getUptime();
 
-    Set<Long> getAllSwitchDpids();
 
-    IOFSwitch getSwitch(long dpid);
-
-    /**
-     * Record a switch event in in-memory debug-event
-     * @param switchDPID
-     * @param reason Reason for this event
-     * @param flushNow see debug-event flushing in IDebugEventService
-     */
-    public void addSwitchEvent(long switchDPID, String reason, boolean flushNow);
-
-    Set<Long> getAllMasterSwitchDpids();
-
-    Set<Long> getAllEqualSwitchDpids();
-
-    IOFSwitch getMasterSwitch(long dpid);
-
-    IOFSwitch getEqualSwitch(long dpid);
+    public INetworkConfigService getNetworkConfigService();
 }
diff --git a/src/main/java/net/floodlightcontroller/core/IOF13Switch.java b/src/main/java/net/floodlightcontroller/core/IOF13Switch.java
index 425c6a9..8ac2912 100644
--- a/src/main/java/net/floodlightcontroller/core/IOF13Switch.java
+++ b/src/main/java/net/floodlightcontroller/core/IOF13Switch.java
@@ -1,5 +1,6 @@
 package net.floodlightcontroller.core;
 
+import java.io.IOException;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Set;
@@ -22,17 +23,20 @@
      * by a switch implementing this interface. It is up to the implementation
      * to translate the 'matchActionOp' into a match-instruction with actions,
      * as expected by OF 1.3 switches.
-     *
+     * 
      * @param matchActionOp
+     * @throws IOException
      */
-    public void pushFlow(MatchActionOperationEntry matchActionOp);
+    public void pushFlow(MatchActionOperationEntry matchActionOp) throws IOException;
 
     /**
      * Pushes a collection of flows to the switch.
-     * 
+     *
      * @param matchActionOps
+     * @throws IOException
      */
-    public void pushFlows(Collection<MatchActionOperationEntry> matchActionOps);
+    public void pushFlows(Collection<MatchActionOperationEntry> matchActionOps)
+            throws IOException;
 
     // ****************************
     // Group related
diff --git a/src/main/java/net/floodlightcontroller/core/IOFSwitch.java b/src/main/java/net/floodlightcontroller/core/IOFSwitch.java
index 40aa530..72ec404 100644
--- a/src/main/java/net/floodlightcontroller/core/IOFSwitch.java
+++ b/src/main/java/net/floodlightcontroller/core/IOFSwitch.java
@@ -624,4 +624,9 @@
      */
     public void setTableFull(boolean isFull);
 
+    /**
+     * Get the switch driver hanshake state
+     */
+    public String getSwitchDriverState();
+
 }
diff --git a/src/main/java/net/floodlightcontroller/core/internal/Controller.java b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
index 3550297..72c536f 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/Controller.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
@@ -68,6 +68,7 @@
 import net.floodlightcontroller.restserver.IRestApiService;
 import net.floodlightcontroller.threadpool.IThreadPoolService;
 import net.floodlightcontroller.util.LoadMonitor;
+import net.onrc.onos.core.configmanager.INetworkConfigService;
 import net.onrc.onos.core.drivermanager.DriverManager;
 import net.onrc.onos.core.linkdiscovery.ILinkDiscoveryService;
 import net.onrc.onos.core.packet.Ethernet;
@@ -136,6 +137,7 @@
     protected IDebugEventService debugEvents;
 
     protected ILinkDiscoveryService linkDiscovery;
+    protected INetworkConfigService networkConfig;
 
     // Configuration options
     protected int openFlowPort = 6633;
@@ -483,6 +485,10 @@
         this.linkDiscovery = linkDiscovery;
     }
 
+    public void setNetworkConfigService(INetworkConfigService networkConfigService) {
+        this.networkConfig = networkConfigService;
+    }
+
     public void setDebugCounter(IDebugCounterService debugCounters) {
         this.debugCounters = debugCounters;
     }
@@ -993,6 +999,10 @@
         }
     }
 
+    public INetworkConfigService getNetworkConfigService() {
+        return networkConfig;
+    }
+
     // **************
     // Initialization
     // **************
diff --git a/src/main/java/net/floodlightcontroller/core/internal/OFChannelHandler.java b/src/main/java/net/floodlightcontroller/core/internal/OFChannelHandler.java
index d2e4156..b011e6b 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/OFChannelHandler.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/OFChannelHandler.java
@@ -1069,7 +1069,7 @@
          * controller. Next State: depends on the role of this controller for
          * this switch - either MASTER or EQUAL.
          */
-        WAIT_SWITCH_DRIVER_SUB_HANDSHAKE(true) {
+        WAIT_SWITCH_DRIVER_SUB_HANDSHAKE(false) {
 
             @Override
             void processOFError(OFChannelHandler h, OFErrorMsg m)
@@ -1871,7 +1871,14 @@
 
         void processOFRoleReply(OFChannelHandler h, OFRoleReply m)
                 throws SwitchStateException, IOException {
-            unhandledMessageReceived(h, m);
+            // A role reply message received by the default handler implies
+            // that the channel state-machine is in a state where it does not
+            // expect a role message. That in turn implies that role-request was
+            // sent out by this controller, as a result of a callback
+            // from the registry service, because the chosen master (some other
+            // instance) died, while this controller instance has not completed
+            // handshake yet. Best to disconnect switch and start over.
+            illegalMessageReceived(h, m);
         }
 
         void processOFGetAsyncReply(OFChannelHandler h,
@@ -1925,15 +1932,17 @@
          * controller that wins mastership. Once the registry API changes to
          * reply to every request, we would not need to wait for a timeout to
          * move to Role.EQUAL (or SLAVE).
-         * 
+         *
          * @param h the channel handler for this switch
          * @param ctx the netty channel handler context for the channel 'h'
          * @throws IOException
          */
         public void handleTimedOutHandshake(OFChannelHandler h,
                 ChannelHandlerContext ctx) throws IOException {
-            log.error("Disconnecting switch {}: failed to complete handshake",
-                    h.getSwitchInfoString());
+            log.error("Disconnecting switch {}: failed to complete handshake " +
+                    "in state {} (with driverState: {})",
+                    h.getSwitchInfoString(), h.getStateForTesting(),
+                    h.sw.getSwitchDriverState());
             h.counters.switchDisconnectHandshakeTimeout.updateCounterWithFlush();
             ctx.getChannel().close();
         }
diff --git a/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImplBase.java b/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImplBase.java
index 3e6d7b2..254e658 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImplBase.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImplBase.java
@@ -1286,4 +1286,9 @@
     public Lock getListenerWriteLock() {
         return listenerLock.writeLock();
     }
+
+    public String getSwitchDriverState() {
+        return "";
+    }
+
 }
diff --git a/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingManager.java b/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingManager.java
index 60cf0b1..961a913 100644
--- a/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingManager.java
+++ b/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingManager.java
@@ -36,7 +36,7 @@
 import net.onrc.onos.core.matchaction.action.PopMplsAction;
 import net.onrc.onos.core.matchaction.action.PushMplsAction;
 import net.onrc.onos.core.matchaction.action.SetMplsIdAction;
-import net.onrc.onos.core.matchaction.match.Ipv4PacketMatch;
+import net.onrc.onos.core.matchaction.match.Ipv4Match;
 import net.onrc.onos.core.matchaction.match.Match;
 import net.onrc.onos.core.matchaction.match.MplsMatch;
 import net.onrc.onos.core.packet.ARP;
@@ -432,7 +432,7 @@
     private void setIpTableRouter(Switch sw, String subnetIp, String mplsLabel,
             List<String> fwdToSws) {
 
-        Ipv4PacketMatch ipMatch = new Ipv4PacketMatch(subnetIp);
+        Ipv4Match ipMatch = new Ipv4Match(subnetIp);
         List<Action> actions = new ArrayList<>();
 
         // If destination SW is the same as the fwd SW, then do not push MPLS label
@@ -537,9 +537,9 @@
         Match m = ma.getMatch();
         List<Action> actions = ma.getActions();
 
-        if (m instanceof Ipv4PacketMatch) {
+        if (m instanceof Ipv4Match) {
             logStr.append("If the IP matches with ");
-            IPv4Net ip = ((Ipv4PacketMatch) m).getDestination();
+            IPv4Net ip = ((Ipv4Match) m).getDestination();
             logStr.append(ip.toString());
             logStr.append(" then ");
         }
diff --git a/src/main/java/net/onrc/onos/core/configmanager/NetworkConfigManager.java b/src/main/java/net/onrc/onos/core/configmanager/NetworkConfigManager.java
index b1d3836..d7c0ac4 100644
--- a/src/main/java/net/onrc/onos/core/configmanager/NetworkConfigManager.java
+++ b/src/main/java/net/onrc/onos/core/configmanager/NetworkConfigManager.java
@@ -46,13 +46,13 @@
      * JSON Config file needs to use one of the following types for defining the
      * kind of switch or link it wishes to configure.
      */
-    private static final String SEGMENT_ROUTER = "Router_SR";
-    private static final String ROADM = "Roadm";
-    private static final String OF10SWITCH = "Switch_OF10";
+    public static final String SEGMENT_ROUTER = "Router_SR";
+    public static final String ROADM = "Roadm";
+    public static final String OF10SWITCH = "Switch_OF10";
 
-    private static final String PKT_LINK = "pktLink";
-    private static final String WDM_LINK = "wdmLink";
-    private static final String PKT_OPT_LINK = "pktOptLink";
+    public static final String PKT_LINK = "pktLink";
+    public static final String WDM_LINK = "wdmLink";
+    public static final String PKT_OPT_LINK = "pktOptLink";
 
     NetworkConfig networkConfig;
     private ConcurrentMap<Long, SwitchConfig> configuredSwitches;
diff --git a/src/main/java/net/onrc/onos/core/configmanager/PktLinkConfig.java b/src/main/java/net/onrc/onos/core/configmanager/PktLinkConfig.java
index f205686..e205e77 100644
--- a/src/main/java/net/onrc/onos/core/configmanager/PktLinkConfig.java
+++ b/src/main/java/net/onrc/onos/core/configmanager/PktLinkConfig.java
@@ -132,6 +132,7 @@
     private void validateParams() {
         // TODO - wrong-names, duplicate links,
         // duplicate use of port, is switch-allowed for which link is allowed?
+        // valid port numbers
     }
 
     public static class PktLinkParamsNotSpecified extends RuntimeException {
diff --git a/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplCPqD13.java b/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplCPqD13.java
index 2e80c3b..d722da8 100644
--- a/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplCPqD13.java
+++ b/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplCPqD13.java
@@ -2,16 +2,51 @@
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import net.floodlightcontroller.core.IFloodlightProviderService.Role;
+import net.floodlightcontroller.core.IOF13Switch;
+import net.floodlightcontroller.core.IOFSwitch;
 import net.floodlightcontroller.core.SwitchDriverSubHandshakeAlreadyStarted;
 import net.floodlightcontroller.core.SwitchDriverSubHandshakeCompleted;
 import net.floodlightcontroller.core.SwitchDriverSubHandshakeNotStarted;
 import net.floodlightcontroller.core.internal.OFSwitchImplBase;
+import net.onrc.onos.core.configmanager.INetworkConfigService;
+import net.onrc.onos.core.configmanager.INetworkConfigService.NetworkConfigState;
+import net.onrc.onos.core.configmanager.INetworkConfigService.SwitchConfigStatus;
+import net.onrc.onos.core.configmanager.NetworkConfig.LinkConfig;
+import net.onrc.onos.core.configmanager.NetworkConfigManager;
+import net.onrc.onos.core.configmanager.PktLinkConfig;
+import net.onrc.onos.core.configmanager.SegmentRouterConfig;
+import net.onrc.onos.core.matchaction.MatchAction;
+import net.onrc.onos.core.matchaction.MatchActionOperationEntry;
+import net.onrc.onos.core.matchaction.MatchActionOperations.Operator;
+import net.onrc.onos.core.matchaction.action.Action;
+import net.onrc.onos.core.matchaction.action.CopyTtlInAction;
+import net.onrc.onos.core.matchaction.action.CopyTtlOutAction;
+import net.onrc.onos.core.matchaction.action.DecMplsTtlAction;
+import net.onrc.onos.core.matchaction.action.DecNwTtlAction;
+import net.onrc.onos.core.matchaction.action.GroupAction;
+import net.onrc.onos.core.matchaction.action.ModifyDstMacAction;
+import net.onrc.onos.core.matchaction.action.ModifySrcMacAction;
+import net.onrc.onos.core.matchaction.action.OutputAction;
+import net.onrc.onos.core.matchaction.action.PopMplsAction;
+import net.onrc.onos.core.matchaction.action.PushMplsAction;
+import net.onrc.onos.core.matchaction.action.SetMplsIdAction;
+import net.onrc.onos.core.matchaction.match.Ipv4Match;
+import net.onrc.onos.core.matchaction.match.Match;
+import net.onrc.onos.core.matchaction.match.MplsMatch;
+import net.onrc.onos.core.matchaction.match.PacketMatch;
+import net.onrc.onos.core.util.Dpid;
+import net.onrc.onos.core.util.IPv4Net;
+import net.onrc.onos.core.util.PortNumber;
 
 import org.projectfloodlight.openflow.protocol.OFAsyncGetReply;
 import org.projectfloodlight.openflow.protocol.OFBarrierRequest;
@@ -48,15 +83,18 @@
 import org.projectfloodlight.openflow.types.U64;
 import org.projectfloodlight.openflow.util.HexString;
 
+import com.google.common.collect.Sets;
+
 /**
  * OFDescriptionStatistics Vendor (Manufacturer Desc.): Stanford University,
  * Ericsson Research and CPqD Research. Make (Hardware Desc.) : OpenFlow 1.3
  * Reference Userspace Switch Model (Datapath Desc.) : None Software : Serial :
  * None
  */
-public class OFSwitchImplCPqD13 extends OFSwitchImplBase {
+public class OFSwitchImplCPqD13 extends OFSwitchImplBase implements IOF13Switch {
     private static final int VLAN_ID_OFFSET = 16;
     private AtomicBoolean driverHandshakeComplete;
+    private AtomicBoolean haltStateMachine;
     private OFFactory factory;
     private static final int OFPCML_NO_BUFFER = 0xffff;
     // Configuration of asynch messages to controller. We need different
@@ -73,7 +111,6 @@
     private static final long TEST_FLOW_REMOVED_MASK = 0xf;
     private static final long TEST_PACKET_IN_MASK = 0x7;
     private static final long TEST_PORT_STATUS_MASK = 0x7;
-    private long barrierXidToWaitFor = -1;
 
     private static final int TABLE_VLAN = 0;
     private static final int TABLE_TMAC = 1;
@@ -83,25 +120,38 @@
     private static final int TABLE_ACL = 5;
 
     private static final short MAX_PRIORITY = (short) 0xffff;
-    private static final short SLASH_24_PRIORITY = (short) 0xfff0;
-    private static final short SLASH_16_PRIORITY = (short) 0xff00;
-    private static final short SLASH_8_PRIORITY = (short) 0xf000;
+    private static final short PRIORITY_MULTIPLIER = (short) 2046;
     private static final short MIN_PRIORITY = 0x0;
     private static final U64 METADATA_MASK = U64.of(Long.MAX_VALUE << 1 | 0x1);
 
     ConcurrentHashMap<Integer, OFGroup> l2groups;
 
+    private long barrierXidToWaitFor = -1;
+    private DriverState driverState;
     private final boolean usePipeline13;
+    private SegmentRouterConfig srConfig;
+    private ConcurrentMap<Dpid, Set<PortNumber>> neighbors;
+    private ConcurrentMap<NeighborSet, EcmpInfo> ecmpGroups;
+
+
 
     public OFSwitchImplCPqD13(OFDescStatsReply desc, boolean usePipeline13) {
         super();
+        haltStateMachine = new AtomicBoolean(false);
+        driverState = DriverState.INIT;
         driverHandshakeComplete = new AtomicBoolean(false);
         l2groups = new ConcurrentHashMap<Integer, OFGroup>();
         setSwitchDescription(desc);
-
+        neighbors = new ConcurrentHashMap<Dpid, Set<PortNumber>>();
+        ecmpGroups = new ConcurrentHashMap<NeighborSet, EcmpInfo>();
         this.usePipeline13 = usePipeline13;
     }
 
+    // *****************************
+    // OFSwitchImplBase
+    // *****************************
+
+
     /* (non-Javadoc)
      * @see java.lang.Object#toString()
      */
@@ -123,10 +173,10 @@
         if (!usePipeline13) {
             // Send packet-in to controller if a packet misses the first table
             populateTableMissEntry(0, true, false, false, 0);
+            driverHandshakeComplete.set(true);
         } else {
-           configureSwitch();
+            nextDriverState();
         }
-        sendBarrier(true);
     }
 
 
@@ -141,64 +191,759 @@
     public void processDriverHandshakeMessage(OFMessage m) {
         if (!startDriverHandshakeCalled)
             throw new SwitchDriverSubHandshakeNotStarted();
-        if (driverHandshakeComplete.get())
+        if (isDriverHandshakeComplete())
             throw new SwitchDriverSubHandshakeCompleted(m);
+        try {
+            processOFMessage(this, m);
+        } catch (IOException e) {
+            log.error("Error generated when processing OFMessage", e.getCause());
+        }
+    }
 
+    @Override
+    public String getSwitchDriverState() {
+        return driverState.toString();
+    }
+
+    // *****************************
+    // Driver handshake state-machine
+    // *****************************
+
+    enum DriverState {
+        INIT,
+        SET_TABLE_MISS_ENTRIES,
+        SET_TABLE_VLAN_TMAC,
+        SET_GROUPS,
+        VERIFY_GROUPS,
+        SET_ADJACENCY_LABELS,
+        EXIT
+    }
+
+    protected void nextDriverState() throws IOException {
+        DriverState currentState = driverState;
+        if (haltStateMachine.get())
+            return;
+        switch (currentState) {
+        case INIT:
+            driverState = DriverState.SET_TABLE_MISS_ENTRIES;
+            setTableMissEntries();
+            sendBarrier();
+            break;
+        case SET_TABLE_MISS_ENTRIES:
+            driverState = DriverState.SET_TABLE_VLAN_TMAC;
+            getNetworkConfig();
+            populateTableVlan();
+            populateTableTMac();
+            sendBarrier();
+            break;
+        case SET_TABLE_VLAN_TMAC:
+            driverState = DriverState.SET_GROUPS;
+            createGroups();
+            sendBarrier();
+            break;
+        case SET_GROUPS:
+            driverState = DriverState.VERIFY_GROUPS;
+            verifyGroups();
+            break;
+        case VERIFY_GROUPS:
+            driverState = DriverState.SET_ADJACENCY_LABELS;
+            assignAdjacencyLabels();
+            break;
+        case SET_ADJACENCY_LABELS:
+            driverState = DriverState.EXIT;
+            driverHandshakeComplete.set(true);
+            break;
+        case EXIT:
+        default:
+            driverState = DriverState.EXIT;
+            log.error("Driver handshake has exited for sw: {}", getStringId());
+        }
+    }
+
+    void processOFMessage(IOFSwitch sw, OFMessage m) throws IOException {
         switch (m.getType()) {
         case BARRIER_REPLY:
-            if (m.getXid() == barrierXidToWaitFor)
-                driverHandshakeComplete.set(true);
+            processBarrierReply(m);
             break;
 
         case ERROR:
-            log.error("Switch {} Error {}", getStringId(), (OFErrorMsg) m);
+            processErrorMessage(m);
             break;
 
-        case FEATURES_REPLY:
-            break;
-        case FLOW_REMOVED:
-            break;
         case GET_ASYNC_REPLY:
             OFAsyncGetReply asrep = (OFAsyncGetReply) m;
             decodeAsyncGetReply(asrep);
             break;
 
         case PACKET_IN:
+            // not ready to handle packet-ins
             break;
-        case PORT_STATUS:
-            break;
+
         case QUEUE_GET_CONFIG_REPLY:
-            break;
-        case ROLE_REPLY:
+            // not doing queue config yet
             break;
 
         case STATS_REPLY:
             processStatsReply((OFStatsReply) m);
             break;
 
+        case ROLE_REPLY: // channelHandler should handle this
+        case PORT_STATUS: // channelHandler should handle this
+        case FEATURES_REPLY: // don't care
+        case FLOW_REMOVED: // don't care
         default:
             log.debug("Received message {} during switch-driver subhandshake "
-                    + "from switch {} ... Ignoring message", m, getStringId());
+                    + "from switch {} ... Ignoring message", m, sw.getStringId());
+        }
+    }
+
+    private void processStatsReply(OFStatsReply sr) {
+        switch (sr.getStatsType()) {
+        case AGGREGATE:
+            break;
+        case DESC:
+            break;
+        case EXPERIMENTER:
+            break;
+        case FLOW:
+            break;
+        case GROUP_DESC:
+            processGroupDesc((OFGroupDescStatsReply) sr);
+            break;
+        case GROUP_FEATURES:
+            processGroupFeatures((OFGroupFeaturesStatsReply) sr);
+            break;
+        case METER_CONFIG:
+            break;
+        case METER_FEATURES:
+            break;
+        case PORT_DESC:
+            break;
+        case TABLE_FEATURES:
+            break;
+        default:
+            break;
 
         }
     }
 
+    private void processErrorMessage(OFMessage m) {
+        log.error("Switch {} Error {} in DriverState", getStringId(),
+                (OFErrorMsg) m, driverState);
+    }
+
+    private void processBarrierReply(OFMessage m) throws IOException {
+        if (m.getXid() == barrierXidToWaitFor) {
+            // Driver state-machine progresses to the next state.
+            // If Barrier messages is not received, then eventually
+            // the ChannelHandler state machine will timeout, and the switch
+            // will be disconnected.
+            nextDriverState();
+        } else {
+            log.error("Received incorrect barrier-message xid {} (expected: {}) in "
+                    + "switch-driver state {} for switch {}", m, barrierXidToWaitFor,
+                    driverState, getStringId());
+        }
+    }
+
+    private void processGroupDesc(OFGroupDescStatsReply gdsr) {
+        log.info("Sw: {} Group Desc {}", getStringId(), gdsr);
+        try {
+            nextDriverState();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
+
+    // *****************************
+    // Utility methods
+    // *****************************
+
+    void setTableMissEntries() throws IOException {
+        // set all table-miss-entries
+        populateTableMissEntry(TABLE_VLAN, true, false, false, -1);
+        populateTableMissEntry(TABLE_TMAC, true, false, false, -1);
+        populateTableMissEntry(TABLE_IPv4_UNICAST, false, true, true,
+                TABLE_ACL);
+        populateTableMissEntry(TABLE_MPLS, false, true, true,
+                TABLE_ACL);
+        populateTableMissEntry(TABLE_ACL, false, false, false, -1);
+    }
+
+    private void sendBarrier() throws IOException {
+        long xid = getNextTransactionId();
+        barrierXidToWaitFor = xid;
+        OFBarrierRequest br = getFactory()
+                .buildBarrierRequest()
+                .setXid(xid)
+                .build();
+        write(br, null);
+    }
+
+    /**
+     * Adds a table-miss-entry to a pipeline table.
+     * <p>
+     * The table-miss-entry can be added with 'write-actions' or
+     * 'apply-actions'. It can also add a 'goto-table' instruction. By default
+     * if none of the booleans in the call are set, then the table-miss entry is
+     * added with no instructions, which means that if a packet hits the
+     * table-miss-entry, pipeline execution will stop, and the action set
+     * associated with the packet will be executed.
+     *
+     * @param tableToAdd the table to where the table-miss-entry will be added
+     * @param toControllerNow as an APPLY_ACTION instruction
+     * @param toControllerWrite as a WRITE_ACTION instruction
+     * @param toTable as a GOTO_TABLE instruction
+     * @param tableToSend the table to send as per the GOTO_TABLE instruction it
+     *        needs to be set if 'toTable' is true. Ignored of 'toTable' is
+     *        false.
+     * @throws IOException
+     */
+    @SuppressWarnings("unchecked")
+    private void populateTableMissEntry(int tableToAdd, boolean toControllerNow,
+            boolean toControllerWrite,
+            boolean toTable, int tableToSend) throws IOException {
+        OFOxmList oxmList = OFOxmList.EMPTY;
+        OFMatchV3 match = factory.buildMatchV3()
+                .setOxmList(oxmList)
+                .build();
+        OFAction outc = factory.actions()
+                .buildOutput()
+                .setPort(OFPort.CONTROLLER)
+                .setMaxLen(OFPCML_NO_BUFFER)
+                .build();
+        List<OFInstruction> instructions = new ArrayList<OFInstruction>();
+        if (toControllerNow) {
+            // table-miss instruction to send to controller immediately
+            OFInstruction instr = factory.instructions()
+                    .buildApplyActions()
+                    .setActions(Collections.singletonList(outc))
+                    .build();
+            instructions.add(instr);
+        }
+
+        if (toControllerWrite) {
+            // table-miss instruction to write-action to send to controller
+            // this will be executed whenever the action-set gets executed
+            OFInstruction instr = factory.instructions()
+                    .buildWriteActions()
+                    .setActions(Collections.singletonList(outc))
+                    .build();
+            instructions.add(instr);
+        }
+
+        if (toTable) {
+            // table-miss instruction to goto-table x
+            OFInstruction instr = factory.instructions()
+                    .gotoTable(TableId.of(tableToSend));
+            instructions.add(instr);
+        }
+
+        if (!toControllerNow && !toControllerWrite && !toTable) {
+            // table-miss has no instruction - at which point action-set will be
+            // executed - if there is an action to output/group in the action
+            // set
+            // the packet will be sent there, otherwise it will be dropped.
+            instructions = (List<OFInstruction>) Collections.EMPTY_LIST;
+        }
+
+        OFMessage tableMissEntry = factory.buildFlowAdd()
+                .setTableId(TableId.of(tableToAdd))
+                .setMatch(match) // match everything
+                .setInstructions(instructions)
+                .setPriority(MIN_PRIORITY)
+                .setBufferId(OFBufferId.NO_BUFFER)
+                .setIdleTimeout(0)
+                .setHardTimeout(0)
+                .setXid(getNextTransactionId())
+                .build();
+        write(tableMissEntry, null);
+    }
+
+    private void getNetworkConfig() {
+        INetworkConfigService ncs = floodlightProvider.getNetworkConfigService();
+        SwitchConfigStatus scs = ncs.checkSwitchConfig(new Dpid(getId()));
+        if (scs.getConfigState() == NetworkConfigState.ACCEPT_ADD) {
+            srConfig = (SegmentRouterConfig) scs.getSwitchConfig();
+        } else {
+            log.error("Switch not configured as Segment-Router");
+        }
+
+        List<LinkConfig> linkConfigList = ncs.getConfiguredAllowedLinks();
+        setNeighbors(linkConfigList);
+    }
+
+    private void populateTableVlan() throws IOException {
+        List<OFMessage> msglist = new ArrayList<OFMessage>();
+        for (OFPortDesc p : getPorts()) {
+            int pnum = p.getPortNo().getPortNumber();
+            if (U32.of(pnum).compareTo(U32.of(OFPort.MAX.getPortNumber())) < 1) {
+                OFOxmInPort oxp = factory.oxms().inPort(p.getPortNo());
+                OFOxmVlanVid oxv = factory.oxms()
+                        .vlanVid(OFVlanVidMatch.UNTAGGED);
+                OFOxmList oxmList = OFOxmList.of(oxp, oxv);
+                OFMatchV3 match = factory.buildMatchV3()
+                        .setOxmList(oxmList).build();
+
+                // TODO: match on vlan-tagged packets for vlans configured on
+                // subnet ports and strip-vlan
+
+                // Do not need to add vlans
+                /*int vlanid = getVlanConfig(pnum);
+                OFOxmVlanVid vidToSet = factory.oxms()
+                        .vlanVid(OFVlanVidMatch.ofVlan(vlanid));
+                OFAction pushVlan = factory.actions().pushVlan(EthType.VLAN_FRAME);
+                OFAction setVlan = factory.actions().setField(vidToSet);
+                List<OFAction> actionlist = new ArrayList<OFAction>();
+                actionlist.add(pushVlan);
+                actionlist.add(setVlan);
+                OFInstruction appAction = factory.instructions().buildApplyActions()
+                        .setActions(actionlist).build();*/
+
+                OFInstruction gotoTbl = factory.instructions().buildGotoTable()
+                        .setTableId(TableId.of(TABLE_TMAC)).build();
+                List<OFInstruction> instructions = new ArrayList<OFInstruction>();
+                // instructions.add(appAction);
+                instructions.add(gotoTbl);
+                OFMessage flowEntry = factory.buildFlowAdd()
+                        .setTableId(TableId.of(TABLE_VLAN))
+                        .setMatch(match)
+                        .setInstructions(instructions)
+                        .setPriority(1000) // does not matter - all rules
+                                           // exclusive
+                        .setBufferId(OFBufferId.NO_BUFFER)
+                        .setIdleTimeout(0)
+                        .setHardTimeout(0)
+                        .setXid(getNextTransactionId())
+                        .build();
+                msglist.add(flowEntry);
+            }
+        }
+        write(msglist);
+        log.debug("Adding {} port/vlan-rules in sw {}", msglist.size(), getStringId());
+    }
+
+    private void populateTableTMac() throws IOException {
+        // match for router-mac and ip-packets
+        OFOxmEthType oxe = factory.oxms().ethType(EthType.IPv4);
+        OFOxmEthDst dmac = factory.oxms().ethDst(getRouterMacAddr());
+        OFOxmList oxmListIp = OFOxmList.of(dmac, oxe);
+        OFMatchV3 matchIp = factory.buildMatchV3()
+                .setOxmList(oxmListIp).build();
+        OFInstruction gotoTblIp = factory.instructions().buildGotoTable()
+                .setTableId(TableId.of(TABLE_IPv4_UNICAST)).build();
+        List<OFInstruction> instructionsIp = Collections.singletonList(gotoTblIp);
+        OFMessage ipEntry = factory.buildFlowAdd()
+                .setTableId(TableId.of(TABLE_TMAC))
+                .setMatch(matchIp)
+                .setInstructions(instructionsIp)
+                .setPriority(1000) // strict priority required lower than
+                                   // multicastMac
+                .setBufferId(OFBufferId.NO_BUFFER)
+                .setIdleTimeout(0)
+                .setHardTimeout(0)
+                .setXid(getNextTransactionId())
+                .build();
+
+        // match for router-mac and mpls packets
+        OFOxmEthType oxmpls = factory.oxms().ethType(EthType.MPLS_UNICAST);
+        OFOxmList oxmListMpls = OFOxmList.of(dmac, oxmpls);
+        OFMatchV3 matchMpls = factory.buildMatchV3()
+                .setOxmList(oxmListMpls).build();
+        OFInstruction gotoTblMpls = factory.instructions().buildGotoTable()
+                .setTableId(TableId.of(TABLE_MPLS)).build();
+        List<OFInstruction> instructionsMpls = Collections.singletonList(gotoTblMpls);
+        OFMessage mplsEntry = factory.buildFlowAdd()
+                .setTableId(TableId.of(TABLE_TMAC))
+                .setMatch(matchMpls)
+                .setInstructions(instructionsMpls)
+                .setPriority(1001) // strict priority required lower than
+                                   // multicastMac
+                .setBufferId(OFBufferId.NO_BUFFER)
+                .setIdleTimeout(0)
+                .setHardTimeout(0)
+                .setXid(getNextTransactionId())
+                .build();
+
+        log.debug("Adding termination-mac-rules in sw {}", getStringId());
+        List<OFMessage> msglist = new ArrayList<OFMessage>(2);
+        msglist.add(ipEntry);
+        msglist.add(mplsEntry);
+        write(msglist);
+    }
+
+    private MacAddress getRouterMacAddr() {
+        if (srConfig != null) {
+            return MacAddress.of(srConfig.getRouterMac());
+        } else {
+            // return a dummy mac address - it will not be used
+            return MacAddress.of("00:00:00:00:00:00");
+        }
+    }
+
+    private MacAddress getNeighborRouterMacAddress(Dpid ndpid) {
+        INetworkConfigService ncs = floodlightProvider.getNetworkConfigService();
+        SwitchConfigStatus scs = ncs.checkSwitchConfig(ndpid);
+        if (scs.getConfigState() == NetworkConfigState.ACCEPT_ADD) {
+            return MacAddress.of(((SegmentRouterConfig) scs.getSwitchConfig())
+                    .getRouterMac());
+        } else {
+            // return a dummy mac address - it will not be used
+            return MacAddress.of("00:00:00:00:00:00");
+        }
+    }
+
+    private void setNeighbors(List<LinkConfig> linkConfigList) {
+        List<PortNumber> portlist = new ArrayList<PortNumber>();
+        for (LinkConfig lg : linkConfigList) {
+            if (!lg.getType().equals(NetworkConfigManager.PKT_LINK)) {
+                return;
+            }
+            PktLinkConfig plg = (PktLinkConfig) lg;
+            if (plg.getDpid1() == getId()) {
+                addNeighborAtPort(new Dpid(plg.getDpid2()),
+                        PortNumber.uint32(plg.getPort1()));
+            } else if (plg.getDpid2() == getId()) {
+                addNeighborAtPort(new Dpid(plg.getDpid1()),
+                        PortNumber.uint32(plg.getPort2()));
+            }
+        }
+    }
+
+    private void addNeighborAtPort(Dpid neighborDpid, PortNumber portToNeighbor) {
+        if (neighbors.get(neighborDpid) != null) {
+            neighbors.get(neighborDpid).add(portToNeighbor);
+        } else {
+            Set<PortNumber> ports = new HashSet<PortNumber>();
+            ports.add(portToNeighbor);
+            neighbors.put(neighborDpid, ports);
+        }
+    }
+
+    /**
+     * createGroups creates ECMP groups for all ports on this router connected
+     * to other routers (in the OF network). The information for ports is
+     * gleaned from the configured links. If no links are configured no groups
+     * will be created, and it is up to the caller of the IOF13Switch API to
+     * create groups.
+     * <p>
+     * By default all ports connected to the same neighbor router will be part
+     * of the same ECMP group. In addition, groups will be created for all
+     * possible combinations of neighbor routers.
+     * <p>
+     * For example, consider this router (R0) connected to 3 neighbors (R1, R2,
+     * and R3). The following groups will be created in R0:
+     * <li>1) all ports to R1,
+     * <li>2) all ports to R2,
+     * <li>3) all ports to R3,
+     * <li>4) all ports to R1 and R2
+     * <li>5) all ports to R1 and R3
+     * <li>6) all ports to R2 and R3
+     * <li>7) all ports to R1, R2, and R3
+     */
+    private void createGroups() {
+        Set<Dpid> dpids = neighbors.keySet();
+        if (dpids == null || dpids.isEmpty()) {
+            return;
+        }
+        // temp map of ecmp groupings
+        /*        Map<NeighborSet, List<BucketInfo>> temp =
+                        new HashMap<NeighborSet, List<BucketInfo>>();
+        */
+        // get all combinations of neighbors
+        Set<Set<Dpid>> powerSet = Sets.powerSet(dpids);
+        int groupid = 1;
+        for (Set<Dpid> combo : powerSet) {
+            if (combo.isEmpty()) {
+                // eliminate the empty set in the power set
+                continue;
+            }
+            List<BucketInfo> buckets = new ArrayList<BucketInfo>();
+            NeighborSet ns = new NeighborSet();
+            for (Dpid d : combo) {
+                ns.addDpid(d);
+                for (PortNumber sp : neighbors.get(d)) {
+                    BucketInfo b = new BucketInfo(d,
+                            MacAddress.of(srConfig.getRouterMac()),
+                            getNeighborRouterMacAddress(d), sp);
+                    buckets.add(b);
+                }
+            }
+            EcmpInfo ecmpInfo = new EcmpInfo(groupid++, buckets);
+            setEcmpGroup(ecmpInfo);
+            ecmpGroups.put(ns, ecmpInfo);
+            log.debug("Creating ecmp group in sw {}: {}", getStringId(), ecmpInfo);
+        }
+    }
+
+    private class EcmpInfo {
+        int groupId;
+        List<BucketInfo> buckets;
+
+        EcmpInfo(int gid, List<BucketInfo> bucketInfos) {
+            groupId = gid;
+            buckets = bucketInfos;
+        }
+
+        @Override
+        public String toString() {
+            return "groupId: " + groupId + ", buckets: " + buckets;
+        }
+    }
+
+    private class BucketInfo {
+        Dpid neighborDpid;
+        MacAddress srcMac;
+        MacAddress dstMac;
+        PortNumber outport;
+
+        BucketInfo(Dpid nDpid, MacAddress smac, MacAddress dmac, PortNumber p) {
+            neighborDpid = nDpid;
+            srcMac = smac;
+            dstMac = dmac;
+            outport = p;
+        }
+
+        @Override
+        public String toString() {
+            return " {neighborDpid: " + neighborDpid + ", dstMac: " + dstMac +
+                    ", srcMac: " + srcMac + ", outport: " + outport + "}";
+        }
+    }
+
+    private void setEcmpGroup(EcmpInfo ecmpInfo) {
+        List<OFMessage> msglist = new ArrayList<OFMessage>();
+        OFGroup group = OFGroup.of(ecmpInfo.groupId);
+
+        List<OFBucket> buckets = new ArrayList<OFBucket>();
+        for (BucketInfo b : ecmpInfo.buckets) {
+            OFOxmEthDst dmac = factory.oxms()
+                    .ethDst(b.dstMac);
+            OFAction setDA = factory.actions().buildSetField()
+                    .setField(dmac).build();
+            OFOxmEthDst smac = factory.oxms()
+                    .ethDst(b.srcMac);
+            OFAction setSA = factory.actions().buildSetField()
+                    .setField(smac).build();
+            OFAction outp = factory.actions().buildOutput()
+                    .setPort(OFPort.of(b.outport.shortValue()))
+                    .build();
+            List<OFAction> actions = new ArrayList<OFAction>();
+            actions.add(setSA);
+            actions.add(setDA);
+            actions.add(outp);
+            OFBucket ofb = factory.buildBucket()
+                    .setWeight(1)
+                    .setActions(actions)
+                    .build();
+            buckets.add(ofb);
+        }
+
+        OFMessage gm = factory.buildGroupAdd()
+                .setGroup(group)
+                .setBuckets(buckets)
+                .setGroupType(OFGroupType.SELECT)
+                .setXid(getNextTransactionId())
+                .build();
+        msglist.add(gm);
+        try {
+            write(msglist);
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
+
+    private void verifyGroups() throws IOException {
+        sendGroupDescRequest();
+    }
+
+    private void sendGroupDescRequest() throws IOException {
+        OFMessage gdr = factory.buildGroupDescStatsRequest()
+                .setXid(getNextTransactionId())
+                .build();
+        write(gdr, null);
+    }
+
+    private void assignAdjacencyLabels() {
+        // TODO
+        try {
+            nextDriverState();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
+
+    private void pushIpEntry(MatchActionOperationEntry mao) throws IOException {
+        MatchAction ma = mao.getTarget();
+        Operator op = mao.getOperator();
+        Ipv4Match ipm = (Ipv4Match) ma.getMatch();
+
+        // set match
+        IPv4Net ipdst = ipm.getDestination();
+        OFOxmEthType ethTypeIp = factory.oxms()
+                .ethType(EthType.IPv4);
+        OFOxmIpv4DstMasked ipPrefix = factory.oxms()
+                .ipv4DstMasked(
+                        IPv4Address.of(ipdst.address().value()),
+                        IPv4Address.ofCidrMaskLength(ipdst.prefixLen())
+                );
+        OFOxmList oxmList = OFOxmList.of(ethTypeIp, ipPrefix);
+        OFMatchV3 match = factory.buildMatchV3()
+                .setOxmList(oxmList).build();
+
+        // set actions
+        List<OFAction> writeActions = new ArrayList<OFAction>();
+        for (Action action : ma.getActions()) {
+            OFAction ofAction = null;
+            if (action instanceof OutputAction) {
+                OutputAction outputAction = (OutputAction) action;
+                OFPort port = OFPort.of((int) outputAction.getPortNumber().value());
+                ofAction = factory.actions().output(port, Short.MAX_VALUE);
+            } else if (action instanceof ModifyDstMacAction) {
+                long dstMac = ((ModifyDstMacAction) action).getDstMac().toLong();
+                OFOxmEthDst dmac = factory.oxms()
+                        .ethDst(MacAddress.of(dstMac));
+                ofAction = factory.actions().buildSetField()
+                        .setField(dmac).build();
+            } else if (action instanceof ModifySrcMacAction) {
+                long srcMac = ((ModifySrcMacAction) action).getSrcMac().toLong();
+                OFOxmEthSrc smac = factory.oxms()
+                        .ethSrc(MacAddress.of(srcMac));
+                ofAction = factory.actions().buildSetField()
+                        .setField(smac).build();
+            } else if (action instanceof PushMplsAction) {
+                ofAction = factory.actions().pushMpls(EthType.MPLS_UNICAST);
+            } else if (action instanceof SetMplsIdAction) {
+                int labelid = ((SetMplsIdAction) action).getMplsId();
+                OFOxmMplsLabel lid = factory.oxms()
+                        .mplsLabel(U32.of(labelid));
+                ofAction = factory.actions().buildSetField()
+                        .setField(lid).build();
+            } else if (action instanceof PopMplsAction) {
+
+            } else if (action instanceof GroupAction) {
+                ofAction = factory.actions().buildGroup()
+                        .setGroup(OFGroup.of(0)) // TODO fail
+                        .build();
+            } else if (action instanceof DecNwTtlAction) {
+
+            } else if (action instanceof DecMplsTtlAction) {
+
+            } else if (action instanceof CopyTtlInAction) {
+
+            } else if (action instanceof CopyTtlOutAction) {
+                ofAction = factory.actions().copyTtlOut();
+            } else {
+                log.warn("Unsupported Action type: {}", action.getClass().getName());
+                continue;
+            }
+            writeActions.add(ofAction);
+        }
+
+        // OFAction setBos =
+        // factory.actions().buildSetField().setField(bos).build();
+
+        // set instructions
+        OFInstruction writeInstr = factory.instructions().buildWriteActions()
+                .setActions(writeActions).build();
+        OFInstruction gotoInstr = factory.instructions().buildGotoTable()
+                .setTableId(TableId.of(TABLE_ACL)).build();
+        List<OFInstruction> instructions = new ArrayList<OFInstruction>();
+        instructions.add(writeInstr);
+        instructions.add(gotoInstr);
+
+        // set flow priority
+        int priority = ipdst.prefixLen() * PRIORITY_MULTIPLIER;
+        if (ipdst.prefixLen() == (short) 32) {
+            priority = MAX_PRIORITY;
+        }
+
+        // set flow-mod XXX - This is only ADD (not doing DELETE yet)
+        OFMessage ipFlow = factory.buildFlowAdd()
+                .setTableId(TableId.of(TABLE_IPv4_UNICAST))
+                .setMatch(match)
+                .setInstructions(instructions)
+                .setPriority(priority)
+                .setBufferId(OFBufferId.NO_BUFFER)
+                .setIdleTimeout(0)
+                .setHardTimeout(0)
+                .setXid(getNextTransactionId())
+                .build();
+
+        write(ipFlow, null);
+        log.debug("Adding ip-rule {}-{} in sw {}", match, writeActions,
+                getStringId());
+    }
+
+    private void pushMplsEntry(MatchActionOperationEntry mao) {
+
+    }
+
+    private void pushAclEntry(MatchActionOperationEntry mao) {
+
+    }
+
+    // *****************************
+    // IOF13Switch
+    // *****************************
+
+    @Override
+    public void pushFlow(MatchActionOperationEntry matchActionOp) throws IOException {
+        final MatchAction matchAction = matchActionOp.getTarget();
+        final Match match = matchAction.getMatch();
+        if (match instanceof Ipv4Match) {
+            pushIpEntry(matchActionOp);
+        } else if (match instanceof MplsMatch) {
+            pushMplsEntry(matchActionOp);
+        } else if (match instanceof PacketMatch) {
+            pushAclEntry(matchActionOp);
+        } else {
+            log.error("Unknown match type {} pushed to switch {}", match,
+                    getStringId());
+        }
+    }
+
+    @Override
+    public void pushFlows(Collection<MatchActionOperationEntry> matchActionOps)
+            throws IOException {
+        for (MatchActionOperationEntry matchActionOp : matchActionOps) {
+            pushFlow(matchActionOp);
+        }
+    }
+
+    @Override
+    public int getEcmpGroupId(NeighborSet ns) {
+        EcmpInfo ei = ecmpGroups.get(ns);
+        if (ei == null) {
+            return -1;
+        } else {
+            return ei.groupId;
+        }
+    }
+
+    // *****************************
+    // Old Hardcoded Stuff
+    // *****************************
+
     private void configureSwitch() throws IOException {
         // setAsyncConfig();
         // getTableFeatures();
         sendGroupFeaturesRequest();
         setL2Groups();
-        sendBarrier(false);
+        sendBarrier();
         setL3Groups();
         setL25Groups();
-        setEcmpGroup();
+        // setEcmpGroup();
         sendGroupDescRequest();
         populateTableVlan();
         populateTableTMac();
         populateIpTable();
         populateMplsTable();
         populateTableMissEntry(TABLE_ACL, false, false, false, -1);
-        sendBarrier(true);
+        sendBarrier();
     }
 
     private void setAsyncConfig() throws IOException {
@@ -271,12 +1016,6 @@
         write(gfr, null);
     }
 
-    private void sendGroupDescRequest() throws IOException {
-        OFMessage gdr = factory.buildGroupDescStatsRequest()
-                .setXid(getNextTransactionId())
-                .build();
-        write(gdr, null);
-    }
 
     /*Create L2 interface groups for all physical ports
      Naming convention followed is the same as OF-DPA spec
@@ -324,14 +1063,6 @@
         return portVlan;
     }
 
-    private MacAddress getRouterMacAddr() {
-        if (getId() == 0x3)
-            return MacAddress.of("00:00:07:07:07:80"); // router mac
-        if (getId() == 0x1)
-            return MacAddress.of("00:00:01:01:01:80");
-        // switch 0x2
-        return MacAddress.of("00:00:02:02:02:80");
-    }
 
     // only for ports connected to other routers
     private OFAction getDestAction(int portnum) {
@@ -469,181 +1200,12 @@
         log.debug("Creating {} MPLS groups in sw {}", msglist.size(), getStringId());
     }
 
-    private void setEcmpGroup() throws IOException {
-        if (getId() != 0x1)
-            return;
-        List<OFMessage> msglist = new ArrayList<OFMessage>();
-        OFGroup group47 = OFGroup.of(47);
-
-        OFAction outg1 = factory.actions().buildGroup()
-                .setGroup(OFGroup.of(0xa0000000 | // mpls group id
-                        6))
-                .build();
-        OFBucket buc47_1 = factory.buildBucket()
-                .setWeight(1)
-                .setActions(Collections.singletonList(outg1))
-                .build();
-
-        OFAction outg2 = factory.actions().buildGroup()
-                .setGroup(OFGroup.of(0xa0000000 | // mpls group id
-                        7))
-                .build();
-        OFBucket buc47_2 = factory.buildBucket()
-                .setWeight(1)
-                .setActions(Collections.singletonList(outg2))
-                .build();
-
-        List<OFBucket> buckets47 = new ArrayList<OFBucket>();
-        buckets47.add(buc47_1);
-        buckets47.add(buc47_2);
-        OFMessage gmS12 = factory.buildGroupAdd()
-                .setGroup(group47)
-                .setBuckets(buckets47)
-                .setGroupType(OFGroupType.SELECT)
-                .setXid(getNextTransactionId())
-                .build();
-        msglist.add(gmS12);
-        write(msglist);
-        log.debug("Creating {} ECMP groups in sw {}", msglist.size(), getStringId());
-    }
-
-    private void processStatsReply(OFStatsReply sr) {
-        switch (sr.getStatsType()) {
-        case AGGREGATE:
-            break;
-        case DESC:
-            break;
-        case EXPERIMENTER:
-            break;
-        case FLOW:
-            break;
-        case GROUP_DESC:
-            processGroupDesc((OFGroupDescStatsReply) sr);
-            break;
-        case GROUP_FEATURES:
-            processGroupFeatures((OFGroupFeaturesStatsReply) sr);
-            break;
-        case METER_CONFIG:
-            break;
-        case METER_FEATURES:
-            break;
-        case PORT_DESC:
-            break;
-        case TABLE_FEATURES:
-            break;
-        default:
-            break;
-
-        }
-    }
 
     private void processGroupFeatures(OFGroupFeaturesStatsReply gfsr) {
         log.info("Sw: {} Group Features {}", getStringId(), gfsr);
     }
 
-    private void processGroupDesc(OFGroupDescStatsReply gdsr) {
-        log.info("Sw: {} Group Desc {}", getStringId(), gdsr);
-    }
 
-    private void populateTableVlan() throws IOException {
-        // for all incoming ports assign configured port-vlans
-        // currently assign portnum*10 -> vlanid to access ports
-        // and vlan 192 to router to router ports
-        List<OFMessage> msglist = new ArrayList<OFMessage>();
-        for (OFPortDesc p : getPorts()) {
-            int pnum = p.getPortNo().getPortNumber();
-            if (U32.of(pnum).compareTo(U32.of(OFPort.MAX.getPortNumber())) < 1) {
-                int vlanid = getVlanConfig(pnum);
-                OFOxmInPort oxp = factory.oxms().inPort(p.getPortNo());
-                OFOxmVlanVid oxv = factory.oxms()
-                        .vlanVid(OFVlanVidMatch.UNTAGGED);
-                OFOxmList oxmList = OFOxmList.of(oxp, oxv);
-                OFMatchV3 match = factory.buildMatchV3()
-                        .setOxmList(oxmList).build();
-                OFOxmVlanVid vidToSet = factory.oxms()
-                        .vlanVid(OFVlanVidMatch.ofVlan(vlanid));
-                OFAction pushVlan = factory.actions().pushVlan(EthType.VLAN_FRAME);
-                OFAction setVlan = factory.actions().setField(vidToSet);
-                List<OFAction> actionlist = new ArrayList<OFAction>();
-                actionlist.add(pushVlan);
-                actionlist.add(setVlan);
-                OFInstruction appAction = factory.instructions().buildApplyActions()
-                        .setActions(actionlist).build();
-                OFInstruction gotoTbl = factory.instructions().buildGotoTable()
-                        .setTableId(TableId.of(TABLE_TMAC)).build();
-                List<OFInstruction> instructions = new ArrayList<OFInstruction>();
-                // instructions.add(appAction);
-                instructions.add(gotoTbl);
-                OFMessage flowEntry = factory.buildFlowAdd()
-                        .setTableId(TableId.of(TABLE_VLAN))
-                        .setMatch(match)
-                        .setInstructions(instructions)
-                        .setPriority(1000) // does not matter - all rules
-                                           // exclusive
-                        .setBufferId(OFBufferId.NO_BUFFER)
-                        .setIdleTimeout(0)
-                        .setHardTimeout(0)
-                        .setXid(getNextTransactionId())
-                        .build();
-                msglist.add(flowEntry);
-            }
-        }
-        // table-vlan has no table-miss entry, and so packets that miss are
-        // essentially dropped
-        write(msglist);
-        log.debug("Adding {} vlan-rules in sw {}", msglist.size(), getStringId());
-    }
-
-    private void populateTableTMac() throws IOException {
-        // match for ip packets
-        OFOxmEthType oxe = factory.oxms().ethType(EthType.IPv4);
-        OFOxmList oxmListIp = OFOxmList.of(oxe);
-        OFMatchV3 matchIp = factory.buildMatchV3()
-                .setOxmList(oxmListIp).build();
-        OFInstruction gotoTblIp = factory.instructions().buildGotoTable()
-                .setTableId(TableId.of(TABLE_IPv4_UNICAST)).build();
-        List<OFInstruction> instructionsIp = Collections.singletonList(gotoTblIp);
-        OFMessage ipEntry = factory.buildFlowAdd()
-                .setTableId(TableId.of(TABLE_TMAC))
-                .setMatch(matchIp)
-                .setInstructions(instructionsIp)
-                .setPriority(1000) // strict priority required lower than
-                                   // multicastMac
-                .setBufferId(OFBufferId.NO_BUFFER)
-                .setIdleTimeout(0)
-                .setHardTimeout(0)
-                .setXid(getNextTransactionId())
-                .build();
-
-        // match for mpls packets
-        OFOxmEthType oxmpls = factory.oxms().ethType(EthType.MPLS_UNICAST);
-        OFOxmList oxmListMpls = OFOxmList.of(oxmpls);
-        OFMatchV3 matchMpls = factory.buildMatchV3()
-                .setOxmList(oxmListMpls).build();
-        OFInstruction gotoTblMpls = factory.instructions().buildGotoTable()
-                .setTableId(TableId.of(TABLE_MPLS)).build();
-        List<OFInstruction> instructionsMpls = Collections.singletonList(gotoTblMpls);
-        OFMessage mplsEntry = factory.buildFlowAdd()
-                .setTableId(TableId.of(TABLE_TMAC))
-                .setMatch(matchMpls)
-                .setInstructions(instructionsMpls)
-                .setPriority(1001) // strict priority required lower than
-                                   // multicastMac
-                .setBufferId(OFBufferId.NO_BUFFER)
-                .setIdleTimeout(0)
-                .setHardTimeout(0)
-                .setXid(getNextTransactionId())
-                .build();
-
-        // match for everything else to send to controller. Essentially
-        // the table miss flow entry
-        populateTableMissEntry(TABLE_TMAC, true, false, false, -1);
-        log.debug("Adding termination-mac-rules in sw {}", getStringId());
-        List<OFMessage> msglist = new ArrayList<OFMessage>(2);
-        msglist.add(ipEntry);
-        msglist.add(mplsEntry);
-        write(msglist);
-    }
 
     private List<String> getMyIps() { // send to controller
         List<String> myIps = new ArrayList<String>();
@@ -828,7 +1390,7 @@
                     .setTableId(TableId.of(TABLE_IPv4_UNICAST))
                     .setMatch(match)
                     .setInstructions(instructions)
-                    .setPriority(SLASH_24_PRIORITY)
+                    .setPriority((short) 0xfff0)
                     .setBufferId(OFBufferId.NO_BUFFER)
                     .setIdleTimeout(0)
                     .setHardTimeout(0)
@@ -918,7 +1480,7 @@
             if (routerNextHopIps.get(i).mask.equals("255.255.255.255"))
                 priority = MAX_PRIORITY;
             else
-                priority = SLASH_24_PRIORITY;
+                priority = (short) 0xfff0;
             OFMessage myIpEntry = factory.buildFlowAdd()
                     .setTableId(TableId.of(TABLE_IPv4_UNICAST))
                     .setMatch(match)
@@ -1133,90 +1695,5 @@
 
     }
 
-    /**
-     * By default if none of the booleans in the call are set, then the
-     * table-miss entry is added with no instructions, which means that pipeline
-     * execution will stop, and the action set associated with the packet will
-     * be executed.
-     *
-     * @param tableToAdd
-     * @param toControllerNow as an APPLY_ACTION instruction
-     * @param toControllerWrite as a WRITE_ACITION instruction
-     * @param toTable as a GOTO_TABLE instruction
-     * @param tableToSend
-     * @throws IOException
-     */
-    @SuppressWarnings("unchecked")
-    private void populateTableMissEntry(int tableToAdd, boolean toControllerNow,
-            boolean toControllerWrite,
-            boolean toTable, int tableToSend) throws IOException {
-        OFOxmList oxmList = OFOxmList.EMPTY;
-        OFMatchV3 match = factory.buildMatchV3()
-                .setOxmList(oxmList)
-                .build();
-        OFAction outc = factory.actions()
-                .buildOutput()
-                .setPort(OFPort.CONTROLLER)
-                .setMaxLen(OFPCML_NO_BUFFER)
-                .build();
-        List<OFInstruction> instructions = new ArrayList<OFInstruction>();
-        if (toControllerNow) {
-            // table-miss instruction to send to controller immediately
-            OFInstruction instr = factory.instructions()
-                    .buildApplyActions()
-                    .setActions(Collections.singletonList(outc))
-                    .build();
-            instructions.add(instr);
-        }
-
-        if (toControllerWrite) {
-            // table-miss instruction to write-action to send to controller
-            // this will be executed whenever the action-set gets executed
-            OFInstruction instr = factory.instructions()
-                    .buildWriteActions()
-                    .setActions(Collections.singletonList(outc))
-                    .build();
-            instructions.add(instr);
-        }
-
-        if (toTable) {
-            // table-miss instruction to goto-table x
-            OFInstruction instr = factory.instructions()
-                    .gotoTable(TableId.of(tableToSend));
-            instructions.add(instr);
-        }
-
-        if (!toControllerNow && !toControllerWrite && !toTable) {
-            // table-miss has no instruction - at which point action-set will be
-            // executed - if there is an action to output/group in the action
-            // set
-            // the packet will be sent there, otherwise it will be dropped.
-            instructions = (List<OFInstruction>) Collections.EMPTY_LIST;
-        }
-
-        OFMessage tableMissEntry = factory.buildFlowAdd()
-                .setTableId(TableId.of(tableToAdd))
-                .setMatch(match) // match everything
-                .setInstructions(instructions)
-                .setPriority(MIN_PRIORITY)
-                .setBufferId(OFBufferId.NO_BUFFER)
-                .setIdleTimeout(0)
-                .setHardTimeout(0)
-                .setXid(getNextTransactionId())
-                .build();
-        write(tableMissEntry, null);
-    }
-
-    private void sendBarrier(boolean finalBarrier) throws IOException {
-        int xid = getNextTransactionId();
-        if (finalBarrier) {
-            barrierXidToWaitFor = xid;
-        }
-        OFBarrierRequest br = factory
-                .buildBarrierRequest()
-                .setXid(xid)
-                .build();
-        write(br, null);
-    }
 
 }
diff --git a/src/main/java/net/onrc/onos/core/matchaction/match/Ipv4PacketMatch.java b/src/main/java/net/onrc/onos/core/matchaction/match/Ipv4PacketMatch.java
deleted file mode 100644
index 7182ca1..0000000
--- a/src/main/java/net/onrc/onos/core/matchaction/match/Ipv4PacketMatch.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package net.onrc.onos.core.matchaction.match;
-
-import net.onrc.onos.core.util.IPv4Net;
-
-public class Ipv4PacketMatch implements Match {
-
-    IPv4Net dstIp;
-
-    public Ipv4PacketMatch(String ipAddressSlash) {
-        this.dstIp = new IPv4Net(ipAddressSlash);
-    }
-
-    public IPv4Net getDestination() {
-        return dstIp;
-    }
-
-}
