diff --git a/src/main/java/net/onrc/onos/api/registry/ILocalSwitchMastershipListener.java b/src/main/java/net/onrc/onos/api/registry/ILocalSwitchMastershipListener.java
deleted file mode 100644
index 2445b76..0000000
--- a/src/main/java/net/onrc/onos/api/registry/ILocalSwitchMastershipListener.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package net.onrc.onos.api.registry;
-
-// TODO: The "Role" enums should be moved to this file
-import net.floodlightcontroller.core.IFloodlightProviderService.Role;
-import net.onrc.onos.core.util.Dpid;
-
-/**
- * Switch mastership listener interface for controller role changes for
- * local switches.
- * <p/>
- * The interface can be used to track only switches that are connected
- * to this ONOS instance.
- */
-public interface ILocalSwitchMastershipListener {
-    /**
-     * The role of this controller has changed for a switch.
-     * <p/>
-     * This is the method that is called when the switch connects to the
-     * controller, and when the role of the controller has changed.
-     *
-     * @param dpid the DPID of the switch.
-     * @param role the new role of this controller for the switch.
-     */
-    void controllerRoleChanged(Dpid dpid, Role role);
-
-    /**
-     * The switch has disconnected, and it is not tracked anymore.
-     *
-     * @param dpid the DPID of the switch.
-     */
-    void switchDisconnected(Dpid dpid);
-}
diff --git a/src/main/java/net/onrc/onos/apps/sdnip/FlowCache.java b/src/main/java/net/onrc/onos/apps/sdnip/FlowCache.java
index 8c518d7..dc9182c 100644
--- a/src/main/java/net/onrc/onos/apps/sdnip/FlowCache.java
+++ b/src/main/java/net/onrc/onos/apps/sdnip/FlowCache.java
@@ -1,6 +1,5 @@
 package net.onrc.onos.apps.sdnip;
 
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
@@ -14,7 +13,6 @@
 import org.openflow.protocol.OFFlowMod;
 import org.openflow.protocol.OFMessage;
 import org.openflow.protocol.OFPort;
-import org.openflow.util.HexString;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -27,19 +25,19 @@
 
     private final Comparator<OFFlowMod> cookieComparator =
             new Comparator<OFFlowMod>() {
-        @Override
-        public int compare(OFFlowMod fm1, OFFlowMod fm2) {
-            long difference = fm2.getCookie() - fm1.getCookie();
+                @Override
+                public int compare(OFFlowMod fm1, OFFlowMod fm2) {
+                    long difference = fm2.getCookie() - fm1.getCookie();
 
-            if (difference > 0) {
-                return 1;
-            } else if (difference < 0) {
-                return -1;
-            } else {
-                return 0;
-            }
-        }
-    };
+                    if (difference > 0) {
+                        return 1;
+                    } else if (difference < 0) {
+                        return -1;
+                    } else {
+                        return 0;
+                    }
+                }
+            };
 
     public FlowCache(IFloodlightProviderService floodlightProvider) {
         this.floodlightProvider = floodlightProvider;
@@ -83,11 +81,12 @@
             List<OFMessage> msgList = new ArrayList<OFMessage>(clones.size());
             msgList.addAll(clones);
 
-            try {
+            // XXX S commenting out the old message writes
+            /*try {
                 sw.write(msgList, null);
             } catch (IOException e) {
                 log.error("Error writing to switch", e);
-            }
+            }*/
         }
     }
 
@@ -124,11 +123,12 @@
             List<OFMessage> msgList = new ArrayList<OFMessage>(flowMods.size());
             msgList.addAll(flowMods);
 
-            try {
-                sw.write(msgList, null);
+            // XXX S commenting out old message writes
+            /*try {
+            sw.write(msgList, null);
             } catch (IOException e) {
                 log.error("Error writing to switch", e);
-            }
+            }*/
         }
     }
 
@@ -147,12 +147,14 @@
             List<OFMessage> messages = new ArrayList<OFMessage>(flowMods.size());
             messages.addAll(flowMods);
 
-            try {
-                sw.write(messages, null);
-            } catch (IOException e) {
-                log.error("Failure writing flow mods to switch {}",
-                        HexString.toHexString(sw.getId()));
-            }
+            // XXX S commenting out old message writes
+            /*            try {
+                        sw.write(messages, null);
+                        } catch (IOException e) {
+                            log.error("Failure writing flow mods to switch {}",
+                                    HexString.toHexString(sw.getId()));
+                        }
+            */
         }
     }
 
diff --git a/src/main/java/net/onrc/onos/apps/sdnip/SdnIp.java b/src/main/java/net/onrc/onos/apps/sdnip/SdnIp.java
index f4bf28d..135d0a7 100644
--- a/src/main/java/net/onrc/onos/apps/sdnip/SdnIp.java
+++ b/src/main/java/net/onrc/onos/apps/sdnip/SdnIp.java
@@ -17,6 +17,7 @@
 
 import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.core.IOFSwitch.PortChangeType;
 import net.floodlightcontroller.core.IOFSwitchListener;
 import net.floodlightcontroller.core.module.FloodlightModuleContext;
 import net.floodlightcontroller.core.module.FloodlightModuleException;
@@ -68,6 +69,7 @@
 import org.openflow.protocol.action.OFAction;
 import org.openflow.protocol.action.OFActionOutput;
 import org.openflow.util.HexString;
+import org.projectfloodlight.openflow.protocol.OFPortDesc;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -83,8 +85,7 @@
 import com.googlecode.concurrenttrees.radixinverted.InvertedRadixTree;
 
 public class SdnIp implements IFloodlightModule, ISdnIpService,
-        IArpRequester,
-        IOFSwitchListener, IConfigInfoService {
+        IArpRequester, IOFSwitchListener, IConfigInfoService {
 
     private static final Logger log = LoggerFactory.getLogger(SdnIp.class);
     private final CallerId callerId = new CallerId("SDNIP");
@@ -146,7 +147,7 @@
     // True when we have a full mesh of shortest paths between gateways
     private volatile boolean topologyReady = false;
 
-    //private SingletonTask topologyChangeDetectorTask;
+    // private SingletonTask topologyChangeDetectorTask;
 
     private SetMultimap<InetAddress, RibUpdate> prefixesWaitingOnArp;
 
@@ -156,7 +157,7 @@
 
     private Map<InetAddress, Path> pushedPaths;
     private Map<Prefix, Path> prefixToPath;
-    //  private Multimap<Prefix, PushedFlowMod> pushedFlows;
+    // private Multimap<Prefix, PushedFlowMod> pushedFlows;
     private Multimap<Prefix, FlowId> pushedFlowIds;
 
     private FlowCache flowCache;
@@ -245,8 +246,7 @@
 
     @Override
     public Collection<Class<? extends IFloodlightService>> getModuleServices() {
-        Collection<Class<? extends IFloodlightService>> l
-                = new ArrayList<>();
+        Collection<Class<? extends IFloodlightService>> l = new ArrayList<>();
         l.add(ISdnIpService.class);
         l.add(IConfigInfoService.class);
         return l;
@@ -254,8 +254,7 @@
 
     @Override
     public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
-        Map<Class<? extends IFloodlightService>, IFloodlightService> m
-                = new HashMap<>();
+        Map<Class<? extends IFloodlightService>, IFloodlightService> m = new HashMap<>();
         m.put(ISdnIpService.class, this);
         m.put(IConfigInfoService.class, this);
         return m;
@@ -263,8 +262,7 @@
 
     @Override
     public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
-        Collection<Class<? extends IFloodlightService>> l
-                = new ArrayList<>();
+        Collection<Class<? extends IFloodlightService>> l = new ArrayList<>();
         l.add(IFloodlightProviderService.class);
         l.add(IRestApiService.class);
         l.add(IControllerRegistryService.class);
@@ -289,11 +287,14 @@
         restApi = context.getServiceImpl(IRestApiService.class);
         proxyArp = context.getServiceImpl(IProxyArpService.class);
 
-        controllerRegistryService = context.getServiceImpl(IControllerRegistryService.class);
+        controllerRegistryService = context
+                .getServiceImpl(IControllerRegistryService.class);
         pathRuntime = context.getServiceImpl(IPathCalcRuntimeService.class);
 
-        //ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
-        //topologyChangeDetectorTask = new SingletonTask(executor, new TopologyChangeDetector());
+        // ScheduledExecutorService executor =
+        // Executors.newScheduledThreadPool(1);
+        // topologyChangeDetectorTask = new SingletonTask(executor, new
+        // TopologyChangeDetector());
 
         pathsWaitingOnArp = new HashMap<>();
         prefixesWaitingOnArp = Multimaps.synchronizedSetMultimap(
@@ -301,7 +302,7 @@
 
         pushedPaths = new HashMap<>();
         prefixToPath = new HashMap<>();
-//              pushedFlows = HashMultimap.<Prefix, PushedFlowMod>create();
+        // pushedFlows = HashMultimap.<Prefix, PushedFlowMod>create();
         pushedFlowIds = HashMultimap.create();
 
         flowCache = new FlowCache(floodlightProvider);
@@ -439,8 +440,10 @@
             RibEntry rib = bgpRoutes.put(prefix.toBinaryString(), update.getRibEntry());
 
             if (rib != null && !rib.equals(update.getRibEntry())) {
-                // There was an existing nexthop for this prefix. This update supersedes that,
-                // so we need to remove the old flows for this prefix from the switches
+                // There was an existing nexthop for this prefix. This update
+                // supersedes that,
+                // so we need to remove the old flows for this prefix from the
+                // switches
                 executeDeletePrefix(prefix, rib);
             }
 
@@ -527,11 +530,11 @@
     }
 
     /**
-     * Add a flow to match dst-IP prefix and rewrite MAC for one IP prefix
-     * to all other border switches.
+     * Add a flow to match dst-IP prefix and rewrite MAC for one IP prefix to
+     * all other border switches.
      */
     private void addPrefixFlows(Prefix prefix, Interface egressInterface,
-                                MACAddress nextHopMacAddress) {
+            MACAddress nextHopMacAddress) {
         log.debug("Adding flows for prefix {}, next hop mac {}",
                 prefix, nextHopMacAddress);
 
@@ -550,10 +553,11 @@
 
         // Create the DataPath object: dstSwitchPort
         SwitchPort dstPort =
-            new SwitchPort(new Dpid(egressInterface.getDpid()),
-                           new PortNumber(egressInterface.getPort()));
+                new SwitchPort(new Dpid(egressInterface.getDpid()),
+                        new PortNumber(egressInterface.getPort()));
 
-        // We only need one flow mod per switch, so pick one interface on each switch
+        // We only need one flow mod per switch, so pick one interface on each
+        // switch
         Map<Long, Interface> srcInterfaces = new HashMap<>();
         for (Interface intf : interfaces.values()) {
             if (!srcInterfaces.containsKey(intf.getDpid())
@@ -572,8 +576,8 @@
 
             // Create DataPath object: srcSwitchPort
             SwitchPort srcPort =
-                new SwitchPort(new Dpid(srcInterface.getDpid()),
-                               new PortNumber(srcInterface.getPort()));
+                    new SwitchPort(new Dpid(srcInterface.getDpid()),
+                            new PortNumber(srcInterface.getPort()));
 
             DataPath dataPath = new DataPath();
             dataPath.setSrcPort(srcPort);
@@ -620,9 +624,11 @@
         synchronized (this) {
             Prefix prefix = update.getPrefix();
 
-            //if (ptree.remove(prefix, update.getRibEntry())) {
-            // TODO check the change of logic here - remove doesn't check that the
-            // rib entry was what we expected (and we can't do this concurrently)
+            // if (ptree.remove(prefix, update.getRibEntry())) {
+            // TODO check the change of logic here - remove doesn't check that
+            // the
+            // rib entry was what we expected (and we can't do this
+            // concurrently)
             if (bgpRoutes.remove(prefix.toBinaryString())) {
                 /*
                  * Only delete flows if an entry was actually removed from the tree.
@@ -644,8 +650,8 @@
             Path path = prefixToPath.remove(prefix);
 
             if (path != null) {
-                //path could be null if we added to the Ptree but didn't push
-                //flows yet because we were waiting to resolve ARP
+                // path could be null if we added to the Ptree but didn't push
+                // flows yet because we were waiting to resolve ARP
 
                 path.decrementUsers();
                 if (path.getUsers() <= 0 && !path.isPermanent()) {
@@ -707,9 +713,8 @@
         }*/
     }
 
-
-    //TODO test next-hop changes
-    //TODO check delete/add synchronization
+    // TODO test next-hop changes
+    // TODO check delete/add synchronization
 
     /**
      * On startup, we need to calculate a full mesh of paths between all gateway
@@ -778,15 +783,16 @@
         flowPath.setFlowPathType(FlowPathType.FP_TYPE_SHORTEST_PATH);
         flowPath.setFlowPathUserState(FlowPathUserState.FP_USER_ADD);
 
-        // Insert the dest-mac based forwarding flow entry to the non-first-hop switches
+        // Insert the dest-mac based forwarding flow entry to the non-first-hop
+        // switches
         FlowPathFlags flowPathFlags = new FlowPathFlags();
         flowPathFlags.setFlags(FlowPathFlags.DISCARD_FIRST_HOP_ENTRY);
         flowPath.setFlowPathFlags(flowPathFlags);
 
         // Create the DataPath object: dstSwitchPort
         SwitchPort dstPort =
-            new SwitchPort(new Dpid(dstInterface.getDpid()),
-                           new PortNumber(dstInterface.getPort()));
+                new SwitchPort(new Dpid(dstInterface.getDpid()),
+                        new PortNumber(dstInterface.getPort()));
 
         for (Interface srcInterface : interfaces.values()) {
 
@@ -799,8 +805,8 @@
 
             // Create the DataPath object: srcSwitchPort
             SwitchPort srcPort =
-                new SwitchPort(new Dpid(srcInterface.getDpid()),
-                               new PortNumber(srcInterface.getPort()));
+                    new SwitchPort(new Dpid(srcInterface.getDpid()),
+                            new PortNumber(srcInterface.getPort()));
 
             DataPath dataPath = new DataPath();
             dataPath.setSrcPort(srcPort);
@@ -814,7 +820,8 @@
             flowPath.setFlowEntryMatch(flowEntryMatch);
 
             // NOTE: No need to add ACTION_OUTPUT. It is implied when creating
-            // Shortest Path Flow, and is always the last action for the Flow Entries
+            // Shortest Path Flow, and is always the last action for the Flow
+            // Entries
             log.debug("FlowPath of MAC based forwarding: {}", flowPath.toString());
             // TODO: Add the flow by using the new Path Intent framework
             /*
@@ -832,11 +839,11 @@
 
     @Override
     public void beginRoutingNew() {
-            setupBgpPathsNew();
+        setupBgpPathsNew();
 
-        //setupFullMesh();
+        // setupFullMesh();
 
-        //Suppress link discovery on external-facing router ports
+        // Suppress link discovery on external-facing router ports
 
         for (Interface intf : interfaces.values()) {
             linkDiscoveryService.disableDiscoveryOnPort(intf.getDpid(), intf.getPort());
@@ -851,37 +858,39 @@
     }
 
     /**
-     * Setup the Paths to the BGP Daemon.
-     *
-     * Run a loop for all of the bgpPeers
-     * Push flow from BGPd to the peer
-     * Push flow from peer to BGPd
-     * Parameters to pass to the intent are as follows:
-     *     String id,
-     *     long srcSwitch, long srcPort, long srcMac, int srcIP,
-     *     long dstSwitch, long dstPort, long dstMac, int dstIP
+     * Setup the Paths to the BGP Daemon. Run a loop for all of the bgpPeers
+     * Push flow from BGPd to the peer Push flow from peer to BGPd Parameters to
+     * pass to the intent are as follows: String id, long srcSwitch, long
+     * srcPort, long srcMac, int srcIP, long dstSwitch, long dstPort, long
+     * dstMac, int dstIP
      */
     private void setupBgpPathsNew() {
         IntentOperationList operations = new IntentOperationList();
         for (BgpPeer bgpPeer : bgpPeers.values()) {
             Interface peerInterface = interfaces.get(bgpPeer.getInterfaceName());
-            //Inet4Address.
+            // Inet4Address.
             int srcIP = InetAddresses.coerceToInteger(peerInterface.getIpAddress());
             int dstIP = InetAddresses.coerceToInteger(bgpPeer.getIpAddress());
-            String fwdIntentId = caller + ":" + controllerRegistryService.getNextUniqueId();
-            String bwdIntentId = caller + ":" + controllerRegistryService.getNextUniqueId();
+            String fwdIntentId = caller + ":"
+                    + controllerRegistryService.getNextUniqueId();
+            String bwdIntentId = caller + ":"
+                    + controllerRegistryService.getNextUniqueId();
             SwitchPort srcPort =
-                new SwitchPort(bgpdAttachmentPoint.dpid(),
-                               bgpdAttachmentPoint.port());
+                    new SwitchPort(bgpdAttachmentPoint.dpid(),
+                            bgpdAttachmentPoint.port());
             SwitchPort dstPort =
-                new SwitchPort(new Dpid(peerInterface.getDpid()),
-                               new PortNumber(peerInterface.getSwitchPort().port()));
+                    new SwitchPort(new Dpid(peerInterface.getDpid()),
+                            new PortNumber(peerInterface.getSwitchPort().port()));
             ShortestPathIntent fwdIntent = new ShortestPathIntent(fwdIntentId,
-                    srcPort.dpid().value(), srcPort.port().value(), ShortestPathIntent.EMPTYMACADDRESS, srcIP,
-                    dstPort.dpid().value(), dstPort.port().value(), ShortestPathIntent.EMPTYMACADDRESS, dstIP);
+                    srcPort.dpid().value(), srcPort.port().value(),
+                    ShortestPathIntent.EMPTYMACADDRESS, srcIP,
+                    dstPort.dpid().value(), dstPort.port().value(),
+                    ShortestPathIntent.EMPTYMACADDRESS, dstIP);
             ShortestPathIntent bwdIntent = new ShortestPathIntent(bwdIntentId,
-                    dstPort.dpid().value(), dstPort.port().value(), ShortestPathIntent.EMPTYMACADDRESS, dstIP,
-                    srcPort.dpid().value(), srcPort.port().value(), ShortestPathIntent.EMPTYMACADDRESS, srcIP);
+                    dstPort.dpid().value(), dstPort.port().value(),
+                    ShortestPathIntent.EMPTYMACADDRESS, dstIP,
+                    srcPort.dpid().value(), srcPort.port().value(),
+                    ShortestPathIntent.EMPTYMACADDRESS, srcIP);
             IntentOperation.Operator operator = IntentOperation.Operator.ADD;
             operations.add(operator, fwdIntent);
             operations.add(operator, bwdIntent);
@@ -914,11 +923,13 @@
             flowEntryMatch.enableEthernetFrameType(Ethernet.TYPE_IPV4);
 
             // Match both source address and dest address
-            IPv4Net dstIPv4Net = new IPv4Net(bgpPeer.getIpAddress().getHostAddress() + "/32");
+            IPv4Net dstIPv4Net = new IPv4Net(bgpPeer.getIpAddress().getHostAddress()
+                    + "/32");
 
             flowEntryMatch.enableDstIPv4Net(dstIPv4Net);
 
-            IPv4Net srcIPv4Net = new IPv4Net(peerInterface.getIpAddress().getHostAddress() + "/32");
+            IPv4Net srcIPv4Net = new IPv4Net(peerInterface.getIpAddress()
+                    .getHostAddress() + "/32");
             flowEntryMatch.enableSrcIPv4Net(srcIPv4Net);
 
             // Match TCP protocol
@@ -935,13 +946,13 @@
             DataPath dataPath = new DataPath();
 
             SwitchPort srcPort =
-                new SwitchPort(bgpdAttachmentPoint.dpid(),
-                               bgpdAttachmentPoint.port());
+                    new SwitchPort(bgpdAttachmentPoint.dpid(),
+                            bgpdAttachmentPoint.port());
             dataPath.setSrcPort(srcPort);
 
             SwitchPort dstPort =
-                new SwitchPort(new Dpid(peerInterface.getDpid()),
-                               new PortNumber(peerInterface.getSwitchPort().port()));
+                    new SwitchPort(new Dpid(peerInterface.getDpid()),
+                            new PortNumber(peerInterface.getSwitchPort().port()));
             dataPath.setDstPort(dstPort);
 
             flowPath.setDataPath(dataPath);
@@ -1070,13 +1081,10 @@
 
             // match ICMP protocol BGP -> Peer
             flowPath.setFlowId(new FlowId());
-
             flowEntryMatch.enableDstIPv4Net(dstIPv4Net);
             flowEntryMatch.enableSrcIPv4Net(srcIPv4Net);
             flowPath.setFlowEntryMatch(flowEntryMatch);
-
             flowPath.setDataPath(dataPath);
-
             log.debug("ICMP flowPath: {}", flowPath.toString());
 
             // TODO: Add the flow by using the new Path Intent framework
@@ -1111,11 +1119,14 @@
                 log.debug("Pushing path to {} at {} on {}",
                         path.getDstIpAddress().getHostAddress(), macAddress,
                         path.getDstInterface().getSwitchPort());
-                // These paths should always be to BGP peers. Paths to non-peers are
+                // These paths should always be to BGP peers. Paths to non-peers
+                // are
                 // handled once the first prefix is ready to push
                 if (pushedPaths.containsKey(path.getDstIpAddress())) {
-                    // A path already got pushed to this endpoint while we were waiting
-                    // for ARP. We'll copy over the permanent attribute if it is set on this path.
+                    // A path already got pushed to this endpoint while we were
+                    // waiting
+                    // for ARP. We'll copy over the permanent attribute if it is
+                    // set on this path.
                     if (path.isPermanent()) {
                         pushedPaths.get(path.getDstIpAddress()).setPermanent();
                     }
@@ -1135,9 +1146,12 @@
                 if (rib != null && rib.equals(update.getRibEntry())) {
                     log.debug("Pushing prefix {} next hop {}", update.getPrefix(),
                             rib.getNextHop().getHostAddress());
-                    // We only push prefix flows if the prefix is still in the ptree
-                    // and the next hop is the same as our update. The prefix could
-                    // have been removed while we were waiting for the ARP, or the
+                    // We only push prefix flows if the prefix is still in the
+                    // ptree
+                    // and the next hop is the same as our update. The prefix
+                    // could
+                    // have been removed while we were waiting for the ARP, or
+                    // the
                     // next hop could have changed.
                     executeRibAdd(update);
                 } else {
@@ -1247,7 +1261,7 @@
         setupBgpPaths();
         setupFullMesh();
 
-        //Suppress link discovery on external-facing router ports
+        // Suppress link discovery on external-facing router ports
         for (Interface intf : interfaces.values()) {
             linkDiscoveryService.disableDiscoveryOnPort(intf.getDpid(), intf.getPort());
         }
@@ -1285,7 +1299,8 @@
         */
     }
 
-    // Actually we only need to go half way round to verify full mesh connectivity
+    // Actually we only need to go half way round to verify full mesh
+    // connectivity
     private void checkTopologyReady() {
         for (Interface dstInterface : interfaces.values()) {
             for (Interface srcInterface : interfaces.values()) {
@@ -1329,25 +1344,25 @@
                 try {
                     RibUpdate update = ribUpdates.take();
                     switch (update.getOperation()) {
-                        case UPDATE:
-                            if (validateUpdate(update)) {
-                                processRibAdd(update);
-                            } else {
-                                log.debug("Rib UPDATE out of order: {} via {}",
-                                        update.getPrefix(), update.getRibEntry().getNextHop());
-                            }
-                            break;
-                        case DELETE:
-                            if (validateUpdate(update)) {
-                                processRibDelete(update);
-                            } else {
-                                log.debug("Rib DELETE out of order: {} via {}",
-                                        update.getPrefix(), update.getRibEntry().getNextHop());
-                            }
-                            break;
-                        default:
-                            log.error("Unknown operation {}", update.getOperation());
-                            break;
+                    case UPDATE:
+                        if (validateUpdate(update)) {
+                            processRibAdd(update);
+                        } else {
+                            log.debug("Rib UPDATE out of order: {} via {}",
+                                    update.getPrefix(), update.getRibEntry().getNextHop());
+                        }
+                        break;
+                    case DELETE:
+                        if (validateUpdate(update)) {
+                            processRibDelete(update);
+                        } else {
+                            log.debug("Rib DELETE out of order: {} via {}",
+                                    update.getPrefix(), update.getRibEntry().getNextHop());
+                        }
+                        break;
+                    default:
+                        log.error("Unknown operation {}", update.getOperation());
+                        break;
                     }
                 } catch (InterruptedException e) {
                     log.debug("Interrupted while taking from updates queue", e);
@@ -1368,10 +1383,11 @@
         RibEntry oldEntry = bgpRoutes.getValueForExactKey(
                 update.getPrefix().toBinaryString());
 
-        //If there is no existing entry we must assume this is the most recent
-        //update. However this might not always be the case as we might have a
-        //POST then DELETE reordering.
-        //if (oldEntry == null || !newEntry.getNextHop().equals(oldEntry.getNextHop())) {
+        // If there is no existing entry we must assume this is the most recent
+        // update. However this might not always be the case as we might have a
+        // POST then DELETE reordering.
+        // if (oldEntry == null ||
+        // !newEntry.getNextHop().equals(oldEntry.getNextHop())) {
         if (oldEntry == null) {
             return true;
         }
@@ -1387,7 +1403,7 @@
         }
 
         return newEntry.getSysUpTime() == oldEntry.getSysUpTime() &&
-               newEntry.getSequenceNum() > oldEntry.getSequenceNum();
+                newEntry.getSequenceNum() > oldEntry.getSequenceNum();
     }
 
     private Interface longestInterfacePrefixMatch(InetAddress address) {
@@ -1438,8 +1454,17 @@
     }
     */
 
+    // ******************
+    // IOFSwitchListener
+    // ******************
+
     @Override
-    public void addedSwitch(IOFSwitch sw) {
+    public void switchActivatedMaster(long swId) {
+        IOFSwitch sw = floodlightProvider.getSwitch(swId);
+        if (sw == null) {
+            log.warn("Added switch not available {} ", swId);
+            return;
+        }
         if (!topologyReady) {
             sw.clearAllFlowMods();
         }
@@ -1448,12 +1473,30 @@
     }
 
     @Override
-    public void removedSwitch(IOFSwitch sw) {
+    public void switchActivatedEqual(long swId) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void switchMasterToEqual(long swId) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void switchEqualToMaster(long swId) {
+        // for now treat as switchActivatedMaster
+        switchActivatedMaster(swId);
+    }
+
+    @Override
+    public void switchDisconnected(long swId) {
         // Not used
     }
 
     @Override
-    public void switchPortChanged(Long switchId) {
+    public void switchPortChanged(long swId, OFPortDesc port, PortChangeType pct) {
         // Not used
     }
 
diff --git a/src/main/java/net/onrc/onos/core/drivermanager/DriverManager.java b/src/main/java/net/onrc/onos/core/drivermanager/DriverManager.java
new file mode 100644
index 0000000..fe86077
--- /dev/null
+++ b/src/main/java/net/onrc/onos/core/drivermanager/DriverManager.java
@@ -0,0 +1,58 @@
+package net.onrc.onos.core.drivermanager;
+
+import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.core.internal.OFSwitchImplBase;
+
+import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
+import org.projectfloodlight.openflow.protocol.OFVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A simple implementation of a driver manager that differentiates between
+ * connected switches using the OF Description Statistics Reply message.
+ */
+public final class DriverManager {
+
+    private static final Logger log = LoggerFactory.getLogger(DriverManager.class);
+
+    /**
+     * Return an IOFSwitch object based on switch's manufacturer description
+     * from OFDescStatsReply.
+     *
+     * @param desc DescriptionStatistics reply from the switch
+     * @return A IOFSwitch instance if the driver found an implementation for
+     *         the given description. Otherwise it returns OFSwitchImplBase
+     */
+    public static IOFSwitch getOFSwitchImpl(OFDescStatsReply desc, OFVersion ofv) {
+        String vendor = desc.getMfrDesc();
+        String hw = desc.getHwDesc();
+        if (vendor.startsWith("Stanford University, Ericsson Research and CPqD Research")
+                &&
+                hw.startsWith("OpenFlow 1.3 Reference Userspace Switch")) {
+            return new OFSwitchImplCPqD13(desc);
+        }
+
+        if (vendor.startsWith("Nicira") &&
+                hw.startsWith("Open vSwitch")) {
+            if (ofv == OFVersion.OF_10) {
+                return new OFSwitchImplOVS10(desc);
+            } else if (ofv == OFVersion.OF_13) {
+                return new OFSwitchImplOVS13(desc);
+            }
+        }
+
+        log.warn("DriverManager could not identify switch desc: {}. "
+                + "Assigning OFSwitchImplBase", desc);
+        OFSwitchImplBase base = new OFSwitchImplBase();
+        base.setSwitchDescription(desc);
+        // XXX S must set counter here - unidentified switch
+        return base;
+    }
+
+    /**
+     * Private constructor to avoid instantiation.
+     */
+    private DriverManager() {
+    }
+}
diff --git a/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplCPqD13.java b/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplCPqD13.java
new file mode 100644
index 0000000..c2bb344
--- /dev/null
+++ b/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplCPqD13.java
@@ -0,0 +1,1208 @@
+package net.onrc.onos.core.drivermanager;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import net.floodlightcontroller.core.IFloodlightProviderService.Role;
+import net.floodlightcontroller.core.SwitchDriverSubHandshakeAlreadyStarted;
+import net.floodlightcontroller.core.SwitchDriverSubHandshakeCompleted;
+import net.floodlightcontroller.core.SwitchDriverSubHandshakeNotStarted;
+import net.floodlightcontroller.core.internal.OFSwitchImplBase;
+
+import org.projectfloodlight.openflow.protocol.OFAsyncGetReply;
+import org.projectfloodlight.openflow.protocol.OFBarrierRequest;
+import org.projectfloodlight.openflow.protocol.OFBucket;
+import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
+import org.projectfloodlight.openflow.protocol.OFErrorMsg;
+import org.projectfloodlight.openflow.protocol.OFFactory;
+import org.projectfloodlight.openflow.protocol.OFGroupDescStatsReply;
+import org.projectfloodlight.openflow.protocol.OFGroupFeaturesStatsReply;
+import org.projectfloodlight.openflow.protocol.OFGroupType;
+import org.projectfloodlight.openflow.protocol.OFMatchV3;
+import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFOxmList;
+import org.projectfloodlight.openflow.protocol.OFPortDesc;
+import org.projectfloodlight.openflow.protocol.OFStatsReply;
+import org.projectfloodlight.openflow.protocol.action.OFAction;
+import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthDst;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthSrc;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthType;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmInPort;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv4DstMasked;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmMetadataMasked;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmMplsLabel;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmVlanVid;
+import org.projectfloodlight.openflow.types.EthType;
+import org.projectfloodlight.openflow.types.IPv4Address;
+import org.projectfloodlight.openflow.types.MacAddress;
+import org.projectfloodlight.openflow.types.OFBufferId;
+import org.projectfloodlight.openflow.types.OFGroup;
+import org.projectfloodlight.openflow.types.OFMetadata;
+import org.projectfloodlight.openflow.types.OFPort;
+import org.projectfloodlight.openflow.types.OFVlanVidMatch;
+import org.projectfloodlight.openflow.types.TableId;
+import org.projectfloodlight.openflow.types.U32;
+import org.projectfloodlight.openflow.types.U64;
+import org.projectfloodlight.openflow.util.HexString;
+
+/**
+ * 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 {
+    private static final int VLAN_ID_OFFSET = 16;
+    private AtomicBoolean driverHandshakeComplete;
+    private OFFactory factory;
+    private static final int OFPCML_NO_BUFFER = 0xffff;
+    // Configuration of asynch messages to controller. We need different
+    // asynch messages depending on role-equal or role-master.
+    // We don't want to get anything if we are slave.
+    private static final long SET_FLOW_REMOVED_MASK_MASTER = 0xf;
+    private static final long SET_PACKET_IN_MASK_MASTER = 0x7;
+    private static final long SET_PORT_STATUS_MASK_MASTER = 0x7;
+    private static final long SET_FLOW_REMOVED_MASK_EQUAL = 0x0;
+    private static final long SET_PACKET_IN_MASK_EQUAL = 0x0;
+    private static final long SET_PORT_STATUS_MASK_EQUAL = 0x7;
+    private static final long SET_ALL_SLAVE = 0x0;
+
+    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;
+    private static final int TABLE_IPV4_UNICAST = 2;
+    private static final int TABLE_MPLS = 3;
+    private static final int TABLE_META = 4;
+    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 MIN_PRIORITY = 0x0;
+    private static final U64 METADATA_MASK = U64.of(Long.MAX_VALUE << 1 | 0x1);
+
+    ConcurrentHashMap<Integer, OFGroup> l2groups;
+
+    public OFSwitchImplCPqD13(OFDescStatsReply desc) {
+        super();
+        driverHandshakeComplete = new AtomicBoolean(false);
+        l2groups = new ConcurrentHashMap<Integer, OFGroup>();
+        setSwitchDescription(desc);
+
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return "OFSwitchImplCPqD13 [" + ((channel != null)
+                ? channel.getRemoteAddress() : "?")
+                + " DPID[" + ((stringId != null) ? stringId : "?") + "]]";
+    }
+
+    @Override
+    public void startDriverHandshake() throws IOException {
+        log.debug("Starting driver handshake for sw {}", getStringId());
+        if (startDriverHandshakeCalled) {
+            throw new SwitchDriverSubHandshakeAlreadyStarted();
+        }
+        startDriverHandshakeCalled = true;
+        factory = floodlightProvider.getOFMessageFactory_13();
+        // configureSwitch();
+        sendBarrier(true);
+    }
+
+    @Override
+    public boolean isDriverHandshakeComplete() {
+        if (!startDriverHandshakeCalled) {
+            throw new SwitchDriverSubHandshakeNotStarted();
+        }
+        return driverHandshakeComplete.get();
+    }
+
+    @Override
+    public void processDriverHandshakeMessage(OFMessage m) {
+        if (!startDriverHandshakeCalled) {
+            throw new SwitchDriverSubHandshakeNotStarted();
+        }
+        if (driverHandshakeComplete.get()) {
+            throw new SwitchDriverSubHandshakeCompleted(m);
+        }
+
+        if (!startDriverHandshakeCalled) {
+            throw new SwitchDriverSubHandshakeNotStarted();
+        }
+        if (driverHandshakeComplete.get()) {
+            throw new SwitchDriverSubHandshakeCompleted(m);
+        }
+
+        switch (m.getType()) {
+        case BARRIER_REPLY:
+            if (m.getXid() == barrierXidToWaitFor) {
+                driverHandshakeComplete.set(true);
+            }
+            break;
+
+        case ERROR:
+            log.error("Switch {} Error {}", getStringId(), (OFErrorMsg) m);
+            break;
+
+        case FEATURES_REPLY:
+            break;
+        case FLOW_REMOVED:
+            break;
+        case GET_ASYNC_REPLY:
+            OFAsyncGetReply asrep = (OFAsyncGetReply) m;
+            decodeAsyncGetReply(asrep);
+            break;
+
+        case PACKET_IN:
+            break;
+        case PORT_STATUS:
+            break;
+        case QUEUE_GET_CONFIG_REPLY:
+            break;
+        case ROLE_REPLY:
+            break;
+
+        case STATS_REPLY:
+            processStatsReply((OFStatsReply) m);
+            break;
+
+        default:
+            log.debug("Received message {} during switch-driver subhandshake "
+                    + "from switch {} ... Ignoring message", m, getStringId());
+
+        }
+    }
+
+    private void configureSwitch() throws IOException {
+        // setAsyncConfig();
+        // getTableFeatures();
+        sendGroupFeaturesRequest();
+        setL2Groups();
+        sendBarrier(false);
+        setL3Groups();
+        setL25Groups();
+        sendGroupDescRequest();
+        populateTableVlan();
+        populateTableTMac();
+        populateIpTable();
+        populateMplsTable();
+        populateTableMissEntry(TABLE_ACL, false, false, false, -1);
+        sendBarrier(true);
+    }
+
+    private void setAsyncConfig() throws IOException {
+        List<OFMessage> msglist = new ArrayList<OFMessage>(3);
+        OFMessage setAC = null;
+
+        if (role == Role.MASTER) {
+            setAC = factory.buildAsyncSet()
+                    .setFlowRemovedMaskEqualMaster(SET_FLOW_REMOVED_MASK_MASTER)
+                    .setPacketInMaskEqualMaster(SET_PACKET_IN_MASK_MASTER)
+                    .setPortStatusMaskEqualMaster(SET_PORT_STATUS_MASK_MASTER)
+                    .setFlowRemovedMaskSlave(SET_ALL_SLAVE)
+                    .setPacketInMaskSlave(SET_ALL_SLAVE)
+                    .setPortStatusMaskSlave(SET_ALL_SLAVE)
+                    .setXid(getNextTransactionId())
+                    .build();
+        } else if (role == Role.EQUAL) {
+            setAC = factory.buildAsyncSet()
+                    .setFlowRemovedMaskEqualMaster(SET_FLOW_REMOVED_MASK_EQUAL)
+                    .setPacketInMaskEqualMaster(SET_PACKET_IN_MASK_EQUAL)
+                    .setPortStatusMaskEqualMaster(SET_PORT_STATUS_MASK_EQUAL)
+                    .setFlowRemovedMaskSlave(SET_ALL_SLAVE)
+                    .setPacketInMaskSlave(SET_ALL_SLAVE)
+                    .setPortStatusMaskSlave(SET_ALL_SLAVE)
+                    .setXid(getNextTransactionId())
+                    .build();
+        }
+        msglist.add(setAC);
+
+        OFMessage br = factory.buildBarrierRequest()
+                .setXid(getNextTransactionId())
+                .build();
+        msglist.add(br);
+
+        OFMessage getAC = factory.buildAsyncGetRequest()
+                .setXid(getNextTransactionId())
+                .build();
+        msglist.add(getAC);
+
+        write(msglist);
+    }
+
+    private void decodeAsyncGetReply(OFAsyncGetReply rep) {
+        long frm = rep.getFlowRemovedMaskEqualMaster();
+        //long frs = rep.getFlowRemovedMaskSlave();
+        long pim = rep.getPacketInMaskEqualMaster();
+        //long pis = rep.getPacketInMaskSlave();
+        long psm = rep.getPortStatusMaskEqualMaster();
+        //long pss = rep.getPortStatusMaskSlave();
+
+        if (role == Role.MASTER || role == Role.EQUAL) { // should separate
+            log.info("FRM:{}", HexString.toHexString((frm & TEST_FLOW_REMOVED_MASK)));
+            log.info("PIM:{}", HexString.toHexString((pim & TEST_PACKET_IN_MASK)));
+            log.info("PSM:{}", HexString.toHexString((psm & TEST_PORT_STATUS_MASK)));
+        }
+
+    }
+
+    private void getTableFeatures() throws IOException {
+        OFMessage gtf = factory.buildTableFeaturesStatsRequest()
+                .setXid(getNextTransactionId())
+                .build();
+        write(gtf, null);
+    }
+
+    private void sendGroupFeaturesRequest() throws IOException {
+        OFMessage gfr = factory.buildGroupFeaturesStatsRequest()
+                .setXid(getNextTransactionId())
+                .build();
+        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
+     eg. port 1 with allowed vlan 10, is enveloped in group with id,
+         0x0 00a 0001, where the uppermost 4 bits identify an L2 interface,
+         the next 12 bits identify the vlan-id, and the lowermost 16 bits
+         identify the port number.*/
+    private void setL2Groups() throws IOException {
+        List<OFMessage> msglist = new ArrayList<OFMessage>();
+        for (OFPortDesc p : getPorts()) {
+            int pnum = p.getPortNo().getPortNumber();
+            int portVlan = getVlanConfig(pnum);
+            if (U32.of(pnum).compareTo(U32.of(OFPort.MAX.getPortNumber())) < 1) {
+                OFGroup gl2 = OFGroup.of(pnum | (portVlan << VLAN_ID_OFFSET));
+                OFAction out = factory.actions().buildOutput()
+                        .setPort(p.getPortNo()).build();
+                OFAction popVlan = factory.actions().popVlan();
+                List<OFAction> actions = new ArrayList<OFAction>();
+                actions.add(popVlan);
+                actions.add(out);
+                OFBucket bucket = factory.buildBucket()
+                        .setActions(actions).build();
+                List<OFBucket> buckets = Collections.singletonList(bucket);
+                OFMessage gmAdd = factory.buildGroupAdd()
+                        .setGroup(gl2)
+                        .setBuckets(buckets)
+                        .setGroupType(OFGroupType.INDIRECT)
+                        .setXid(getNextTransactionId())
+                        .build();
+                msglist.add(gmAdd);
+                l2groups.put(pnum, gl2);
+            }
+        }
+        log.debug("Creating {} L2 groups in sw {}", msglist.size(), getStringId());
+        write(msglist);
+    }
+
+    private int getVlanConfig(int portnum) {
+        int portVlan = 10 * portnum;
+        if ((getId() == 0x1 && portnum == 6) ||
+                (getId() == 0x2) ||
+                (getId() == 0x3 && portnum == 2)) {
+            portVlan = 192; // 0xc0
+        }
+        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) {
+        OFAction setDA = null;
+        MacAddress dAddr = null;
+        if (getId() == 0x1 && portnum == 6) { // connected to switch 2
+            dAddr = MacAddress.of("00:00:02:02:02:80");
+        }
+        if (getId() == 0x2) {
+            if (portnum == 1) { // connected to sw 1
+                dAddr = MacAddress.of("00:00:01:01:01:80");
+            } else if (portnum == 2) { // connected to sw 3
+                dAddr = MacAddress.of("00:00:07:07:07:80");
+            }
+        }
+        if (getId() == 0x3) {
+            if (portnum == 2) { // connected to switch 2
+                dAddr = MacAddress.of("00:00:02:02:02:80");
+            }
+        }
+
+        if (dAddr != null) {
+            OFOxmEthDst dstAddr = factory.oxms().ethDst(dAddr);
+            setDA = factory.actions().buildSetField()
+                    .setField(dstAddr).build();
+        }
+        return setDA;
+    }
+
+    /*
+     * L3 groups are created for all router ports and they all point to corresponding
+     * L2 groups. Only the ports that connect to other routers will have the
+     * DA set.
+     */
+    private void setL3Groups() throws IOException {
+        List<OFMessage> msglist = new ArrayList<OFMessage>();
+        for (OFGroup gl2 : l2groups.values()) {
+            int gnum = gl2.getGroupNumber();
+            int portnum = gnum & 0x0000ffff;
+            int vlanid = ((gnum & 0x0fff0000) >> VLAN_ID_OFFSET);
+            MacAddress sAddr = getRouterMacAddr();
+
+            OFGroup gl3 = OFGroup.of(0x20000000 | portnum);
+            OFAction group = factory.actions().buildGroup()
+                    .setGroup(gl2).build();
+            OFOxmEthSrc srcAddr = factory.oxms().ethSrc(sAddr);
+            OFAction setSA = factory.actions().buildSetField()
+                    .setField(srcAddr).build();
+            OFOxmVlanVid vid = factory.oxms().vlanVid(OFVlanVidMatch.ofVlan(vlanid));
+            OFAction setVlan = factory.actions().buildSetField()
+                    .setField(vid).build();
+            OFAction decTtl = factory.actions().decNwTtl();
+
+            List<OFAction> actions = new ArrayList<OFAction>();
+            actions.add(decTtl); // decrement the IP TTL/do-checksum/check TTL
+                                 // and MTU
+            actions.add(setVlan); // set the vlan-id of the exit-port (and
+                                  // l2group)
+            actions.add(setSA); // set this routers mac address
+            // make L3Unicast group setDA for known (configured) ports
+            // that connect to other routers
+            OFAction setDA = getDestAction(portnum);
+            if (setDA != null) {
+                actions.add(setDA);
+            }
+            actions.add(group);
+
+            OFBucket bucket = factory.buildBucket()
+                    .setActions(actions).build();
+            List<OFBucket> buckets = Collections.singletonList(bucket);
+            OFMessage gmAdd = factory.buildGroupAdd()
+                    .setGroup(gl3)
+                    .setBuckets(buckets)
+                    .setGroupType(OFGroupType.INDIRECT)
+                    .setXid(getNextTransactionId())
+                    .build();
+            msglist.add(gmAdd);
+        }
+        write(msglist);
+        log.debug("Creating {} L3 groups in sw {}", msglist.size(), getStringId());
+    }
+
+    /*
+     * L2.5 or mpls-unicast groups are only created for those router ports
+     * connected to other router ports. They differ from the corresponding
+     * L3-unicast group only by the fact that they decrement the MPLS TTL
+     * instead of the IP ttl
+     */
+    private void setL25Groups() throws IOException {
+        List<OFMessage> msglist = new ArrayList<OFMessage>();
+        for (OFGroup gl2 : l2groups.values()) {
+            int gnum = gl2.getGroupNumber();
+            int portnum = gnum & 0x0000ffff;
+            int vlanid = ((gnum & 0x0fff0000) >> VLAN_ID_OFFSET);
+            MacAddress sAddr = getRouterMacAddr();
+            OFAction setDA = getDestAction(portnum);
+            // setDA will only be non-null for ports connected to routers
+            if (setDA != null) {
+                OFGroup gl3 = OFGroup.of(0xa0000000 | portnum); // different id
+                                                                // for mpls
+                                                                // group
+                OFAction group = factory.actions().buildGroup()
+                        .setGroup(gl2).build();
+                OFOxmEthSrc srcAddr = factory.oxms().ethSrc(sAddr);
+                OFAction setSA = factory.actions().buildSetField()
+                        .setField(srcAddr).build();
+                OFOxmVlanVid vid = factory.oxms().vlanVid(OFVlanVidMatch.ofVlan(vlanid));
+                OFAction setVlan = factory.actions().buildSetField()
+                        .setField(vid).build();
+                OFAction decMplsTtl = factory.actions().decMplsTtl();
+                List<OFAction> actions = new ArrayList<OFAction>();
+                actions.add(decMplsTtl); // decrement the MPLS
+                                         // TTL/do-checksum/check TTL and MTU
+                actions.add(setVlan); // set the vlan-id of the exit-port (and
+                                      // l2group)
+                actions.add(setSA); // set this routers mac address
+                actions.add(setDA);
+                actions.add(group);
+                OFBucket bucket = factory.buildBucket()
+                        .setActions(actions).build();
+                List<OFBucket> buckets = Collections.singletonList(bucket);
+                OFMessage gmAdd = factory.buildGroupAdd()
+                        .setGroup(gl3)
+                        .setBuckets(buckets)
+                        .setGroupType(OFGroupType.INDIRECT)
+                        .setXid(getNextTransactionId())
+                        .build();
+                msglist.add(gmAdd);
+            }
+        }
+        write(msglist);
+        log.debug("Creating {} MPLS groups in sw {}", msglist.size(), getStringId());
+    }
+
+    /* Using ECMP groups
+     *
+     * OFGroup group47 = OFGroup.of(47);
+        OFAction outgroup1 = factory.actions()
+                        .buildGroup()
+                        .setGroup(group61)
+                        .build();
+        OFBucket buc47_1 = factory.buildBucket()
+                        .setWeight(1)
+                        .setActions(Collections.singletonList(outgroup1))
+                        .build();
+        OFAction outgroup2 = factory.actions()
+                        .buildGroup()
+                        .setGroup(group62)
+                        .build();
+        OFBucket buc47_2 = factory.buildBucket()
+                        .setWeight(1)
+                        .setActions(Collections.singletonList(outgroup2))
+                        .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();
+        write(gmS12, null);     */
+
+    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>();
+        if (getId() == 0x1) {
+            myIps.add("10.0.2.128");
+            myIps.add("10.0.3.128");
+            myIps.add("10.0.1.128");
+            myIps.add("192.168.0.1");
+        }
+        if (getId() == 0x2) {
+            myIps.add("192.168.0.2");
+        }
+        if (getId() == 0x3) {
+            myIps.add("192.168.0.3");
+            myIps.add("7.7.7.128");
+        }
+        return myIps;
+    }
+
+    private List<String> getMySubnetIps() { // send to controller
+        List<String> subnetIps = new ArrayList<String>();
+        if (getId() == 0x1) {
+            subnetIps.add("10.0.2.0");
+            subnetIps.add("10.0.3.0");
+            subnetIps.add("10.0.1.0");
+        }
+        // TODO needed?
+        //if (getId() == 0x2) {
+        //}
+        if (getId() == 0x3) {
+            subnetIps.add("7.7.7.0");
+        }
+        return subnetIps;
+    }
+
+    private static class RouteEntry {
+        String prefix;
+        String mask;
+        int nextHopPort;
+        String dstMac;
+        int label;
+
+        public RouteEntry(String prefix, String mask, int nextHopPort, int label) {
+            this.prefix = prefix;
+            this.mask = mask;
+            this.nextHopPort = nextHopPort;
+            this.label = label;
+        }
+
+        public RouteEntry(String prefix, int nextHopPort, String dstMac) {
+            this.prefix = prefix;
+            this.nextHopPort = nextHopPort;
+            this.dstMac = dstMac;
+        }
+    }
+
+    // send out of mpls-group where the next-hop mac-da is already set
+    private List<RouteEntry> getRouterNextHopIps() {
+        List<RouteEntry> routerNextHopIps = new ArrayList<RouteEntry>();
+        if (getId() == 0x1) {
+            routerNextHopIps
+                    .add(new RouteEntry("192.168.0.2", "255.255.255.255", 6, 102));
+            routerNextHopIps
+                    .add(new RouteEntry("192.168.0.3", "255.255.255.255", 6, 103));
+            routerNextHopIps.add(new RouteEntry("7.7.7.0", "255.255.255.0", 6, 103));
+        }
+        //if (getId() == 0x2) {
+            /* These are required for normal IP routing without labels.
+            routerNextHopIps.add(new RouteEntry("192.168.0.1","255.255.255.255",1));
+            routerNextHopIps.add(new RouteEntry("192.168.0.3","255.255.255.255",2));
+            routerNextHopIps.add(new RouteEntry("10.0.1.0","255.255.255.0",1));
+            routerNextHopIps.add(new RouteEntry("10.0.2.0","255.255.255.0",1));
+            routerNextHopIps.add(new RouteEntry("10.0.3.0","255.255.255.0",1));
+            routerNextHopIps.add(new RouteEntry("7.7.7.0","255.255.255.0",2));*/
+        //}
+        if (getId() == 0x3) {
+            routerNextHopIps
+                    .add(new RouteEntry("192.168.0.2", "255.255.255.255", 2, 102));
+            routerNextHopIps
+                    .add(new RouteEntry("192.168.0.1", "255.255.255.255", 2, 101));
+            routerNextHopIps.add(new RouteEntry("10.0.1.0", "255.255.255.0", 2, 101));
+            routerNextHopIps.add(new RouteEntry("10.0.2.0", "255.255.255.0", 2, 101));
+            routerNextHopIps.add(new RouteEntry("10.0.3.0", "255.255.255.0", 2, 101));
+        }
+        return routerNextHopIps;
+    }
+
+    // known host mac-addr, setDA/send out of l3group
+    private List<RouteEntry> getHostNextHopIps() {
+        List<RouteEntry> hostNextHopIps = new ArrayList<RouteEntry>();
+        if (getId() == 0x1) {
+            hostNextHopIps.add(new RouteEntry("10.0.2.1", 4, "00:00:00:00:02:01"));
+            hostNextHopIps.add(new RouteEntry("10.0.3.1", 5, "00:00:00:00:03:01"));
+        }
+        // TODO needed?
+        //if (getId() == 0x2) {
+        //}
+        if (getId() == 0x3) {
+            hostNextHopIps.add(new RouteEntry("7.7.7.7", 1, "00:00:07:07:07:07"));
+        }
+        return hostNextHopIps;
+    }
+
+    private void populateIpTable() throws IOException {
+        populateMyIps();
+        populateMySubnets();
+        populateRoutes();
+        populateHostRoutes();
+
+        // match for everything else to send to ACL table. Essentially
+        // the table miss flow entry
+        populateTableMissEntry(TABLE_IPV4_UNICAST, false, true,
+                true, TABLE_ACL);
+    }
+
+    private void populateMyIps() throws IOException {
+        List<OFMessage> msglist = new ArrayList<OFMessage>();
+        // first all my ip's as exact-matches
+        // write-action instruction to send to controller
+        List<String> myIps = getMyIps();
+        for (int i = 0; i < myIps.size(); i++) {
+            OFOxmEthType ethTypeIp = factory.oxms()
+                    .ethType(EthType.IPv4);
+            OFOxmIpv4DstMasked ipPrefix = factory.oxms()
+                    .ipv4DstMasked(IPv4Address.of(myIps.get(i)), IPv4Address.NO_MASK);
+            OFOxmList oxmListSlash32 = OFOxmList.of(ethTypeIp, ipPrefix);
+            OFMatchV3 match = factory.buildMatchV3()
+                    .setOxmList(oxmListSlash32).build();
+            OFAction outc = factory.actions().buildOutput()
+                    .setPort(OFPort.CONTROLLER).setMaxLen(OFPCML_NO_BUFFER)
+                    .build();
+            OFInstruction writeInstr = factory.instructions().buildWriteActions()
+                    .setActions(Collections.singletonList(outc)).build();
+            OFInstruction gotoInstr = factory.instructions().buildGotoTable()
+                    .setTableId(TableId.of(TABLE_ACL)).build();
+            List<OFInstruction> instructions = new ArrayList<OFInstruction>();
+            instructions.add(writeInstr);
+            instructions.add(gotoInstr);
+            OFMessage myIpEntry = factory.buildFlowAdd()
+                    .setTableId(TableId.of(TABLE_IPV4_UNICAST))
+                    .setMatch(match)
+                    .setInstructions(instructions)
+                    .setPriority(MAX_PRIORITY) // highest priority for exact
+                                               // match
+                    .setBufferId(OFBufferId.NO_BUFFER)
+                    .setIdleTimeout(0)
+                    .setHardTimeout(0)
+                    .setXid(getNextTransactionId())
+                    .build();
+            msglist.add(myIpEntry);
+        }
+        write(msglist);
+        log.debug("Adding {} my-ip-rules in sw {}", msglist.size(), getStringId());
+    }
+
+    private void populateMySubnets() throws IOException {
+        List<OFMessage> msglist = new ArrayList<OFMessage>();
+        // next prefix-based subnet-IP's configured on my interfaces
+        // need to ARP for exact-IP, so write-action instruction to send to
+        // controller
+        // this has different mask and priority than earlier case
+        List<String> subnetIps = getMySubnetIps();
+        for (int i = 0; i < subnetIps.size(); i++) {
+            OFOxmEthType ethTypeIp = factory.oxms()
+                    .ethType(EthType.IPv4);
+            OFOxmIpv4DstMasked ipPrefix = factory.oxms().ipv4DstMasked(
+                    IPv4Address.of(subnetIps.get(i)),
+                    IPv4Address.of(0xffffff00)); // '/24' mask
+            OFOxmList oxmListSlash24 = OFOxmList.of(ethTypeIp, ipPrefix);
+            OFMatchV3 match = factory.buildMatchV3()
+                    .setOxmList(oxmListSlash24).build();
+            OFAction outc = factory.actions().buildOutput()
+                    .setPort(OFPort.CONTROLLER).setMaxLen(OFPCML_NO_BUFFER)
+                    .build();
+            OFInstruction writeInstr = factory.instructions().buildWriteActions()
+                    .setActions(Collections.singletonList(outc)).build();
+            OFInstruction gotoInstr = factory.instructions().buildGotoTable()
+                    .setTableId(TableId.of(TABLE_ACL)).build();
+            List<OFInstruction> instructions = new ArrayList<OFInstruction>();
+            instructions.add(writeInstr);
+            instructions.add(gotoInstr);
+            OFMessage myIpEntry = factory.buildFlowAdd()
+                    .setTableId(TableId.of(TABLE_IPV4_UNICAST))
+                    .setMatch(match)
+                    .setInstructions(instructions)
+                    .setPriority(SLASH_24_PRIORITY)
+                    .setBufferId(OFBufferId.NO_BUFFER)
+                    .setIdleTimeout(0)
+                    .setHardTimeout(0)
+                    .setXid(getNextTransactionId())
+                    .build();
+            msglist.add(myIpEntry);
+        }
+        write(msglist);
+        log.debug("Adding {} subnet-ip-rules in sw {}", msglist.size(), getStringId());
+        msglist.clear();
+    }
+
+    private void populateRoutes() throws IOException {
+        List<OFMessage> msglist = new ArrayList<OFMessage>();
+        // addresses where I know the next-hop's mac-address because it is a
+        // router port - so I have an L3 interface to it (and an MPLS interface)
+        List<RouteEntry> routerNextHopIps = getRouterNextHopIps();
+        for (int i = 0; i < routerNextHopIps.size(); i++) {
+            OFOxmEthType ethTypeIp = factory.oxms()
+                    .ethType(EthType.IPv4);
+            OFOxmIpv4DstMasked ipPrefix = factory.oxms()
+                    .ipv4DstMasked(
+                            IPv4Address.of(routerNextHopIps.get(i).prefix),
+                            IPv4Address.of(routerNextHopIps.get(i).mask)
+                    );
+            OFOxmList oxmListSlash32 = OFOxmList.of(ethTypeIp, ipPrefix);
+            OFMatchV3 match = factory.buildMatchV3()
+                    .setOxmList(oxmListSlash32).build();
+            OFAction outg = factory.actions().buildGroup()
+                    .setGroup(OFGroup.of(0xa0000000 | // mpls group id
+                            routerNextHopIps.get(i).nextHopPort))
+                    .build();
+            // lots of actions before forwarding to mpls group, and
+            // unfortunately
+            // they need to be apply-actions
+
+            OFAction pushlabel = factory.actions().pushMpls(EthType.MPLS_UNICAST);
+            OFOxmMplsLabel l = factory.oxms()
+                    .mplsLabel(U32.of(routerNextHopIps.get(i).label));
+            OFAction setlabelid = factory.actions().buildSetField()
+                    .setField(l).build();
+            OFAction copyTtlOut = factory.actions().copyTtlOut();
+            // OFAction setBos =
+            // factory.actions().buildSetField().setField(bos).build();
+
+            /*
+            writeActions.add(pushlabel);  // need to be apply actions so can be
+            writeActions.add(copyTtlOut); // matched in pseudo-table
+            //writeActions.add(setlabelid); // bad support in cpqd
+            //writeActions.add(setBos); no support in loxigen
+            */
+
+            List<OFAction> applyActions = new ArrayList<OFAction>();
+            applyActions.add(pushlabel);
+            applyActions.add(copyTtlOut);
+            OFInstruction applyInstr = factory.instructions().buildApplyActions()
+                    .setActions(applyActions).build();
+            List<OFAction> writeActions = new ArrayList<OFAction>();
+            writeActions.add(outg); // group will decr mpls-ttl, set mac-sa/da,
+                                    // vlan
+            OFInstruction writeInstr = factory.instructions().buildWriteActions()
+                    .setActions(writeActions).build();
+
+            // necessary to match in pseudo-table to overcome cpqd 1.3 flaw
+            OFInstruction writeMeta = factory.instructions().buildWriteMetadata()
+                    .setMetadata(U64.of(routerNextHopIps.get(i).label))
+                    .setMetadataMask(METADATA_MASK).build();
+            /*OFInstruction gotoInstr = factory.instructions().buildGotoTable()
+                        .setTableId(TableId.of(TABLE_ACL)).build();*/
+            OFInstruction gotoInstr = factory.instructions().buildGotoTable()
+                    .setTableId(TableId.of(TABLE_META)).build();
+            List<OFInstruction> instructions = new ArrayList<OFInstruction>();
+            instructions.add(applyInstr);
+            // instructions.add(writeInstr);// cannot write here - causes switch
+            // to crash
+            instructions.add(writeMeta);
+            instructions.add(gotoInstr);
+
+            int priority = -1;
+            if (routerNextHopIps.get(i).mask.equals("255.255.255.255")) {
+                priority = MAX_PRIORITY;
+            } else {
+                priority = SLASH_24_PRIORITY;
+            }
+            OFMessage myIpEntry = 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();
+            msglist.add(myIpEntry);
+
+            // need to also handle psuedo-table entries to match-metadata and
+            // set mpls
+            // label-id
+            OFOxmEthType ethTypeMpls = factory.oxms()
+                    .ethType(EthType.MPLS_UNICAST);
+            OFOxmMetadataMasked meta = factory.oxms()
+                    .metadataMasked(
+                            OFMetadata.ofRaw(routerNextHopIps.get(i).label),
+                            OFMetadata.NO_MASK);
+            OFOxmList oxmListMeta = OFOxmList.of(ethTypeMpls, meta);
+            OFMatchV3 matchMeta = factory.buildMatchV3()
+                    .setOxmList(oxmListMeta).build();
+            List<OFAction> writeActions2 = new ArrayList<OFAction>();
+            writeActions2.add(setlabelid);
+            OFAction outg2 = factory.actions().buildGroup()
+                    .setGroup(OFGroup.of(routerNextHopIps.get(i).nextHopPort |
+                            (192 << VLAN_ID_OFFSET)))
+                    .build();
+            writeActions2.add(outg2);
+            OFInstruction writeInstr2 = factory.instructions().buildWriteActions()
+                    .setActions(writeActions2).build();
+            OFInstruction gotoInstr2 = factory.instructions().buildGotoTable()
+                    .setTableId(TableId.of(TABLE_ACL)).build();
+            List<OFInstruction> instructions2 = new ArrayList<OFInstruction>();
+            // unfortunately have to apply this action too
+            OFInstruction applyInstr2 = factory.instructions().buildApplyActions()
+                    .setActions(writeActions2).build();
+            instructions2.add(applyInstr2);
+            // instructions2.add(writeInstr2);
+            // instructions2.add(gotoInstr2);
+
+            /*OFMatchV3 match3 = factory.buildMatchV3()
+                        .setOxmList(OFOxmList.of(meta)).build();
+            OFInstruction clearInstruction = factory.instructions().clearActions();
+            List<OFInstruction> instructions3 = new ArrayList<OFInstruction>();
+            OFAction outc = factory.actions().buildOutput()
+                        .setPort(OFPort.CONTROLLER).setMaxLen(OFPCML_NO_BUFFER)
+                        .build();
+            OFInstruction writec = factory.instructions()
+                        .writeActions(Collections.singletonList(outc));
+            instructions3.add(clearInstruction);
+            instructions3.add(writec);
+            instructions3.add(gotoInstr2); */
+            OFMessage myMetaEntry = factory.buildFlowAdd()
+                    .setTableId(TableId.of(TABLE_META))
+                    .setMatch(matchMeta)
+                    .setInstructions(instructions2)
+                    .setPriority(MAX_PRIORITY)
+                    .setBufferId(OFBufferId.NO_BUFFER)
+                    .setIdleTimeout(0)
+                    .setHardTimeout(0)
+                    .setXid(getNextTransactionId())
+                    .build();
+            msglist.add(myMetaEntry);
+
+        }
+        write(msglist);
+        log.debug("Adding {} next-hop-router-rules in sw {}", msglist.size(),
+                getStringId());
+
+        // add a table-miss entry to table 4 for debugging - leave it out
+        // unclear packet state - causes switch to crash
+        // populateTableMissEntry(TABLE_META, false, true,
+        // true, TABLE_ACL);
+    }
+
+    private void populateHostRoutes() throws IOException {
+        List<OFMessage> msglist = new ArrayList<OFMessage>();
+        // addresses where I know the next hop's mac-address and I can set the
+        // destination mac in the match-instruction.write-action
+        // either I sent out arp-request or I got an arp-request from this host
+        List<RouteEntry> hostNextHopIps = getHostNextHopIps();
+        for (int i = 0; i < hostNextHopIps.size(); i++) {
+            OFOxmEthType ethTypeIp = factory.oxms()
+                    .ethType(EthType.IPv4);
+            OFOxmIpv4DstMasked ipPrefix = factory.oxms()
+                    .ipv4DstMasked(
+                            IPv4Address.of(hostNextHopIps.get(i).prefix),
+                            IPv4Address.NO_MASK); // host addr should be /32
+            OFOxmList oxmListSlash32 = OFOxmList.of(ethTypeIp, ipPrefix);
+            OFMatchV3 match = factory.buildMatchV3()
+                    .setOxmList(oxmListSlash32).build();
+            OFAction setDmac = null, outg = null;
+            OFOxmEthDst dmac = factory.oxms()
+                    .ethDst(MacAddress.of(hostNextHopIps.get(i).dstMac));
+            setDmac = factory.actions().buildSetField()
+                    .setField(dmac).build();
+            outg = factory.actions().buildGroup()
+                    .setGroup(OFGroup.of(0x20000000 | hostNextHopIps.get(i).nextHopPort)) // l3group
+                                                                                          // id
+                    .build();
+            List<OFAction> writeActions = new ArrayList<OFAction>();
+            writeActions.add(setDmac);
+            writeActions.add(outg);
+            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);
+            OFMessage myIpEntry = factory.buildFlowAdd()
+                    .setTableId(TableId.of(TABLE_IPV4_UNICAST))
+                    .setMatch(match)
+                    .setInstructions(instructions)
+                    .setPriority(MAX_PRIORITY) // highest priority for exact
+                                               // match
+                    .setBufferId(OFBufferId.NO_BUFFER)
+                    .setIdleTimeout(0)
+                    .setHardTimeout(0)
+                    .setXid(getNextTransactionId())
+                    .build();
+            msglist.add(myIpEntry);
+        }
+        write(msglist);
+        log.debug("Adding {} next-hop-host-rules in sw {}", msglist.size(), getStringId());
+    }
+
+    private static class MplsEntry {
+        int labelid;
+        int portnum;
+
+        public MplsEntry(int labelid, int portnum) {
+            this.labelid = labelid;
+            this.portnum = portnum;
+        }
+    }
+
+    private List<MplsEntry> getMplsEntries() {
+        List<MplsEntry> myLabels = new ArrayList<MplsEntry>();
+        if (getId() == 0x1) {
+            myLabels.add(new MplsEntry(101, OFPort.CONTROLLER.getPortNumber()));
+            myLabels.add(new MplsEntry(103, 6));
+        }
+        if (getId() == 0x2) {
+            myLabels.add(new MplsEntry(103, 2));
+            myLabels.add(new MplsEntry(102, OFPort.CONTROLLER.getPortNumber()));
+            myLabels.add(new MplsEntry(101, 1));
+        }
+        if (getId() == 0x3) {
+            myLabels.add(new MplsEntry(103, OFPort.CONTROLLER.getPortNumber()));
+            myLabels.add(new MplsEntry(101, 2));
+        }
+        return myLabels;
+    }
+
+    private void populateMplsTable() throws IOException {
+        List<OFMessage> msglist = new ArrayList<OFMessage>();
+        List<MplsEntry> lfibEntries = getMplsEntries();
+        for (int i = 0; i < lfibEntries.size(); i++) {
+            OFOxmEthType ethTypeMpls = factory.oxms()
+                    .ethType(EthType.MPLS_UNICAST);
+            OFOxmMplsLabel labelid = factory.oxms()
+                    .mplsLabel(U32.of(lfibEntries.get(i).labelid));
+            OFOxmList oxmList = OFOxmList.of(ethTypeMpls, labelid);
+            OFMatchV3 matchlabel = factory.buildMatchV3()
+                    .setOxmList(oxmList).build();
+            OFAction poplabel = factory.actions().popMpls(EthType.IPv4);
+            OFAction sendTo = null;
+            if (lfibEntries.get(i).portnum == OFPort.CONTROLLER.getPortNumber()) {
+                sendTo = factory.actions().output(OFPort.CONTROLLER,
+                        OFPCML_NO_BUFFER);
+            } else {
+                sendTo = factory.actions().group(OFGroup.of(
+                        0xa0000000 | lfibEntries.get(i).portnum));
+            }
+            List<OFAction> writeActions = new ArrayList<OFAction>();
+            writeActions.add(poplabel);
+            writeActions.add(sendTo);
+            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);
+            OFMessage myMplsEntry = factory.buildFlowAdd()
+                    .setTableId(TableId.of(TABLE_MPLS))
+                    .setMatch(matchlabel)
+                    .setInstructions(instructions)
+                    .setPriority(MAX_PRIORITY) // exact match and exclusive
+                    .setBufferId(OFBufferId.NO_BUFFER)
+                    .setIdleTimeout(0)
+                    .setHardTimeout(0)
+                    .setXid(getNextTransactionId())
+                    .build();
+            msglist.add(myMplsEntry);
+        }
+        write(msglist);
+        log.debug("Adding {} mpls-forwarding-rules in sw {}", msglist.size(),
+                getStringId());
+
+        // match for everything else to send to ACL table. Essentially
+        // the table miss flow entry
+        populateTableMissEntry(TABLE_MPLS, false, true,
+                true, TABLE_ACL);
+
+    }
+
+    /**
+     * 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/drivermanager/OFSwitchImplOVS10.java b/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplOVS10.java
new file mode 100644
index 0000000..bfe613e
--- /dev/null
+++ b/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplOVS10.java
@@ -0,0 +1,29 @@
+package net.onrc.onos.core.drivermanager;
+
+import net.floodlightcontroller.core.internal.OFSwitchImplBase;
+
+import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
+
+/**
+ * OFDescriptionStatistics Vendor (Manufacturer Desc.): Nicira, Inc. Make
+ * (Hardware Desc.) : Open vSwitch Model (Datapath Desc.) : None Software :
+ * 1.11.90 (or whatever version + build) Serial : None
+ */
+public class OFSwitchImplOVS10 extends OFSwitchImplBase {
+
+    public OFSwitchImplOVS10(OFDescStatsReply desc) {
+        super();
+        setSwitchDescription(desc);
+        setAttribute(SWITCH_SUPPORTS_NX_ROLE, true);
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return "OFSwitchImplOVS10 [" + ((channel != null)
+                ? channel.getRemoteAddress() : "?")
+                + " DPID[" + ((stringId != null) ? stringId : "?") + "]]";
+    }
+}
diff --git a/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplOVS13.java b/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplOVS13.java
new file mode 100644
index 0000000..efe43a0
--- /dev/null
+++ b/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplOVS13.java
@@ -0,0 +1,138 @@
+package net.onrc.onos.core.drivermanager;
+
+import java.io.IOException;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import net.floodlightcontroller.core.SwitchDriverSubHandshakeAlreadyStarted;
+import net.floodlightcontroller.core.SwitchDriverSubHandshakeCompleted;
+import net.floodlightcontroller.core.SwitchDriverSubHandshakeNotStarted;
+import net.floodlightcontroller.core.internal.OFSwitchImplBase;
+
+import org.projectfloodlight.openflow.protocol.OFBarrierRequest;
+import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
+import org.projectfloodlight.openflow.protocol.OFErrorMsg;
+import org.projectfloodlight.openflow.protocol.OFFactory;
+import org.projectfloodlight.openflow.protocol.OFMessage;
+
+/**
+ * OFDescriptionStatistics Vendor (Manufacturer Desc.): Nicira, Inc. Make
+ * (Hardware Desc.) : Open vSwitch Model (Datapath Desc.) : None Software :
+ * 2.1.0 (or whatever version + build) Serial : None
+ */
+public class OFSwitchImplOVS13 extends OFSwitchImplBase {
+    private AtomicBoolean driverHandshakeComplete;
+    private OFFactory factory;
+    private long barrierXidToWaitFor = -1;
+
+    public OFSwitchImplOVS13(OFDescStatsReply desc) {
+        super();
+        driverHandshakeComplete = new AtomicBoolean(false);
+        setSwitchDescription(desc);
+    }
+
+    @Override
+    public String toString() {
+        return "OFSwitchImplOVS13 [" + ((channel != null)
+                ? channel.getRemoteAddress() : "?")
+                + " DPID[" + ((stringId != null) ? stringId : "?") + "]]";
+    }
+
+    @Override
+    public void startDriverHandshake() throws IOException {
+        log.debug("Starting driver handshake for sw {}", getStringId());
+        if (startDriverHandshakeCalled) {
+            throw new SwitchDriverSubHandshakeAlreadyStarted();
+        }
+        startDriverHandshakeCalled = true;
+        factory = floodlightProvider.getOFMessageFactory_13();
+        configureSwitch();
+    }
+
+    @Override
+    public boolean isDriverHandshakeComplete() {
+        if (!startDriverHandshakeCalled) {
+            throw new SwitchDriverSubHandshakeNotStarted();
+        }
+        return driverHandshakeComplete.get();
+    }
+
+    @Override
+    public void processDriverHandshakeMessage(OFMessage m) {
+        if (!startDriverHandshakeCalled) {
+            throw new SwitchDriverSubHandshakeNotStarted();
+        }
+        if (driverHandshakeComplete.get()) {
+            throw new SwitchDriverSubHandshakeCompleted(m);
+        }
+
+        switch (m.getType()) {
+        case BARRIER_REPLY:
+            if (m.getXid() == barrierXidToWaitFor) {
+                driverHandshakeComplete.set(true);
+            }
+            break;
+
+        case ERROR:
+            log.error("Switch {} Error {}", getStringId(), (OFErrorMsg) m);
+            break;
+
+        case FEATURES_REPLY:
+            break;
+        case FLOW_REMOVED:
+            break;
+        case GET_ASYNC_REPLY:
+            // OFAsyncGetReply asrep = (OFAsyncGetReply)m;
+            // decodeAsyncGetReply(asrep);
+            break;
+
+        case PACKET_IN:
+            break;
+        case PORT_STATUS:
+            break;
+        case QUEUE_GET_CONFIG_REPLY:
+            break;
+        case ROLE_REPLY:
+            break;
+
+        case STATS_REPLY:
+            // processStatsReply((OFStatsReply) m);
+            break;
+
+        default:
+            log.debug("Received message {} during switch-driver subhandshake "
+                    + "from switch {} ... Ignoring message", m, getStringId());
+
+        }
+    }
+
+
+    private void configureSwitch() throws IOException {
+        // setAsyncConfig();
+        // getTableFeatures();
+        /*sendGroupFeaturesRequest();
+        setL2Groups();
+        sendBarrier(false);
+        setL3Groups();
+        setL25Groups();
+        sendGroupDescRequest();*/
+        // populateTableVlan();
+        // populateTableTMac();
+        // populateIpTable();
+        // populateMplsTable();
+        // populateTableMissEntry(TABLE_ACL, false, false, false, -1);
+        sendBarrier(true);
+    }
+
+
+    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/flowprogrammer/FlowProgrammer.java b/src/main/java/net/onrc/onos/core/flowprogrammer/FlowProgrammer.java
index 046d130..4a62947 100644
--- a/src/main/java/net/onrc/onos/core/flowprogrammer/FlowProgrammer.java
+++ b/src/main/java/net/onrc/onos/core/flowprogrammer/FlowProgrammer.java
@@ -7,6 +7,7 @@
 
 import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.core.IOFSwitch.PortChangeType;
 import net.floodlightcontroller.core.IOFSwitchListener;
 import net.floodlightcontroller.core.module.FloodlightModuleContext;
 import net.floodlightcontroller.core.module.FloodlightModuleException;
@@ -16,19 +17,20 @@
 import net.onrc.onos.core.flowprogrammer.web.FlowProgrammerWebRoutable;
 import net.onrc.onos.core.registry.IControllerRegistryService;
 
+import org.projectfloodlight.openflow.protocol.OFPortDesc;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * FlowProgrammer is a module responsible to maintain flows installed to switches.
- * FlowProgrammer consists of FlowPusher and FlowSynchronizer.
- * FlowPusher manages the rate of installation, and FlowSynchronizer synchronizes
- * flows between GraphDB and switches.
- * FlowProgrammer also watch the event of addition/deletion of switches to
- * start/stop synchronization. When a switch is added to network, FlowProgrammer
- * immediately kicks synchronization to keep switch's flow table latest state.
- * Adversely, when a switch is removed from network, FlowProgrammer immediately
- * stops synchronization.
+ * FlowProgrammer is a module responsible to maintain flows installed to
+ * switches. FlowProgrammer consists of FlowPusher and FlowSynchronizer.
+ * FlowPusher manages the rate of installation, and FlowSynchronizer
+ * synchronizes flows between GraphDB and switches. FlowProgrammer also watch
+ * the event of addition/deletion of switches to start/stop synchronization.
+ * When a switch is added to network, FlowProgrammer immediately kicks
+ * synchronization to keep switch's flow table latest state. Adversely, when a
+ * switch is removed from network, FlowProgrammer immediately stops
+ * synchronization.
  */
 public class FlowProgrammer implements IFloodlightModule,
         IOFSwitchListener {
@@ -57,7 +59,7 @@
         floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
         registryService = context.getServiceImpl(IControllerRegistryService.class);
         restApi = context.getServiceImpl(IRestApiService.class);
-        pusher.init(null, context, floodlightProvider.getOFMessageFactory(), null);
+        pusher.init(context);
         if (ENABLE_FLOW_SYNC) {
             synchronizer.init(pusher);
         }
@@ -83,8 +85,7 @@
 
     @Override
     public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
-        Map<Class<? extends IFloodlightService>,
-                IFloodlightService> m =
+        Map<Class<? extends IFloodlightService>, IFloodlightService> m =
                 new HashMap<Class<? extends IFloodlightService>,
                         IFloodlightService>();
         m.put(IFlowPusherService.class, pusher);
@@ -103,25 +104,56 @@
         return l;
     }
 
+    // ***********************
+    // IOFSwitchListener
+    // ***********************
+
     @Override
     public String getName() {
-        // TODO Auto-generated method stub
         return "FlowProgrammer";
     }
 
     @Override
-    public void addedSwitch(IOFSwitch sw) {
-        log.debug("Switch added: {}", sw.getId());
+    public void switchActivatedMaster(long swId) {
+        IOFSwitch sw = floodlightProvider.getSwitch(swId);
+        if (sw == null) {
+            log.warn("Added switch not available {} ", swId);
+            return;
+        }
+        log.debug("Switch added: {}", swId);
 
         if (ENABLE_FLOW_SYNC) {
-            if (registryService.hasControl(sw.getId())) {
+            if (registryService.hasControl(swId)) {
                 synchronizer.synchronize(sw);
             }
         }
     }
 
     @Override
-    public void removedSwitch(IOFSwitch sw) {
+    public void switchActivatedEqual(long swId) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void switchMasterToEqual(long swId) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void switchEqualToMaster(long swId) {
+        // for now treat as switchActivatedMaster
+        switchActivatedMaster(swId);
+    }
+
+    @Override
+    public void switchDisconnected(long swId) {
+        IOFSwitch sw = floodlightProvider.getSwitch(swId);
+        if (sw == null) {
+            log.warn("Removed switch not available {} ", swId);
+            return;
+        }
         log.debug("Switch removed: {}", sw.getId());
 
         if (ENABLE_FLOW_SYNC) {
@@ -132,7 +164,7 @@
     }
 
     @Override
-    public void switchPortChanged(Long switchId) {
+    public void switchPortChanged(long swId, OFPortDesc port, PortChangeType pct) {
         // TODO Auto-generated method stub
     }
 
diff --git a/src/main/java/net/onrc/onos/core/flowprogrammer/FlowPusher.java b/src/main/java/net/onrc/onos/core/flowprogrammer/FlowPusher.java
index 37e1b44..17bbc1a 100644
--- a/src/main/java/net/onrc/onos/core/flowprogrammer/FlowPusher.java
+++ b/src/main/java/net/onrc/onos/core/flowprogrammer/FlowPusher.java
@@ -4,7 +4,6 @@
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedList;
@@ -25,48 +24,17 @@
 import net.floodlightcontroller.core.internal.OFMessageFuture;
 import net.floodlightcontroller.core.module.FloodlightModuleContext;
 import net.floodlightcontroller.threadpool.IThreadPoolService;
-import net.floodlightcontroller.util.MACAddress;
 import net.floodlightcontroller.util.OFMessageDamper;
-import net.onrc.onos.core.util.FlowEntry;
-import net.onrc.onos.core.util.FlowEntryAction;
-import net.onrc.onos.core.util.FlowEntryAction.ActionEnqueue;
-import net.onrc.onos.core.util.FlowEntryAction.ActionOutput;
-import net.onrc.onos.core.util.FlowEntryAction.ActionSetEthernetAddr;
-import net.onrc.onos.core.util.FlowEntryAction.ActionSetIPv4Addr;
-import net.onrc.onos.core.util.FlowEntryAction.ActionSetIpToS;
-import net.onrc.onos.core.util.FlowEntryAction.ActionSetTcpUdpPort;
-import net.onrc.onos.core.util.FlowEntryAction.ActionSetVlanId;
-import net.onrc.onos.core.util.FlowEntryAction.ActionSetVlanPriority;
-import net.onrc.onos.core.util.FlowEntryAction.ActionStripVlan;
-import net.onrc.onos.core.util.FlowEntryActions;
-import net.onrc.onos.core.util.FlowEntryMatch;
-import net.onrc.onos.core.util.FlowEntryUserState;
-import net.onrc.onos.core.util.IPv4Net;
+import net.onrc.onos.core.intent.FlowEntry;
 import net.onrc.onos.core.util.Pair;
-import net.onrc.onos.core.util.PortNumber;
 
-import org.openflow.protocol.OFBarrierReply;
-import org.openflow.protocol.OFBarrierRequest;
-import org.openflow.protocol.OFFlowMod;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketOut;
-import org.openflow.protocol.OFPort;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.action.OFAction;
-import org.openflow.protocol.action.OFActionDataLayerDestination;
-import org.openflow.protocol.action.OFActionDataLayerSource;
-import org.openflow.protocol.action.OFActionEnqueue;
-import org.openflow.protocol.action.OFActionNetworkLayerDestination;
-import org.openflow.protocol.action.OFActionNetworkLayerSource;
-import org.openflow.protocol.action.OFActionNetworkTypeOfService;
-import org.openflow.protocol.action.OFActionOutput;
-import org.openflow.protocol.action.OFActionStripVirtualLan;
-import org.openflow.protocol.action.OFActionTransportLayerDestination;
-import org.openflow.protocol.action.OFActionTransportLayerSource;
-import org.openflow.protocol.action.OFActionVirtualLanIdentifier;
-import org.openflow.protocol.action.OFActionVirtualLanPriorityCodePoint;
-import org.openflow.protocol.factory.BasicFactory;
+import org.projectfloodlight.openflow.protocol.OFBarrierReply;
+import org.projectfloodlight.openflow.protocol.OFBarrierRequest;
+import org.projectfloodlight.openflow.protocol.OFFactory;
+import org.projectfloodlight.openflow.protocol.OFFlowMod;
+import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFType;
+import org.projectfloodlight.openflow.protocol.OFVersion;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -75,14 +43,13 @@
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 
 /**
- * FlowPusher is a implementation of FlowPusherService.
- * FlowPusher assigns one message queue instance for each one switch.
- * Number of message processing threads is configurable by constructor, and
- * one thread can handle multiple message queues. Each queue will be assigned to
- * a thread according to hash function defined by getHash().
- * Each processing thread reads messages from queues and sends it to switches
- * in round-robin. Processing thread also calculates rate of sending to suppress
- * excessive message sending.
+ * FlowPusher is a implementation of FlowPusherService. FlowPusher assigns one
+ * message queue instance for each one switch. Number of message processing
+ * threads is configurable by constructor, and one thread can handle multiple
+ * message queues. Each queue will be assigned to a thread according to hash
+ * function defined by getHash(). Each processing thread reads messages from
+ * queues and sends it to switches in round-robin. Processing thread also
+ * calculates rate of sending to suppress excessive message sending.
  */
 public final class FlowPusher implements IFlowPusherService, IOFMessageListener {
     private static final Logger log = LoggerFactory.getLogger(FlowPusher.class);
@@ -91,8 +58,9 @@
     // TODO: Values copied from elsewhere (class LearningSwitch).
     // The local copy should go away!
     //
-    protected static final int OFMESSAGE_DAMPER_CAPACITY = 10000; // TODO: find sweet spot
-    protected static final int OFMESSAGE_DAMPER_TIMEOUT = 250;    // ms
+    protected static final int OFMESSAGE_DAMPER_CAPACITY = 10000; // TODO: find
+                                                                  // sweet spot
+    protected static final int OFMESSAGE_DAMPER_TIMEOUT = 250; // ms
 
     // Number of messages sent to switch at once
     protected static final int MAX_MESSAGE_SEND = 100;
@@ -110,15 +78,15 @@
     }
 
     /**
-     * SwitchQueue represents message queue attached to a switch.
-     * This consists of queue itself and variables used for limiting sending rate.
+     * SwitchQueue represents message queue attached to a switch. This consists
+     * of queue itself and variables used for limiting sending rate.
      */
     private static class SwitchQueue {
         List<Queue<SwitchQueueEntry>> rawQueues;
         QueueState state;
 
         // Max rate of sending message (bytes/ms). 0 implies no limitation.
-        long maxRate = 0;    // 0 indicates no limitation
+        long maxRate = 0; // 0 indicates no limitation
         long lastSentTime = 0;
         long lastSentSize = 0;
 
@@ -137,7 +105,7 @@
 
         /**
          * Check if sending rate is within the rate.
-         *
+         * <p>
          * @param current Current time
          * @return true if within the rate
          */
@@ -158,9 +126,9 @@
 
         /**
          * Log time and size of last sent data.
-         *
+         * <p>
          * @param current Time to be sent.
-         * @param size    Size of sent data (in bytes).
+         * @param size Size of sent data (in bytes).
          */
         void logSentData(long current, long size) {
             lastSentTime = current;
@@ -178,52 +146,52 @@
 
         /**
          * Poll single appropriate entry object according to QueueState.
-         *
+         * <p>
          * @return Entry object.
          */
         SwitchQueueEntry poll() {
             switch (state) {
-                case READY: {
-                    for (int i = 0; i < rawQueues.size(); ++i) {
-                        SwitchQueueEntry entry = rawQueues.get(i).poll();
-                        if (entry != null) {
-                            return entry;
-                        }
+            case READY: {
+                for (int i = 0; i < rawQueues.size(); ++i) {
+                    SwitchQueueEntry entry = rawQueues.get(i).poll();
+                    if (entry != null) {
+                        return entry;
                     }
+                }
 
-                    return null;
-                }
-                case SUSPENDED: {
-                    // Only polling from high priority queue
-                    SwitchQueueEntry entry = getQueue(MsgPriority.HIGH).poll();
-                    return entry;
-                }
-                default:
-                    log.error("Unexpected QueueState: {}", state);
-                    return null;
+                return null;
+            }
+            case SUSPENDED: {
+                // Only polling from high priority queue
+                SwitchQueueEntry entry = getQueue(MsgPriority.HIGH).poll();
+                return entry;
+            }
+            default:
+                log.error("Unexpected QueueState: {}", state);
+                return null;
             }
         }
 
         /**
          * Check if this object has any messages in the queues to be sent.
-         *
+         * <p>
          * @return True if there are some messages to be sent.
          */
         boolean hasMessageToSend() {
             switch (state) {
-                case READY:
-                    for (Queue<SwitchQueueEntry> queue : rawQueues) {
-                        if (!queue.isEmpty()) {
-                            return true;
-                        }
+            case READY:
+                for (Queue<SwitchQueueEntry> queue : rawQueues) {
+                    if (!queue.isEmpty()) {
+                        return true;
                     }
-                    break;
-                case SUSPENDED:
-                    // Only checking high priority queue
-                    return (!getQueue(MsgPriority.HIGH).isEmpty());
-                default:
-                    log.error("Unexpected QueueState: {}", state);
-                    return false;
+                }
+                break;
+            case SUSPENDED:
+                // Only checking high priority queue
+                return (!getQueue(MsgPriority.HIGH).isEmpty());
+            default:
+                log.error("Unexpected QueueState: {}", state);
+                return false;
             }
 
             return false;
@@ -239,7 +207,7 @@
      */
     private static final class BarrierInfo {
         final long dpid;
-        final int xid;
+        final long xid;
 
         static BarrierInfo create(IOFSwitch sw, OFBarrierRequest req) {
             return new BarrierInfo(sw.getId(), req.getXid());
@@ -249,7 +217,7 @@
             return new BarrierInfo(sw.getId(), rpy.getXid());
         }
 
-        private BarrierInfo(long dpid, int xid) {
+        private BarrierInfo(long dpid, long xid) {
             this.dpid = dpid;
             this.xid = xid;
         }
@@ -260,7 +228,7 @@
             final int prime = 31;
             int result = 1;
             result = prime * result + (int) (dpid ^ (dpid >>> 32));
-            result = prime * result + xid;
+            result = prime * result + (int) (xid ^ (xid >>> 32));
             return result;
         }
 
@@ -280,32 +248,30 @@
             return (this.dpid == other.dpid) && (this.xid == other.xid);
         }
 
-
     }
 
+    private FloodlightModuleContext context = null;
     private OFMessageDamper messageDamper = null;
     private IThreadPoolService threadPool = null;
-
-    private FloodlightContext context = null;
-    private BasicFactory factory = null;
+    private IFloodlightProviderService floodlightProvider = null;
+    protected Map<OFVersion, OFFactory> ofFactoryMap = null;
 
     // Map of threads versus dpid
     private Map<Long, FlowPusherThread> threadMap = null;
     // Map from (DPID and transaction ID) to Future objects.
-    private Map<BarrierInfo, OFBarrierReplyFuture> barrierFutures
-            = new ConcurrentHashMap<BarrierInfo, OFBarrierReplyFuture>();
+    private Map<BarrierInfo, OFBarrierReplyFuture> barrierFutures =
+            new ConcurrentHashMap<BarrierInfo, OFBarrierReplyFuture>();
 
     private int numberThread;
 
     /**
      * Main thread that reads messages from queues and sends them to switches.
      */
-    private class FlowPusherThread extends Thread {
-        // Weak ConncurrentHashMap
-        private Map<IOFSwitch, SwitchQueue> assignedQueues
-                = CacheBuilder.newBuilder()
-                    .weakKeys()
-                    .<IOFSwitch, SwitchQueue>build().asMap();
+    private static class FlowPusherThread extends Thread {
+        // Weak ConcurrentHashMap
+        private Map<IOFSwitch, SwitchQueue> assignedQueues = CacheBuilder.newBuilder()
+                .weakKeys()
+                .<IOFSwitch, SwitchQueue>build().asMap();
 
         final Lock queuingLock = new ReentrantLock();
         final Condition messagePushed = queuingLock.newCondition();
@@ -329,9 +295,8 @@
                     }
                 }
 
-                for (Iterator<Entry<IOFSwitch, SwitchQueue>> it = assignedQueues.entrySet().iterator();
-                        it.hasNext();
-                        ) {
+                for (Iterator<Entry<IOFSwitch, SwitchQueue>> it = assignedQueues
+                        .entrySet().iterator(); it.hasNext();) {
                     Entry<IOFSwitch, SwitchQueue> entry = it.next();
                     IOFSwitch sw = entry.getKey();
                     SwitchQueue queue = entry.getValue();
@@ -352,13 +317,13 @@
         }
 
         /**
-         * Read messages from queue and send them to the switch.
-         * If number of messages excess the limit, stop sending messages.
-         *
-         * @param sw      Switch to which messages will be sent.
-         * @param queue   Queue of messages.
-         * @param maxMsg Limitation of number of messages to be sent. If set to 0,
-         *                all messages in queue will be sent.
+         * Read messages from queue and send them to the switch. If number of
+         * messages excess the limit, stop sending messages.
+         * <p>
+         * @param sw Switch to which messages will be sent.
+         * @param queue Queue of messages.
+         * @param maxMsg Limitation of number of messages to be sent. If set to
+         *        0, all messages in queue will be sent.
          */
         private void processQueue(IOFSwitch sw, SwitchQueue queue, int maxMsg) {
             // check sending rate and determine it to be sent or not
@@ -381,11 +346,14 @@
 
                     OFMessage msg = queueEntry.getOFMessage();
                     try {
-                        messageDamper.write(sw, msg, context);
+                        // TODO BOC do we need to use the message damper?
+                        // messageDamper.write(sw, msg, context);
+                        sw.write(msg, null);
                         if (log.isTraceEnabled()) {
-                            log.trace("Pusher sends message: {}", msg);
+                            log.trace("Pusher sends message to switch {}: {}", sw.getStringId(), msg);
                         }
-                        size += msg.getLength();
+                        // TODO BOC how do we get the size?
+                        // size += msg.getLength();
                     } catch (IOException e) {
                         log.error("Exception in sending message (" + msg + "):", e);
                     }
@@ -425,7 +393,7 @@
 
     /**
      * Initialize object with threads of given number.
-     *
+     * <p>
      * @param numberThreadValue Number of threads to handle messages.
      */
     public FlowPusher(int numberThreadValue) {
@@ -438,44 +406,42 @@
 
     /**
      * Set parameters needed for sending messages.
-     *
-     * @param floodlightContext    FloodlightContext used for sending messages.
-     *                   If null, FlowPusher uses default context.
-     * @param modContext FloodlightModuleContext used for acquiring
-     *                   ThreadPoolService and registering MessageListener.
-     * @param basicFactory    Factory object to create OFMessage objects.
-     * @param damper     Message damper used for sending messages.
-     *                   If null, FlowPusher creates its own damper object.
+     * <p>
+     * @param floodlightContext FloodlightModuleContext used for acquiring
+     *        ThreadPoolService and registering MessageListener.
      */
-    public void init(FloodlightContext floodlightContext,
-                     FloodlightModuleContext modContext,
-                     BasicFactory basicFactory,
-                     OFMessageDamper damper) {
-        context = floodlightContext;
-        factory = basicFactory;
-        this.threadPool = modContext.getServiceImpl(IThreadPoolService.class);
-        IFloodlightProviderService flservice
-                = modContext.getServiceImpl(IFloodlightProviderService.class);
-        flservice.addOFMessageListener(OFType.BARRIER_REPLY, this);
+    public void init(FloodlightModuleContext floodlightContext) {
+        this.context = floodlightContext;
+        this.floodlightProvider = context
+                .getServiceImpl(IFloodlightProviderService.class);
+        this.threadPool = context.getServiceImpl(IThreadPoolService.class);
+        this.messageDamper = null;
 
-        if (damper != null) {
-            messageDamper = damper;
-        } else {
-            // use default values
-            messageDamper = new OFMessageDamper(OFMESSAGE_DAMPER_CAPACITY,
-                    EnumSet.of(OFType.FLOW_MOD),
-                    OFMESSAGE_DAMPER_TIMEOUT);
-        }
+        ofFactoryMap = new HashMap<>();
+        ofFactoryMap.put(OFVersion.OF_10, floodlightProvider.getOFMessageFactory_10());
+        ofFactoryMap.put(OFVersion.OF_13, floodlightProvider.getOFMessageFactory_13());
+        floodlightProvider.addOFMessageListener(OFType.BARRIER_REPLY, this);
+
+        // TODO BOC message damper may not be needed...
+        // if (damper != null) {
+        // messageDamper = damper;
+        // } else {
+        // use default values
+        /*messageDamper = new OFMessageDamper(OFMESSAGE_DAMPER_CAPACITY,
+                EnumSet.of(OFType.FLOW_MOD),
+                OFMESSAGE_DAMPER_TIMEOUT);*/
+        // }
     }
 
     /**
      * Begin processing queue.
      */
     public void start() {
-        if (factory == null) {
-            log.error("FlowPusher not yet initialized.");
-            return;
-        }
+        // TODO BOC
+        // if (factory == null) {
+        // log.error("FlowPusher not yet initialized.");
+        // return;
+        // }
 
         threadMap = new HashMap<Long, FlowPusherThread>();
         for (long i = 0; i < numberThread; ++i) {
@@ -491,7 +457,8 @@
         SwitchQueue queue = getQueue(sw);
 
         if (queue == null) {
-            // create queue in case suspend is called before first message addition
+            // create queue in case suspend is called before first message
+            // addition
             queue = createQueueImpl(sw);
         }
 
@@ -509,7 +476,7 @@
         SwitchQueue queue = getQueue(sw);
 
         if (queue == null) {
-            log.error("No queue is attached to DPID: {}", sw.getId());
+            log.error("No queue is attached to DPID: {}", sw.getStringId());
             return false;
         }
 
@@ -560,7 +527,7 @@
         }
 
         if (rate > 0) {
-            log.debug("rate for {} is set to {}", sw.getId(), rate);
+            log.debug("rate for {} is set to {}", sw.getStringId(), rate);
             synchronized (queue) {
                 queue.maxRate = rate;
             }
@@ -569,7 +536,7 @@
 
     @Override
     @SuppressFBWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE",
-                        justification = "Future versions of createQueueImpl() might return null")
+            justification = "Future versions of createQueueImpl() might return null")
     public boolean createQueue(IOFSwitch sw) {
         SwitchQueue queue = createQueueImpl(sw);
 
@@ -619,13 +586,12 @@
 
     /**
      * Invalidate.
-     *
+     * <p>
      * @param sw switch
-     *
      * @see OFMessageDamper#invalidate(IOFSwitch)
      */
     public void invalidate(IOFSwitch sw) {
-        messageDamper.invalidate(sw);
+        // messageDamper.invalidate(sw); currently a null ptr - commenting out
     }
 
     @Override
@@ -668,226 +634,9 @@
     }
 
     /**
-     * Fetch the match conditions.
-     * NOTE: The Flow matching conditions common for all Flow Entries are
-     * used ONLY if a Flow Entry does NOT have the corresponding matching
-     * condition set.
-     *
-     * @param flowEntryMatch Flow entry to create a matcher for
-     * @return open flow matcher for the given values
-     */
-    private OFMatch computeMatch(FlowEntryMatch flowEntryMatch) {
-        OFMatch match = new OFMatch();
-        match.setWildcards(OFMatch.OFPFW_ALL);
-
-        // Match the Incoming Port
-        PortNumber matchInPort = flowEntryMatch.inPort();
-        if (matchInPort != null) {
-            match.setInputPort(matchInPort.shortValue());
-            match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_IN_PORT);
-        }
-
-        // Match the Source MAC address
-        MACAddress matchSrcMac = flowEntryMatch.srcMac();
-        if (matchSrcMac != null) {
-            match.setDataLayerSource(matchSrcMac.toString());
-            match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_SRC);
-        }
-
-        // Match the Destination MAC address
-        MACAddress matchDstMac = flowEntryMatch.dstMac();
-        if (matchDstMac != null) {
-            match.setDataLayerDestination(matchDstMac.toString());
-            match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_DST);
-        }
-
-        // Match the Ethernet Frame Type
-        Short matchEthernetFrameType = flowEntryMatch.ethernetFrameType();
-        if (matchEthernetFrameType != null) {
-            match.setDataLayerType(matchEthernetFrameType);
-            match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_TYPE);
-        }
-
-        // Match the VLAN ID
-        Short matchVlanId = flowEntryMatch.vlanId();
-        if (matchVlanId != null) {
-            match.setDataLayerVirtualLan(matchVlanId);
-            match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_VLAN);
-        }
-
-        // Match the VLAN priority
-        Byte matchVlanPriority = flowEntryMatch.vlanPriority();
-        if (matchVlanPriority != null) {
-            match.setDataLayerVirtualLanPriorityCodePoint(matchVlanPriority);
-            match.setWildcards(match.getWildcards()
-                    & ~OFMatch.OFPFW_DL_VLAN_PCP);
-        }
-
-        // Match the Source IPv4 Network prefix
-        IPv4Net matchSrcIPv4Net = flowEntryMatch.srcIPv4Net();
-        if (matchSrcIPv4Net != null) {
-            match.setFromCIDR(matchSrcIPv4Net.toString(), OFMatch.STR_NW_SRC);
-        }
-
-        // Natch the Destination IPv4 Network prefix
-        IPv4Net matchDstIPv4Net = flowEntryMatch.dstIPv4Net();
-        if (matchDstIPv4Net != null) {
-            match.setFromCIDR(matchDstIPv4Net.toString(), OFMatch.STR_NW_DST);
-        }
-
-        // Match the IP protocol
-        Byte matchIpProto = flowEntryMatch.ipProto();
-        if (matchIpProto != null) {
-            match.setNetworkProtocol(matchIpProto);
-            match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_NW_PROTO);
-        }
-
-        // Match the IP ToS (DSCP field, 6 bits)
-        Byte matchIpToS = flowEntryMatch.ipToS();
-        if (matchIpToS != null) {
-            match.setNetworkTypeOfService(matchIpToS);
-            match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_NW_TOS);
-        }
-
-        // Match the Source TCP/UDP port
-        Short matchSrcTcpUdpPort = flowEntryMatch.srcTcpUdpPort();
-        if (matchSrcTcpUdpPort != null) {
-            match.setTransportSource(matchSrcTcpUdpPort);
-            match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_TP_SRC);
-        }
-
-        // Match the Destination TCP/UDP port
-        Short matchDstTcpUdpPort = flowEntryMatch.dstTcpUdpPort();
-        if (matchDstTcpUdpPort != null) {
-            match.setTransportDestination(matchDstTcpUdpPort);
-            match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_TP_DST);
-        }
-
-        return match;
-    }
-
-
-    /**
-     * Wrapper object to hold a port number.  Used to pass around output ports.
-     */
-    private static class OutputPort {
-        private Short portNumber;
-    }
-
-    /**
-     * Process a flow action entry, putting the resulting flow
-     * actions into a list.  Will also set the actionOutputPort
-     * if one is encountered while processing an action.
-     *
-     * @param action Flow Entry Action to process
-     * @param openFlowActions actions to perform get added to this list
-     * @param actionOutputPort this will get set if an action output
-     *                         port is found
-     */
-    private void processAction(final FlowEntryAction action,
-                               final List<OFAction> openFlowActions,
-                               final OutputPort actionOutputPort) {
-        ActionOutput actionOutput = action.actionOutput();
-        ActionSetVlanId actionSetVlanId = action.actionSetVlanId();
-        ActionSetVlanPriority actionSetVlanPriority = action
-            .actionSetVlanPriority();
-        ActionStripVlan actionStripVlan = action.actionStripVlan();
-        ActionSetEthernetAddr actionSetEthernetSrcAddr = action
-            .actionSetEthernetSrcAddr();
-        ActionSetEthernetAddr actionSetEthernetDstAddr = action
-            .actionSetEthernetDstAddr();
-        ActionSetIPv4Addr actionSetIPv4SrcAddr = action
-            .actionSetIPv4SrcAddr();
-        ActionSetIPv4Addr actionSetIPv4DstAddr = action
-            .actionSetIPv4DstAddr();
-        ActionSetIpToS actionSetIpToS = action.actionSetIpToS();
-        ActionSetTcpUdpPort actionSetTcpUdpSrcPort = action
-            .actionSetTcpUdpSrcPort();
-        ActionSetTcpUdpPort actionSetTcpUdpDstPort = action
-            .actionSetTcpUdpDstPort();
-        ActionEnqueue actionEnqueue = action.actionEnqueue();
-
-        if (actionOutput != null) {
-            actionOutputPort.portNumber = actionOutput.port().shortValue();
-            // XXX: The max length is hard-coded for now
-            OFActionOutput ofa = new OFActionOutput(actionOutput.port()
-                                                    .shortValue(), (short) 0xffff);
-            openFlowActions.add(ofa);
-        }
-
-        if (actionSetVlanId != null) {
-            OFActionVirtualLanIdentifier ofa =
-                new OFActionVirtualLanIdentifier(actionSetVlanId.vlanId());
-            openFlowActions.add(ofa);
-        }
-
-        if (actionSetVlanPriority != null) {
-            OFActionVirtualLanPriorityCodePoint ofa =
-                new OFActionVirtualLanPriorityCodePoint(actionSetVlanPriority.vlanPriority());
-            openFlowActions.add(ofa);
-        }
-
-        if (actionStripVlan != null) {
-            if (actionStripVlan.stripVlan()) {
-                OFActionStripVirtualLan ofa = new OFActionStripVirtualLan();
-                openFlowActions.add(ofa);
-            }
-        }
-
-        if (actionSetEthernetSrcAddr != null) {
-            OFActionDataLayerSource ofa =
-                new OFActionDataLayerSource(actionSetEthernetSrcAddr.addr().toBytes());
-            openFlowActions.add(ofa);
-        }
-
-        if (actionSetEthernetDstAddr != null) {
-            OFActionDataLayerDestination ofa =
-                new OFActionDataLayerDestination(actionSetEthernetDstAddr.addr().toBytes());
-            openFlowActions.add(ofa);
-        }
-
-        if (actionSetIPv4SrcAddr != null) {
-            OFActionNetworkLayerSource ofa =
-                new OFActionNetworkLayerSource(actionSetIPv4SrcAddr.addr().value());
-            openFlowActions.add(ofa);
-        }
-
-        if (actionSetIPv4DstAddr != null) {
-            OFActionNetworkLayerDestination ofa =
-                new OFActionNetworkLayerDestination(actionSetIPv4DstAddr.addr().value());
-            openFlowActions.add(ofa);
-        }
-
-        if (actionSetIpToS != null) {
-            OFActionNetworkTypeOfService ofa =
-                new OFActionNetworkTypeOfService(actionSetIpToS.ipToS());
-            openFlowActions.add(ofa);
-        }
-
-        if (actionSetTcpUdpSrcPort != null) {
-            OFActionTransportLayerSource ofa =
-                new OFActionTransportLayerSource(actionSetTcpUdpSrcPort.port());
-            openFlowActions.add(ofa);
-        }
-
-        if (actionSetTcpUdpDstPort != null) {
-            OFActionTransportLayerDestination ofa =
-                new OFActionTransportLayerDestination(actionSetTcpUdpDstPort.port());
-            openFlowActions.add(ofa);
-        }
-
-        if (actionEnqueue != null) {
-            OFActionEnqueue ofa =
-                new OFActionEnqueue(actionEnqueue.port().shortValue(), actionEnqueue.queueId());
-            openFlowActions.add(ofa);
-        }
-    }
-
-
-    /**
      * Create a message from FlowEntry and add it to the queue of the switch.
-     *
-     * @param sw        Switch to which message is pushed.
+     * <p>
+     * @param sw Switch to which message is pushed.
      * @param flowEntry FlowEntry object used for creating message.
      * @return true if message is successfully added to a queue.
      */
@@ -895,90 +644,14 @@
         //
         // Create the OpenFlow Flow Modification Entry to push
         //
-        OFFlowMod fm = (OFFlowMod) factory.getMessage(OFType.FLOW_MOD);
-        long cookie = flowEntry.flowEntryId().value();
-
-        short flowModCommand = OFFlowMod.OFPFC_ADD;
-        if (flowEntry.flowEntryUserState() == FlowEntryUserState.FE_USER_ADD) {
-            flowModCommand = OFFlowMod.OFPFC_ADD;
-        } else if (flowEntry.flowEntryUserState() == FlowEntryUserState.FE_USER_MODIFY) {
-            flowModCommand = OFFlowMod.OFPFC_MODIFY_STRICT;
-        } else if (flowEntry.flowEntryUserState() == FlowEntryUserState.FE_USER_DELETE) {
-            flowModCommand = OFFlowMod.OFPFC_DELETE_STRICT;
-        } else {
-            // Unknown user state. Ignore the entry
-            log.debug(
-                    "Flow Entry ignored (FlowEntryId = {}): unknown user state {}",
-                    flowEntry.flowEntryId(),
-                    flowEntry.flowEntryUserState());
-            return false;
-        }
-
-        final FlowEntryMatch flowEntryMatch = flowEntry.flowEntryMatch();
-        final OFMatch match = computeMatch(flowEntryMatch);
-
-        final PortNumber matchInPort = flowEntryMatch.inPort();
-        final MACAddress matchSrcMac = flowEntryMatch.srcMac();
-        final MACAddress matchDstMac = flowEntryMatch.dstMac();
-
-        //
-        // Fetch the actions
-        //
-        final List<OFAction> openFlowActions = new ArrayList<OFAction>();
-        final FlowEntryActions flowEntryActions = flowEntry.flowEntryActions();
-        //
-        final OutputPort actionOutputPort = new OutputPort();
-        for (FlowEntryAction action : flowEntryActions.actions()) {
-            processAction(action, openFlowActions, actionOutputPort);
-        }
-        int actionsLen = 0;
-        for (OFAction ofa : openFlowActions) {
-            actionsLen += ofa.getLength();
-        }
-
-        fm.setIdleTimeout((short) flowEntry.idleTimeout())
-                .setHardTimeout((short) flowEntry.hardTimeout())
-                .setPriority((short) flowEntry.priority())
-                .setBufferId(OFPacketOut.BUFFER_ID_NONE).setCookie(cookie)
-                .setCommand(flowModCommand).setMatch(match)
-                .setActions(openFlowActions)
-                .setLengthU(OFFlowMod.MINIMUM_LENGTH + actionsLen);
-        fm.setOutPort(OFPort.OFPP_NONE.getValue());
-        if ((flowModCommand == OFFlowMod.OFPFC_DELETE)
-                || (flowModCommand == OFFlowMod.OFPFC_DELETE_STRICT)) {
-            if (actionOutputPort.portNumber != null) {
-                fm.setOutPort(actionOutputPort.portNumber);
-            }
-        }
-
-        //
-        // Set the OFPFF_SEND_FLOW_REM flag if the Flow Entry is not
-        // permanent.
-        //
-        if ((flowEntry.idleTimeout() != 0) ||
-                (flowEntry.hardTimeout() != 0)) {
-            fm.setFlags(OFFlowMod.OFPFF_SEND_FLOW_REM);
-        }
-
-        if (log.isTraceEnabled()) {
-            log.trace("Installing flow entry {} into switch DPID: {} " +
-                    "flowEntryId: {} srcMac: {} dstMac: {} inPort: {} outPort: {}"
-                    , flowEntry.flowEntryUserState()
-                    , sw.getStringId()
-                    , flowEntry.flowEntryId()
-                    , matchSrcMac
-                    , matchDstMac
-                    , matchInPort
-                    , actionOutputPort
-            );
-        }
-
+        OFFlowMod fm = flowEntry.buildFlowMod(ofFactoryMap.get(sw.getOFVersion()));
+        // log.trace("Pushing flow mod {}", fm);
         return addMessageImpl(sw, fm, priority);
     }
 
     /**
      * Add message to queue.
-     *
+     * <p>
      * @param sw
      * @param msg
      * @param priority
@@ -999,7 +672,7 @@
         synchronized (queue) {
             queue.add(entry, priority);
             if (log.isTraceEnabled()) {
-                log.trace("Message is pushed: {}", entry.getOFMessage());
+                log.trace("Message is pushed to switch {}: {}", sw.getStringId(), entry.getOFMessage());
             }
         }
 
@@ -1014,20 +687,18 @@
         if (future == null) {
             return null;
         }
-
         try {
             return future.get();
         } catch (InterruptedException e) {
             log.error("InterruptedException", e);
-            return null;
         } catch (ExecutionException e) {
             log.error("ExecutionException", e);
-            return null;
         }
+        return null;
     }
 
     @Override
-    public OFBarrierReplyFuture barrierAsync(IOFSwitch sw) {
+    public OFMessageFuture<OFBarrierReply> barrierAsync(IOFSwitch sw) {
         // TODO creation of message and future should be moved to OFSwitchImpl
 
         if (sw == null) {
@@ -1035,25 +706,28 @@
         }
 
         OFBarrierRequest msg = createBarrierRequest(sw);
-
-        OFBarrierReplyFuture future = new OFBarrierReplyFuture(threadPool, sw, msg.getXid());
+        OFBarrierReplyFuture future = new OFBarrierReplyFuture(threadPool, sw,
+                (int) msg.getXid());
         barrierFutures.put(BarrierInfo.create(sw, msg), future);
-
         addMessageImpl(sw, msg, MsgPriority.NORMAL);
-
         return future;
     }
 
     protected OFBarrierRequest createBarrierRequest(IOFSwitch sw) {
-        OFBarrierRequest msg = (OFBarrierRequest) factory.getMessage(OFType.BARRIER_REQUEST);
-        msg.setXid(sw.getNextTransactionId());
-
-        return msg;
+        OFFactory factory = ofFactoryMap.get(sw.getOFVersion());
+        if (factory == null) {
+            log.error("No OF Message Factory for switch {} with OFVersion {}", sw,
+                    sw.getOFVersion());
+            return null;
+        }
+        return factory.buildBarrierRequest()
+                .setXid(sw.getNextTransactionId())
+                .build();
     }
 
     /**
      * Get a queue attached to a switch.
-     *
+     * <p>
      * @param sw Switch object
      * @return Queue object
      */
@@ -1072,7 +746,7 @@
 
     /**
      * Get a hash value correspondent to a switch.
-     *
+     * <p>
      * @param sw Switch object
      * @return Hash value
      */
@@ -1084,7 +758,7 @@
 
     /**
      * Get a Thread object which processes the queue attached to a switch.
-     *
+     * <p>
      * @param sw Switch object
      * @return Thread object
      */
@@ -1112,18 +786,17 @@
     @Override
     public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
         if (log.isTraceEnabled()) {
-            log.trace("Received BARRIER_REPLY from: {}", sw.getId());
+            log.trace("Received BARRIER_REPLY from : {}", sw.getStringId());
         }
 
         if ((msg.getType() != OFType.BARRIER_REPLY) ||
-            !(msg instanceof OFBarrierReply)) {
+                !(msg instanceof OFBarrierReply)) {
             log.error("Unexpected reply message: {}", msg.getType());
             return Command.CONTINUE;
         }
 
         OFBarrierReply reply = (OFBarrierReply) msg;
         BarrierInfo info = BarrierInfo.create(sw, reply);
-
         // Deliver future if exists
         OFBarrierReplyFuture future = barrierFutures.get(info);
         if (future != null) {
@@ -1133,4 +806,5 @@
 
         return Command.CONTINUE;
     }
+
 }
diff --git a/src/main/java/net/onrc/onos/core/flowprogrammer/FlowSynchronizer.java b/src/main/java/net/onrc/onos/core/flowprogrammer/FlowSynchronizer.java
index af3cc70..7b2bfd0 100644
--- a/src/main/java/net/onrc/onos/core/flowprogrammer/FlowSynchronizer.java
+++ b/src/main/java/net/onrc/onos/core/flowprogrammer/FlowSynchronizer.java
@@ -1,6 +1,5 @@
 package net.onrc.onos.core.flowprogrammer;
 
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -8,12 +7,10 @@
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 import java.util.concurrent.FutureTask;
 
 import net.floodlightcontroller.core.IOFSwitch;
-import net.onrc.onos.core.flowprogrammer.IFlowPusherService.MsgPriority;
 import net.onrc.onos.core.util.FlowEntryId;
 
 import org.openflow.protocol.OFFlowMod;
@@ -99,10 +96,6 @@
                 Set<FlowEntryWrapper> graphEntries = getFlowEntriesFromGraph();
                 long step1 = System.nanoTime();
                 Set<FlowEntryWrapper> switchEntries = getFlowEntriesFromSwitch();
-                if (switchEntries == null) {
-                    log.debug("getFlowEntriesFromSwitch() failed");
-                    return null;
-                }
                 long step2 = System.nanoTime();
                 SyncResult result = compare(graphEntries, switchEntries);
                 long step3 = System.nanoTime();
@@ -184,12 +177,12 @@
             Set<FlowEntryWrapper> entries = new HashSet<FlowEntryWrapper>();
 
             // TODO: fix when FlowSynchronizer is refactored
-        /*
+            /*
         for(IFlowEntry entry : swObj.getFlowEntries()) {
         FlowEntryWrapper fe = new FlowEntryWrapper(entry);
         entries.add(fe);
         }
-        */
+             */
             return entries;
         }
 
@@ -218,8 +211,9 @@
             lengthU += req.getLengthU();
             req.setLengthU(lengthU);
 
-            List<OFStatistics> entries = null;
-            try {
+            //List<OFStatistics> entries = null;
+            // XXX S when we fix stats, we fix this
+            /*try {
                 Future<List<OFStatistics>> dfuture = sw.getStatistics(req);
                 entries = dfuture.get();
             } catch (IOException e) {
@@ -231,14 +225,16 @@
             } catch (ExecutionException e) {
                 log.error("Error getting statistics", e);
                 return null;
-            }
+            }*/
 
             Set<FlowEntryWrapper> results = new HashSet<FlowEntryWrapper>();
+            /*
             for (OFStatistics result : entries) {
                 OFFlowStatisticsReply entry = (OFFlowStatisticsReply) result;
                 FlowEntryWrapper fe = new FlowEntryWrapper(entry);
                 results.add(fe);
             }
+             */
             return results;
         }
 
@@ -248,7 +244,7 @@
      * FlowEntryWrapper represents abstract FlowEntry which is embodied
      * by FlowEntryId (from GraphDB) or OFFlowStatisticsReply (from switch).
      */
-    class FlowEntryWrapper {
+    static class FlowEntryWrapper {
         FlowEntryId flowEntryId;
         // TODO: fix when FlowSynchronizer is refactored
         // IFlowEntry iFlowEntry;
@@ -256,12 +252,12 @@
 
 
         // TODO: fix when FlowSynchronizer is refactored
-    /*
+        /*
     public FlowEntryWrapper(IFlowEntry entry) {
         flowEntryId = new FlowEntryId(entry.getFlowEntryId());
         iFlowEntry = entry;
     }
-    */
+         */
 
         public FlowEntryWrapper(OFFlowStatisticsReply entry) {
             flowEntryId = new FlowEntryId(entry.getCookie());
@@ -285,7 +281,7 @@
             double startDB = System.nanoTime();
             // Get the Flow Entry state from the Network Graph
             // TODO: fix when FlowSynchronizer is refactored
-        /*
+            /*
         if (iFlowEntry == null) {
             try {
         // TODO: fix when FlowSynchronizer is refactored
@@ -296,13 +292,13 @@
                 return;
             }
         }
-        */
+             */
             dbTime = System.nanoTime() - startDB;
 
             //
             // TODO: The old FlowDatabaseOperation class is gone, so the code
             //
-        /*
+            /*
         double startExtract = System.nanoTime();
         FlowEntry flowEntry =
         FlowDatabaseOperation.extractFlowEntry(iFlowEntry);
@@ -316,7 +312,7 @@
         double startPush = System.nanoTime();
         pusher.pushFlowEntry(sw, flowEntry, MsgPriority.HIGH);
         pushTime = System.nanoTime() - startPush;
-        */
+             */
         }
 
         /**
@@ -340,7 +336,8 @@
             fm.setPriority(statisticsReply.getPriority());
             fm.setOutPort(OFPort.OFPP_NONE);
 
-            pusher.add(sw, fm, MsgPriority.HIGH);
+            // XXX BOC commented out pending FlowSync refactor
+            //pusher.add(sw, fm, MsgPriority.HIGH);
         }
 
         /**
diff --git a/src/main/java/net/onrc/onos/core/flowprogrammer/IFlowPusherService.java b/src/main/java/net/onrc/onos/core/flowprogrammer/IFlowPusherService.java
index 37911a8..e94119a 100644
--- a/src/main/java/net/onrc/onos/core/flowprogrammer/IFlowPusherService.java
+++ b/src/main/java/net/onrc/onos/core/flowprogrammer/IFlowPusherService.java
@@ -5,11 +5,11 @@
 import net.floodlightcontroller.core.IOFSwitch;
 import net.floodlightcontroller.core.internal.OFMessageFuture;
 import net.floodlightcontroller.core.module.IFloodlightService;
-import net.onrc.onos.core.util.FlowEntry;
+import net.onrc.onos.core.intent.FlowEntry;
 import net.onrc.onos.core.util.Pair;
 
-import org.openflow.protocol.OFBarrierReply;
-import org.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFBarrierReply;
+import org.projectfloodlight.openflow.protocol.OFMessage;
 
 /**
  * FlowPusherService is a service to send message to switches in proper rate.
diff --git a/src/main/java/net/onrc/onos/core/flowprogrammer/OFBarrierReplyFuture.java b/src/main/java/net/onrc/onos/core/flowprogrammer/OFBarrierReplyFuture.java
index bbd10cb..3991019 100644
--- a/src/main/java/net/onrc/onos/core/flowprogrammer/OFBarrierReplyFuture.java
+++ b/src/main/java/net/onrc/onos/core/flowprogrammer/OFBarrierReplyFuture.java
@@ -6,22 +6,24 @@
 import net.floodlightcontroller.core.internal.OFMessageFuture;
 import net.floodlightcontroller.threadpool.IThreadPoolService;
 
-import org.openflow.protocol.OFBarrierReply;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFType;
+import org.projectfloodlight.openflow.protocol.OFBarrierReply;
+import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFType;
+
+//XXX S note that other places are using old OFBarrierReply - so we broke that
 
 public class OFBarrierReplyFuture extends OFMessageFuture<OFBarrierReply> {
 
     protected volatile boolean finished;
 
     public OFBarrierReplyFuture(IThreadPoolService tp,
-                                IOFSwitch sw, int transactionId) {
+            IOFSwitch sw, int transactionId) {
         super(tp, sw, OFType.FEATURES_REPLY, transactionId);
         init();
     }
 
     public OFBarrierReplyFuture(IThreadPoolService tp,
-                                IOFSwitch sw, int transactionId, long timeout, TimeUnit unit) {
+            IOFSwitch sw, int transactionId, long timeout, TimeUnit unit) {
         super(tp, sw, OFType.FEATURES_REPLY, transactionId, timeout, unit);
         init();
     }
diff --git a/src/main/java/net/onrc/onos/core/flowprogrammer/web/SendBarrierResource.java b/src/main/java/net/onrc/onos/core/flowprogrammer/web/SendBarrierResource.java
index 236cc85..4fc6782 100644
--- a/src/main/java/net/onrc/onos/core/flowprogrammer/web/SendBarrierResource.java
+++ b/src/main/java/net/onrc/onos/core/flowprogrammer/web/SendBarrierResource.java
@@ -2,8 +2,8 @@
 
 import net.floodlightcontroller.core.IOFSwitch;
 
-import org.openflow.protocol.OFBarrierReply;
 import org.openflow.util.HexString;
+import org.projectfloodlight.openflow.protocol.OFBarrierReply;
 import org.restlet.resource.Get;
 
 /**
diff --git a/src/main/java/net/onrc/onos/core/hostmanager/HostManager.java b/src/main/java/net/onrc/onos/core/hostmanager/HostManager.java
index 6843fa9..9f6373d 100644
--- a/src/main/java/net/onrc/onos/core/hostmanager/HostManager.java
+++ b/src/main/java/net/onrc/onos/core/hostmanager/HostManager.java
@@ -30,15 +30,15 @@
 import net.onrc.onos.core.util.Dpid;
 import net.onrc.onos.core.util.PortNumber;
 
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFType;
+import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFPacketIn;
+import org.projectfloodlight.openflow.protocol.OFType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public class HostManager implements IFloodlightModule,
-        IOFMessageListener,
-        IHostService {
+IOFMessageListener,
+IHostService {
 
     private static final Logger log = LoggerFactory.getLogger(HostManager.class);
     private static final long HOST_CLEANING_INITIAL_DELAY = 30;
@@ -106,8 +106,10 @@
 
             Ethernet eth = IFloodlightProviderService.bcStore.
                     get(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
+            short inport = (short) cntx.getStorage()
+                    .get(IFloodlightProviderService.CONTEXT_PI_INPORT);
 
-            return processPacketIn(sw, pi, eth);
+            return processPacketIn(sw, pi, eth, inport);
         }
 
         return Command.CONTINUE;
@@ -116,13 +118,14 @@
     // This "protected" modifier is for unit test.
     // The above "receive" method couldn't be tested
     // because of IFloodlightProviderService static final field.
-    protected Command processPacketIn(IOFSwitch sw, OFPacketIn pi, Ethernet eth) {
+    protected Command processPacketIn(IOFSwitch sw, OFPacketIn pi, Ethernet eth,
+            short inport) {
         if (log.isTraceEnabled()) {
             log.trace("Receive PACKET_IN swId {}, portId {}", sw.getId(), pi.getInPort());
         }
 
         final Dpid dpid = new Dpid(sw.getId());
-        final PortNumber portNum = new PortNumber(pi.getInPort());
+        final PortNumber portNum = new PortNumber(inport);
 
         Host srcHost =
                 getSourceHostFromPacket(eth, dpid.value(), portNum.value());
@@ -140,8 +143,8 @@
             if (topology.getOutgoingLink(dpid, portNum) != null ||
                     topology.getIncomingLink(dpid, portNum) != null) {
                 log.debug("Not adding host {} as " +
-                    "there is a link on the port: dpid {} port {}",
-                    srcHost.getMacAddress(), dpid, portNum);
+                        "there is a link on the port: dpid {} port {}",
+                        srcHost.getMacAddress(), dpid, portNum);
                 return Command.CONTINUE;
             }
         } finally {
diff --git a/src/main/java/net/onrc/onos/core/intent/Action.java b/src/main/java/net/onrc/onos/core/intent/Action.java
index 100dc33..8f8c8b2 100644
--- a/src/main/java/net/onrc/onos/core/intent/Action.java
+++ b/src/main/java/net/onrc/onos/core/intent/Action.java
@@ -2,6 +2,9 @@
 
 import net.onrc.onos.core.util.FlowEntryAction;
 
+import org.projectfloodlight.openflow.protocol.OFFactory;
+import org.projectfloodlight.openflow.protocol.action.OFAction;
+
 /**
  * An abstract class that represents an OpenFlow action.
  */
@@ -14,4 +17,12 @@
      * @return an equivalent FlowEntryAction object
      */
     public abstract FlowEntryAction getFlowEntryAction();
+
+    /**
+     * Builds and returns an OFAction given an OFFactory.
+     *
+     * @param factory the OFFactory to use for building
+     * @return the OFAction
+     */
+    public abstract OFAction getOFAction(OFFactory factory);
 }
diff --git a/src/main/java/net/onrc/onos/core/intent/FlowEntry.java b/src/main/java/net/onrc/onos/core/intent/FlowEntry.java
index c738cbc..0fd618e 100644
--- a/src/main/java/net/onrc/onos/core/intent/FlowEntry.java
+++ b/src/main/java/net/onrc/onos/core/intent/FlowEntry.java
@@ -1,22 +1,32 @@
 package net.onrc.onos.core.intent;
 
+import java.util.ArrayList;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Objects;
 import java.util.Set;
 
 import net.floodlightcontroller.util.MACAddress;
 import net.onrc.onos.core.intent.IntentOperation.Operator;
-import net.onrc.onos.core.util.Dpid;
-import net.onrc.onos.core.util.FlowEntryActions;
-import net.onrc.onos.core.util.FlowEntryId;
-import net.onrc.onos.core.util.FlowEntryUserState;
+
+import org.projectfloodlight.openflow.protocol.OFActionType;
+import org.projectfloodlight.openflow.protocol.OFFactory;
+import org.projectfloodlight.openflow.protocol.OFFlowMod;
+import org.projectfloodlight.openflow.protocol.action.OFAction;
+import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
+import org.projectfloodlight.openflow.protocol.match.Match.Builder;
+import org.projectfloodlight.openflow.types.OFBufferId;
+import org.projectfloodlight.openflow.types.OFPort;
+import org.projectfloodlight.openflow.types.U64;
 
 /**
- * A class to represent an OpenFlow FlowMod.
+ * A class to represent an OpenFlow FlowMod. <br>
  * It is OpenFlow v.1.0-centric and contains a Match and an Action.
  */
 
 public class FlowEntry {
+    public static final int PRIORITY_DEFAULT = 32768; // Default Flow Priority
+
     protected long sw;
     protected Match match;
     protected Set<Action> actions;
@@ -37,12 +47,12 @@
      * @param dstIpAddress destination IP address
      * @param operator OpenFlow operation/command (add, remove, etc.)
      */
-// CHECKSTYLE:OFF suppress the warning about too many parameters
+    // CHECKSTYLE:OFF suppress the warning about too many parameters
     public FlowEntry(long sw, long srcPort, long dstPort,
-                     MACAddress srcMac, MACAddress dstMac,
-                     int srcIpAddress, int dstIpAddress,
-                     Operator operator) {
-// CHECKSTYLE:ON
+            MACAddress srcMac, MACAddress dstMac,
+            int srcIpAddress, int dstIpAddress,
+            Operator operator) {
+        // CHECKSTYLE:ON
         this.sw = sw;
         this.match = new Match(sw, srcPort, srcMac, dstMac, srcIpAddress, dstIpAddress);
         this.actions = new HashSet<Action>();
@@ -133,33 +143,91 @@
     }
 
     /**
-     * Converts the FlowEntry in to a legacy FlowEntry object.
+     * Builds and returns an OFFlowMod given an OFFactory.
      *
-     * @return an equivalent legacy FlowEntry object
+     * @param factory the OFFactory to use for building
+     * @return the OFFlowMod
      */
-    public net.onrc.onos.core.util.FlowEntry getFlowEntry() {
-        net.onrc.onos.core.util.FlowEntry entry = new net.onrc.onos.core.util.FlowEntry();
-        entry.setDpid(new Dpid(sw));
-        entry.setFlowEntryId(new FlowEntryId(flowEntryId));
-        entry.setFlowEntryMatch(match.getFlowEntryMatch());
-        FlowEntryActions flowEntryActions = new FlowEntryActions();
-        for (Action action : actions) {
-            flowEntryActions.addAction(action.getFlowEntryAction());
-        }
-        entry.setFlowEntryActions(flowEntryActions);
+    public OFFlowMod buildFlowMod(OFFactory factory) {
+        OFFlowMod.Builder builder = null;
+
         switch (operator) {
-            case ADD:
-                entry.setFlowEntryUserState(FlowEntryUserState.FE_USER_MODIFY);
-                break;
-            case REMOVE:
-                entry.setFlowEntryUserState(FlowEntryUserState.FE_USER_DELETE);
-                break;
-            default:
-                break;
+        case ADD:
+            builder = factory.buildFlowModifyStrict();
+            break;
+        case REMOVE:
+            builder = factory.buildFlowDeleteStrict();
+            break;
+        default:
+            // TODO throw error?
+            return null;
         }
-        entry.setIdleTimeout(idleTimeout);
-        entry.setHardTimeout(hardTimeout);
-        return entry;
+
+        // Build OFMatch
+        Builder matchBuilder = match.getOFMatchBuilder(factory);
+
+        // Build OFAction Set
+        List<OFAction> actionList = new ArrayList<>(actions.size());
+        for (Action action : actions) {
+            actionList.add(action.getOFAction(factory));
+        }
+
+        OFPort outp = OFPort.of((short) 0xffff); // OF1.0 OFPP.NONE
+        if (operator == Operator.REMOVE) {
+            if (actionList.size() == 1) {
+                if (actionList.get(0).getType() == OFActionType.OUTPUT) {
+                    OFActionOutput oa = (OFActionOutput) actionList.get(0);
+                    outp = oa.getPort();
+                }
+            }
+        }
+
+        // Build OFFlowMod
+        builder.setMatch(matchBuilder.build())
+                .setActions(actionList)
+                .setIdleTimeout(idleTimeout)
+                .setHardTimeout(hardTimeout)
+                .setCookie(U64.of(flowEntryId))
+                .setBufferId(OFBufferId.NO_BUFFER)
+                .setPriority(PRIORITY_DEFAULT)
+                .setOutPort(outp);
+
+        /* Note: The following are NOT USED.
+         * builder.setFlags()
+         * builder.setInstructions()
+         * builder.setOutGroup()
+         * builder.setTableId()
+         * builder.setXid()
+         */
+
+        // TODO from Flow Pusher
+        // Set the OFPFF_SEND_FLOW_REM flag if the Flow Entry is not
+        // permanent.
+        //
+        // if ((flowEntry.idleTimeout() != 0) ||
+        // (flowEntry.hardTimeout() != 0)) {
+        // fm.setFlags(OFFlowMod.OFPFF_SEND_FLOW_REM);
+        // }
+
+        // TODO do we care?
+        // fm.setOutPort(OFPort.OFPP_NONE.getValue());
+        // if ((flowModCommand == OFFlowMod.OFPFC_DELETE)
+        // || (flowModCommand == OFFlowMod.OFPFC_DELETE_STRICT)) {
+        // if (actionOutputPort.portNumber != null) {
+        // fm.setOutPort(actionOutputPort.portNumber);
+        // }
+        // }
+
+        // TODO
+        // Set the OFPFF_SEND_FLOW_REM flag if the Flow Entry is not
+        // permanent.
+        //
+        // if ((flowEntry.idleTimeout() != 0) ||
+        // (flowEntry.hardTimeout() != 0)) {
+        // fm.setFlags(OFFlowMod.OFPFF_SEND_FLOW_REM);
+        // }
+
+        return builder.build();
     }
 
     /**
diff --git a/src/main/java/net/onrc/onos/core/intent/ForwardAction.java b/src/main/java/net/onrc/onos/core/intent/ForwardAction.java
index ef6dd00..a3792d1 100644
--- a/src/main/java/net/onrc/onos/core/intent/ForwardAction.java
+++ b/src/main/java/net/onrc/onos/core/intent/ForwardAction.java
@@ -3,6 +3,10 @@
 import net.onrc.onos.core.util.FlowEntryAction;
 import net.onrc.onos.core.util.PortNumber;
 
+import org.projectfloodlight.openflow.protocol.OFFactory;
+import org.projectfloodlight.openflow.protocol.action.OFAction;
+import org.projectfloodlight.openflow.types.OFPort;
+
 /**
  * A class to represent the OpenFlow forwarding action.
  */
@@ -41,6 +45,11 @@
         return action;
     }
 
+    @Override
+    public OFAction getOFAction(OFFactory factory) {
+        return factory.actions().output(OFPort.of((int) dstPort), Short.MAX_VALUE);
+    }
+
     /**
      * A simple hash function that just used the destination port.
      *
diff --git a/src/main/java/net/onrc/onos/core/intent/Match.java b/src/main/java/net/onrc/onos/core/intent/Match.java
index cddd6de..a3c397b 100644
--- a/src/main/java/net/onrc/onos/core/intent/Match.java
+++ b/src/main/java/net/onrc/onos/core/intent/Match.java
@@ -1,6 +1,5 @@
 package net.onrc.onos.core.intent;
 
-
 import java.util.Objects;
 
 import net.floodlightcontroller.util.MACAddress;
@@ -10,6 +9,14 @@
 import net.onrc.onos.core.util.IPv4Net;
 import net.onrc.onos.core.util.PortNumber;
 
+import org.projectfloodlight.openflow.protocol.OFFactory;
+import org.projectfloodlight.openflow.protocol.match.Match.Builder;
+import org.projectfloodlight.openflow.protocol.match.MatchField;
+import org.projectfloodlight.openflow.types.EthType;
+import org.projectfloodlight.openflow.types.IPv4AddressWithMask;
+import org.projectfloodlight.openflow.types.MacAddress;
+import org.projectfloodlight.openflow.types.OFPort;
+
 /**
  * A class to represent the OpenFlow match.
  * <p>
@@ -41,8 +48,10 @@
      * @param dstMac destination Ethernet MAC address
      */
     public Match(long sw, long srcPort,
-                 MACAddress srcMac, MACAddress dstMac) {
-        this(sw, srcPort, srcMac, dstMac, ShortestPathIntent.EMPTYIPADDRESS, ShortestPathIntent.EMPTYIPADDRESS);
+            MACAddress srcMac, MACAddress dstMac) {
+        this(sw, srcPort, srcMac, dstMac,
+                ShortestPathIntent.EMPTYIPADDRESS,
+                ShortestPathIntent.EMPTYIPADDRESS);
     }
 
     /**
@@ -56,7 +65,7 @@
      * @param dstIp destination IP address
      */
     public Match(long sw, long srcPort, MACAddress srcMac, MACAddress dstMac,
-                 int srcIp, int dstIp) {
+            int srcIp, int dstIp) {
 
         this.sw = sw;
         this.srcPort = srcPort;
@@ -75,7 +84,7 @@
     public boolean equals(Object obj) {
         if (obj instanceof Match) {
             Match other = (Match) obj;
-            //TODO: we might consider excluding sw from this comparison
+            // TODO: we might consider excluding sw from this comparison
             if (this.sw != other.sw) {
                 return false;
             }
@@ -130,6 +139,30 @@
         return match;
     }
 
+    public Builder getOFMatchBuilder(OFFactory factory) {
+        Builder matchBuilder = factory.buildMatch();
+
+        if (srcMac != null) {
+            matchBuilder.setExact(MatchField.ETH_SRC, MacAddress.of(srcMac.toLong()));
+        }
+        if (dstMac != null) {
+            matchBuilder.setExact(MatchField.ETH_DST, MacAddress.of(dstMac.toLong()));
+        }
+        if (srcIp != ShortestPathIntent.EMPTYIPADDRESS) {
+            matchBuilder.setExact(MatchField.ETH_TYPE, EthType.IPv4)
+                    .setMasked(MatchField.IPV4_SRC,
+                            IPv4AddressWithMask.of(srcIp, IPV4_PREFIX_LEN));
+        }
+        if (dstIp != ShortestPathIntent.EMPTYIPADDRESS) {
+            matchBuilder.setExact(MatchField.ETH_TYPE, EthType.IPv4)
+                    .setMasked(MatchField.IPV4_DST,
+                            IPv4AddressWithMask.of(dstIp, IPV4_PREFIX_LEN));
+        }
+        matchBuilder.setExact(MatchField.IN_PORT, OFPort.of((int) srcPort));
+
+        return matchBuilder;
+    }
+
     /**
      * Returns a String representation of this Match.
      *
@@ -137,7 +170,9 @@
      */
     @Override
     public String toString() {
-        return "Sw:" + sw + " (" + srcPort + "," + srcMac + "," + dstMac + "," + srcIp + "," + dstIp + ")";
+        return "Sw:" + sw + " (" + srcPort + ","
+                + srcMac + "," + dstMac + ","
+                + srcIp + "," + dstIp + ")";
     }
 
     /**
@@ -147,8 +182,8 @@
      */
     @Override
     public int hashCode() {
-        //TODO: we might consider excluding sw from the hash function
-        //      to make it easier to compare matches between switches
-        return  Objects.hash(sw, srcPort, srcMac, dstMac, srcIp, dstIp);
+        // TODO: we might consider excluding sw from the hash function
+        // to make it easier to compare matches between switches
+        return Objects.hash(sw, srcPort, srcMac, dstMac, srcIp, dstIp);
     }
 }
diff --git a/src/main/java/net/onrc/onos/core/intent/runtime/PlanInstallModule.java b/src/main/java/net/onrc/onos/core/intent/runtime/PlanInstallModule.java
index 025b6d7..058b2d0 100644
--- a/src/main/java/net/onrc/onos/core/intent/runtime/PlanInstallModule.java
+++ b/src/main/java/net/onrc/onos/core/intent/runtime/PlanInstallModule.java
@@ -31,17 +31,17 @@
 import net.onrc.onos.core.intent.ShortestPathIntent;
 import net.onrc.onos.core.topology.ITopologyService;
 
-import org.openflow.protocol.OFFlowRemoved;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFType;
+import org.projectfloodlight.openflow.protocol.OFFlowRemoved;
+import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
  * The PlanInstallModule contains the PlanCalcRuntime and PlanInstallRuntime.
  * <p>
- * It is responsible for converting Intents into FlowMods and seeing that
- * they are properly installed.
+ * It is responsible for converting Intents into FlowMods and seeing that they
+ * are properly installed.
  */
 public class PlanInstallModule implements IFloodlightModule, IOFMessageListener {
 
@@ -76,8 +76,8 @@
             while (true) {
                 try {
                     IntentOperationList intents = intentQueue.take();
-                    //TODO: consider draining the remaining intent lists
-                    //      and processing in one big batch
+                    // TODO: consider draining the remaining intent lists
+                    // and processing in one big batch
 
                     processIntents(intents);
                 } catch (InterruptedException e) {
@@ -111,8 +111,9 @@
         }
 
         /***
-         * This function is for sending intent state notification to other ONOS instances.
-         * The argument of "domainSwitchDpids" is required for dispatching this ONOS's managed switches.
+         * This function is for sending intent state notification to other ONOS
+         * instances. The argument of "domainSwitchDpids" is required for
+         * dispatching this ONOS's managed switches.
          *
          * @param intents list of intents
          * @param installed true if Intents were installed
@@ -125,31 +126,32 @@
             for (IntentOperation i : intents) {
                 IntentState newState;
                 switch (i.operator) {
-                    case REMOVE:
-                        if (installed) {
-                            newState = success ? IntentState.DEL_ACK : IntentState.DEL_PENDING;
-                        } else {
-                            newState = IntentState.DEL_REQ;
+                case REMOVE:
+                    if (installed) {
+                        newState = success ? IntentState.DEL_ACK
+                                : IntentState.DEL_PENDING;
+                    } else {
+                        newState = IntentState.DEL_REQ;
+                    }
+                    break;
+                case ADD:
+                default:
+                    if (installed) {
+                        if (domainSwitchDpids != null) {
+                            states.domainSwitchDpids.addAll(domainSwitchDpids);
                         }
-                        break;
-                    case ADD:
-                    default:
-                        if (installed) {
-                            if (domainSwitchDpids != null) {
-                                states.domainSwitchDpids.addAll(domainSwitchDpids);
-                            }
-                            newState = success ? IntentState.INST_ACK : IntentState.INST_NACK;
-                        } else {
-                            newState = IntentState.INST_REQ;
-                        }
-                        break;
+                        newState = success ? IntentState.INST_ACK : IntentState.INST_NACK;
+                    } else {
+                        newState = IntentState.INST_REQ;
+                    }
+                    break;
                 }
                 states.put(i.intent.getId(), newState);
             }
 
             if (log.isTraceEnabled()) {
                 log.trace("sendNotifications, states {}, domainSwitchDpids {}",
-                       states, states.domainSwitchDpids);
+                        states, states.domainSwitchDpids);
             }
 
             // Send notifications using the same key every time
@@ -222,6 +224,7 @@
 
     /**
      * Formatted log for debugging.
+     * <p>
      * TODO: merge this into debugging framework
      *
      * @param step the step of computation
@@ -261,7 +264,8 @@
                 IntentOperationList.class);
         eventListener.start();
         // start publisher
-        intentStateChannel = datagridService.createChannel(INTENT_STATE_EVENT_CHANNEL_NAME,
+        intentStateChannel = datagridService.createChannel(
+                INTENT_STATE_EVENT_CHANNEL_NAME,
                 Long.class,
                 IntentStateList.class);
         floodlightProvider.addOFMessageListener(OFType.FLOW_REMOVED, this);
@@ -308,19 +312,19 @@
     @Override
     public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
         if (msg.getType().equals(OFType.FLOW_REMOVED) &&
-            (msg instanceof OFFlowRemoved)) {
+                (msg instanceof OFFlowRemoved)) {
             OFFlowRemoved flowRemovedMsg = (OFFlowRemoved) msg;
 
             if (log.isTraceEnabled()) {
-               log.trace("Receive flowRemoved from sw {} : Cookie {}",
-                       sw.getId(), flowRemovedMsg.getCookie());
+                log.trace("Receive flowRemoved from sw {} : Cookie {}",
+                        sw.getId(), flowRemovedMsg.getCookie());
             }
 
-            String intentParentId = Long.toString(flowRemovedMsg.getCookie());
+            String intentParentId = Long.toString(flowRemovedMsg.getCookie().getValue());
             Intent intent = parentIntentMap.get(intentParentId);
 
-            //We assume if the path src sw flow entry is expired,
-            //the path is expired.
+            // We assume if the path src sw flow entry is expired,
+            // the path is expired.
             if (!isFlowSrcRemoved(sw.getId(), intentParentId)) {
                 return Command.CONTINUE;
             }
@@ -343,7 +347,8 @@
             log.debug("addEntry to intentStateChannel intentId {}, states {}",
                     pathIntentId, newState);
 
-            intentStateChannel.addTransientEntry(flowRemovedMsg.getCookie(), states);
+            intentStateChannel.addTransientEntry(flowRemovedMsg.getCookie().getValue(),
+                    states);
         }
 
         return Command.CONTINUE;
@@ -355,10 +360,10 @@
      * @param dpid DPID of affected switch
      * @param shortestPathIntentId Intent to check
      * @return true if the flow's source switch entry is removed or expired,
-     * otherwise false.
+     *         otherwise false.
      */
     private boolean isFlowSrcRemoved(long dpid, String shortestPathIntentId) {
-        Intent intent =  parentIntentMap.get(shortestPathIntentId);
+        Intent intent = parentIntentMap.get(shortestPathIntentId);
         ShortestPathIntent spfIntent = null;
         if (intent instanceof ShortestPathIntent) {
             spfIntent = (ShortestPathIntent) intent;
@@ -376,33 +381,19 @@
         return false;
     }
 
-    /*
-     * (non-Javadoc)
-     * @see net.floodlightcontroller.core.IListener#getName()
-     */
     @Override
     public String getName() {
-        // TODO Auto-generated method stub
-        return null;
+        return "planInstall";
     }
 
-    /*
-     * (non-Javadoc)
-     * @see net.floodlightcontroller.core.IListener#isCallbackOrderingPrereq(java.lang.Object, java.lang.String)
-     */
     @Override
     public boolean isCallbackOrderingPrereq(OFType type, String name) {
-        // TODO Auto-generated method stub
         return false;
     }
 
-    /*
-     * (non-Javadoc)
-     * @see net.floodlightcontroller.core.IListener#isCallbackOrderingPostreq(java.lang.Object, java.lang.String)
-     */
     @Override
     public boolean isCallbackOrderingPostreq(OFType type, String name) {
-        // TODO Auto-generated method stub
         return false;
     }
+
 }
diff --git a/src/main/java/net/onrc/onos/core/intent/runtime/PlanInstallRuntime.java b/src/main/java/net/onrc/onos/core/intent/runtime/PlanInstallRuntime.java
index f942fa8..8a444d7 100644
--- a/src/main/java/net/onrc/onos/core/intent/runtime/PlanInstallRuntime.java
+++ b/src/main/java/net/onrc/onos/core/intent/runtime/PlanInstallRuntime.java
@@ -16,14 +16,15 @@
 import net.onrc.onos.core.intent.FlowEntry;
 import net.onrc.onos.core.util.Pair;
 
-import org.openflow.protocol.OFBarrierReply;
+import org.projectfloodlight.openflow.protocol.OFBarrierReply;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * This class is responsible for installing plans (lists of sets of FlowEntries) into local switches.
- * In this context, a local switch is a switch for which this ONOS instance is the master.
- * It also is responsible for sending barrier messages between sets.
+ * This class is responsible for installing plans (lists of sets of FlowEntries)
+ * into local switches. In this context, a local switch is a switch for which
+ * this ONOS instance is the master. It also is responsible for sending barrier
+ * messages between sets.
  */
 
 public class PlanInstallRuntime {
@@ -39,16 +40,18 @@
      * @param pusher the FlowPusherService to use for FlowEntry installation
      */
     public PlanInstallRuntime(IFloodlightProviderService provider,
-                              IFlowPusherService pusher) {
+            IFlowPusherService pusher) {
         this.provider = provider;
         this.pusher = pusher;
     }
 
     /**
-     * This class is a temporary class for collecting FlowMod installation information. It is
-     * largely used for debugging purposes, and it should not be depended on for other purposes.
+     * This class is a temporary class for collecting FlowMod installation
+     * information. It is largely used for debugging purposes, and it should not
+     * be depended on for other purposes.
      * <p>
-     * TODO: This class should be wrapped into a more generic debugging framework when available.
+     * TODO: This class should be wrapped into a more generic debugging
+     * framework when available.
      */
     private static class FlowModCount {
         WeakReference<IOFSwitch> sw;
@@ -72,17 +75,17 @@
          */
         void addFlowEntry(FlowEntry entry) {
             switch (entry.getOperator()) {
-                case ADD:
-                    modFlows++;
-                    break;
-                case ERROR:
-                    errors++;
-                    break;
-                case REMOVE:
-                    delFlows++;
-                    break;
-                default:
-                    break;
+            case ADD:
+                modFlows++;
+                break;
+            case ERROR:
+                errors++;
+                break;
+            case REMOVE:
+                delFlows++;
+                break;
+            default:
+                break;
             }
         }
 
@@ -101,13 +104,15 @@
         static Map<IOFSwitch, FlowModCount> map = new WeakHashMap<>();
 
         /**
-         * This function is used for collecting statistics information. It should be called for
-         * every FlowEntry that is pushed to the switch for accurate statistics.
+         * This function is used for collecting statistics information. It
+         * should be called for every FlowEntry that is pushed to the switch for
+         * accurate statistics.
          * <p>
-         * This class maintains a map of Switches and FlowModCount collection objects, which
-         * are used for collection.
+         * This class maintains a map of Switches and FlowModCount collection
+         * objects, which are used for collection.
          * <p>
-         * TODO: This should be refactored to use a more generic mechanism when available.
+         * TODO: This should be refactored to use a more generic mechanism when
+         * available.
          *
          * @param sw the switch that entry is being pushed to
          * @param entry the FlowEntry being pushed
@@ -122,7 +127,8 @@
         }
 
         /**
-         * Reset the statistics collection. It should be called when required for debugging.
+         * Reset the statistics collection. It should be called when required
+         * for debugging.
          */
         static void startCount() {
             map.clear();
@@ -148,11 +154,11 @@
     /**
      * This function should be called to install the FlowEntries in the plan.
      * <p>
-     * Each set of FlowEntries can be installed together, but all entries should be installed
-     * proceeded to the next set.
+     * Each set of FlowEntries can be installed together, but all entries should
+     * be installed proceeded to the next set.
      * <p>
-     * TODO: This method lack coordination between the other ONOS instances before proceeded
-     * with the next set of entries
+     * TODO: This method lack coordination between the other ONOS instances
+     * before proceeded with the next set of entries
      *
      * @param plan list of set of FlowEntries for installation on local switches
      * @return true (we assume installation is successful)
@@ -164,7 +170,7 @@
         log.debug("IOFSwitches: {}", switches);
         FlowModCount.startCount();
         for (Set<FlowEntry> phase : plan) {
-            Set<Pair<IOFSwitch, net.onrc.onos.core.util.FlowEntry>> entries = new HashSet<>();
+            Set<Pair<IOFSwitch, FlowEntry>> entries = new HashSet<>();
             Set<IOFSwitch> modifiedSwitches = new HashSet<>();
 
             long step1 = System.nanoTime();
@@ -176,7 +182,7 @@
                     log.debug("Skipping flow entry: {}", entry);
                     continue;
                 }
-                entries.add(new Pair<>(sw, entry.getFlowEntry()));
+                entries.add(new Pair<>(sw, entry));
                 modifiedSwitches.add(sw);
                 FlowModCount.countFlowEntry(sw, entry);
             }
diff --git a/src/main/java/net/onrc/onos/core/linkdiscovery/LinkDiscoveryManager.java b/src/main/java/net/onrc/onos/core/linkdiscovery/LinkDiscoveryManager.java
index a924f00..4c87501 100644
--- a/src/main/java/net/onrc/onos/core/linkdiscovery/LinkDiscoveryManager.java
+++ b/src/main/java/net/onrc/onos/core/linkdiscovery/LinkDiscoveryManager.java
@@ -24,7 +24,6 @@
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -38,6 +37,7 @@
 import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IOFMessageListener;
 import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.core.IOFSwitch.PortChangeType;
 import net.floodlightcontroller.core.IOFSwitchListener;
 import net.floodlightcontroller.core.IUpdate;
 import net.floodlightcontroller.core.annotations.LogMessageCategory;
@@ -57,35 +57,37 @@
 import net.onrc.onos.core.registry.IControllerRegistryService;
 import net.onrc.onos.core.util.SwitchPort;
 
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFPacketOut;
-import org.openflow.protocol.OFPhysicalPort;
-import org.openflow.protocol.OFPhysicalPort.OFPortConfig;
-import org.openflow.protocol.OFPhysicalPort.OFPortState;
-import org.openflow.protocol.OFPort;
-import org.openflow.protocol.OFPortStatus;
-import org.openflow.protocol.OFPortStatus.OFPortReason;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.action.OFAction;
-import org.openflow.protocol.action.OFActionOutput;
-import org.openflow.protocol.action.OFActionType;
-import org.openflow.util.HexString;
+import org.projectfloodlight.openflow.protocol.OFFactories;
+import org.projectfloodlight.openflow.protocol.OFFactory;
+import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFPacketIn;
+import org.projectfloodlight.openflow.protocol.OFPacketOut;
+import org.projectfloodlight.openflow.protocol.OFPortConfig;
+import org.projectfloodlight.openflow.protocol.OFPortDesc;
+import org.projectfloodlight.openflow.protocol.OFPortReason;
+import org.projectfloodlight.openflow.protocol.OFPortState;
+import org.projectfloodlight.openflow.protocol.OFPortStatus;
+import org.projectfloodlight.openflow.protocol.OFType;
+import org.projectfloodlight.openflow.protocol.OFVersion;
+import org.projectfloodlight.openflow.protocol.action.OFAction;
+import org.projectfloodlight.openflow.types.OFBufferId;
+import org.projectfloodlight.openflow.types.OFPort;
+import org.projectfloodlight.openflow.util.HexString;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
  * Discovers links between OpenFlow switches.
- * <p/>
- * Discovery is performed by sending probes (LLDP packets) over the links in
- * the data plane. The LinkDiscoveryManager sends probes periodically on all
- * ports on all connected switches. The probes contain the sending switch's
- * DPID and outgoing port number. LLDP packets that are received (via an
- * OpenFlow packet-in) indicate there is a link between the receiving port and
- * the sending port, which was encoded in the LLDP. When the
- * LinkDiscoveryManager observes a new link, a Link object is created and an
- * event is fired for any event listeners.
- * <p/>
+ * <p>
+ * Discovery is performed by sending probes (LLDP packets) over the links in the
+ * data plane. The LinkDiscoveryManager sends probes periodically on all ports
+ * on all connected switches. The probes contain the sending switch's DPID and
+ * outgoing port number. LLDP packets that are received (via an OpenFlow
+ * packet-in) indicate there is a link between the receiving port and the
+ * sending port, which was encoded in the LLDP. When the LinkDiscoveryManager
+ * observes a new link, a Link object is created and an event is fired for any
+ * event listeners.
+ * </p>
  * Links are removed for one of three reasons:
  * <ul>
  * <li>A probe has not been received on the link for an interval (the timeout
@@ -104,6 +106,9 @@
 
     private static final Logger log =
             LoggerFactory.getLogger(LinkDiscoveryManager.class);
+    // TODO Remove these factories.
+    protected OFFactory factory13 = OFFactories.getFactory(OFVersion.OF_13);
+    protected OFFactory factory10 = OFFactories.getFactory(OFVersion.OF_10);
 
     private IFloodlightProviderService controller;
 
@@ -121,13 +126,16 @@
     // Link discovery task details.
     private SingletonTask discoveryTask;
     private static final int DISCOVERY_TASK_INTERVAL = 1;
-    private static final int LINK_TIMEOUT = 35; // original 35 secs, aggressive 5 secs
-    private static final int LLDP_TO_ALL_INTERVAL = 15; //original 15 seconds, aggressive 2 secs.
+    private static final int LINK_TIMEOUT = 35; // original 35 secs, aggressive
+                                                // 5 secs
+    private static final int LLDP_TO_ALL_INTERVAL = 15; // original 15 seconds,
+                                                        // aggressive 2 secs.
     private long lldpClock = 0;
     // This value is intentionally kept higher than LLDP_TO_ALL_INTERVAL.
     // If we want to identify link failures faster, we could decrease this
     // value to a small number, say 1 or 2 sec.
-    private static final int LLDP_TO_KNOWN_INTERVAL = 20; // LLDP frequency for known links
+    private static final int LLDP_TO_KNOWN_INTERVAL = 20; // LLDP frequency for
+                                                          // known links
 
     private ReentrantReadWriteLock lock;
 
@@ -149,8 +157,8 @@
     /**
      * Listeners are called in the order they were added to the the list.
      */
-    private final List<ILinkDiscoveryListener> linkDiscoveryListeners
-            = new CopyOnWriteArrayList<>();
+    private final List<ILinkDiscoveryListener> linkDiscoveryListeners =
+            new CopyOnWriteArrayList<>();
 
     /**
      * List of ports through which LLDPs are not sent.
@@ -230,8 +238,8 @@
         discover(npt);
     }
 
-    private boolean isLinkDiscoverySuppressed(long sw, short portNumber) {
-        return this.suppressLinkDiscovery.contains(new NodePortTuple(sw, portNumber));
+    private boolean isLinkDiscoverySuppressed(long sw, short p) {
+        return this.suppressLinkDiscovery.contains(new NodePortTuple(sw, p));
     }
 
     private void discoverLinks() {
@@ -239,7 +247,7 @@
         // time out known links.
         timeOutLinks();
 
-        //increment LLDP clock
+        // increment LLDP clock
         lldpClock = (lldpClock + 1) % LLDP_TO_ALL_INTERVAL;
 
         if (lldpClock == 0) {
@@ -271,8 +279,8 @@
     }
 
     /**
-     * Send link discovery message out of a given switch port.
-     * The discovery message is a standard LLDP containing ONOS-specific TLVs.
+     * Send link discovery message out of a given switch port. The discovery
+     * message is a standard LLDP containing ONOS-specific TLVs.
      *
      * @param sw the switch to send on
      * @param port the port to send out
@@ -284,18 +292,18 @@
                     "to the switch.",
             recommendation = LogMessageDoc.CHECK_SWITCH)
     protected void sendDiscoveryMessage(long sw, short port,
-                                        boolean isReverse) {
+            boolean isReverse) {
 
         IOFSwitch iofSwitch = floodlightProvider.getSwitches().get(sw);
         if (iofSwitch == null) {
             return;
         }
 
-        if (port == OFPort.OFPP_LOCAL.getValue()) {
+        if (port == OFPort.LOCAL.getShortPortNumber()) {
             return;
         }
 
-        OFPhysicalPort ofpPort = iofSwitch.getPort(port);
+        OFPortDesc ofpPort = iofSwitch.getPort(port);
 
         if (ofpPort == null) {
             if (log.isTraceEnabled()) {
@@ -314,7 +322,9 @@
                     sw, port);
         }
 
-        OFPacketOut po = createLLDPPacketOut(sw, ofpPort, isReverse);
+        OFFactory factory = (iofSwitch.getOFVersion() == OFVersion.OF_10)
+                ? factory10 : factory13;
+        OFPacketOut po = createLLDPPacketOut(sw, ofpPort, isReverse, factory);
 
         try {
             iofSwitch.write(po, null);
@@ -332,10 +342,11 @@
      * @param dpid the dpid of the outgoing switch
      * @param port the outgoing port
      * @param isReverse whether this is a reverse LLDP or not
+     * @param factory the factory to use to create the message
      * @return Packet_out message with LLDP data
      */
     private OFPacketOut createLLDPPacketOut(long dpid,
-            final OFPhysicalPort port, boolean isReverse) {
+            final OFPortDesc port, boolean isReverse, OFFactory factory) {
         // Set up packets
         // TODO optimize by not creating new packets each time
         OnosLldp lldpPacket = new OnosLldp();
@@ -346,29 +357,25 @@
         ethPacket.setPayload(lldpPacket);
         ethPacket.setPad(true);
 
-        final OFPacketOut packetOut = (OFPacketOut) floodlightProvider.getOFMessageFactory()
-                .getMessage(OFType.PACKET_OUT);
-        packetOut.setBufferId(OFPacketOut.BUFFER_ID_NONE);
-
-        final List<OFAction> actionsList = new LinkedList<OFAction>();
-        final OFActionOutput out = (OFActionOutput) floodlightProvider.getOFMessageFactory()
-                .getAction(OFActionType.OUTPUT);
-        out.setPort(port.getPortNumber());
-        actionsList.add(out);
-        packetOut.setActions(actionsList);
-        final short alen = (short) OFActionOutput.MINIMUM_LENGTH;
-
         lldpPacket.setSwitch(dpid);
-        lldpPacket.setPort(port.getPortNumber());
+        lldpPacket.setPort(port.getPortNo().getShortPortNumber());
         lldpPacket.setReverse(isReverse);
-        ethPacket.setSourceMACAddress(port.getHardwareAddress());
-
+        ethPacket.setSourceMACAddress(port.getHwAddr().getBytes());
         final byte[] lldp = ethPacket.serialize();
-        packetOut.setActionsLength(alen);
-        packetOut.setPacketData(lldp);
-        packetOut
-                .setLength((short) (OFPacketOut.MINIMUM_LENGTH + alen + lldp.length));
-        return packetOut;
+
+        List<OFAction> actions = new ArrayList<OFAction>();
+        actions.add(factory.actions()
+                .buildOutput()
+                .setPort(OFPort.ofShort(port.getPortNo().getShortPortNumber()))
+                .build());
+        OFPacketOut po = factory.buildPacketOut()
+                .setData(lldp)
+                .setBufferId(OFBufferId.NO_BUFFER)
+                .setInPort(OFPort.CONTROLLER)
+                .setActions(actions)
+                .build();
+
+        return po;
     }
 
     /**
@@ -383,12 +390,14 @@
             if (sw.getEnabledPorts() == null) {
                 continue;
             }
-            for (OFPhysicalPort ofp : sw.getEnabledPorts()) {
-                if (isLinkDiscoverySuppressed(sw.getId(), ofp.getPortNumber())) {
+            for (OFPortDesc ofp : sw.getEnabledPorts()) {
+                if (isLinkDiscoverySuppressed(sw.getId(),
+                        ofp.getPortNo().getShortPortNumber())) {
                     continue;
                 }
 
-                sendDiscoveryMessage(sw.getId(), ofp.getPortNumber(), false);
+                sendDiscoveryMessage(sw.getId(),
+                        ofp.getPortNo().getShortPortNumber(), false);
             }
         }
     }
@@ -401,31 +410,31 @@
     @Override
     public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
         switch (msg.getType()) {
-            case PACKET_IN:
-                if (msg instanceof OFPacketIn) {
-                    return this.handlePacketIn(sw.getId(), (OFPacketIn) msg,
-                                               cntx);
-                }
-                break;
-            case PORT_STATUS:
-                if (msg instanceof OFPortStatus) {
-                    return this.handlePortStatus(sw, (OFPortStatus) msg);
-                }
-                break;
-            default:
-                break;
+        case PACKET_IN:
+            if (msg instanceof OFPacketIn) {
+                return this.handlePacketIn(sw.getId(), (OFPacketIn) msg,
+                        cntx);
+            }
+            break;
+        case PORT_STATUS:
+            if (msg instanceof OFPortStatus) {
+                return this.handlePortStatus(sw, (OFPortStatus) msg);
+            }
+            break;
+        default:
+            break;
         }
         return Command.CONTINUE;
     }
 
-    protected Command handleLldp(LLDP lldp, long sw, OFPacketIn pi) {
+    protected Command handleLldp(LLDP lldp, long sw, OFPacketIn pi, short inport) {
         // If LLDP is suppressed on this port, ignore received packet as well
-        IOFSwitch iofSwitch = floodlightProvider.getSwitches().get(sw);
+        IOFSwitch iofSwitch = floodlightProvider.getSwitch(sw);
         if (iofSwitch == null) {
             return Command.STOP;
         }
 
-        if (isLinkDiscoverySuppressed(sw, pi.getInPort())) {
+        if (isLinkDiscoverySuppressed(sw, inport)) {
             return Command.STOP;
         }
 
@@ -435,7 +444,7 @@
         }
 
         // Verify this LLDP packet matches what we're looking for
-        byte[] packetData = pi.getPacketData();
+        byte[] packetData = pi.getData();
         if (!OnosLldp.isOnosLldp(packetData)) {
             log.trace("Dropping LLDP that wasn't sent by ONOS");
             return Command.STOP;
@@ -444,10 +453,10 @@
         SwitchPort switchPort = OnosLldp.extractSwitchPort(packetData);
         long remoteDpid = switchPort.dpid().value();
         short remotePort = switchPort.port().shortValue();
-        IOFSwitch remoteSwitch = floodlightProvider.getSwitches().get(switchPort.dpid().value());
+        IOFSwitch remoteSwitch = floodlightProvider.getSwitches().get(
+                switchPort.dpid().value());
 
-
-        OFPhysicalPort physicalPort = null;
+        OFPortDesc physicalPort = null;
         if (remoteSwitch != null) {
             physicalPort = remoteSwitch.getPort(remotePort);
             if (!remoteSwitch.portEnabled(remotePort)) {
@@ -466,20 +475,24 @@
                 return Command.STOP;
             }
         }
-        if (!iofSwitch.portEnabled(pi.getInPort())) {
+        if (!iofSwitch.portEnabled(inport)) {
             if (log.isTraceEnabled()) {
                 log.trace("Ignoring link with disabled dest port: " +
-                        "switch {} port {}", sw, pi.getInPort());
+                        "switch {} port {}", sw, inport);
             }
             return Command.STOP;
         }
 
-        int srcPortState = (physicalPort != null) ? physicalPort.getState() : 0;
-        physicalPort = iofSwitch.getPort(pi.getInPort());
-        int dstPortState = (physicalPort != null) ? physicalPort.getState() : 0;
+        // TODO It probably should be empty Set instead of null. Confirm and fix.
+        Set<OFPortState> srcPortState = (physicalPort != null)
+                ? physicalPort.getState() : null;
+        physicalPort = iofSwitch.getPort(inport);
+        Set<OFPortState> dstPortState = (physicalPort != null)
+                ? physicalPort.getState() : null;
 
-        // Store the time of update to this link, and push it out to routingEngine
-        Link lt = new Link(remoteDpid, remotePort, iofSwitch.getId(), pi.getInPort());
+        // Store the time of update to this link, and push it out to
+        // routingEngine
+        Link lt = new Link(remoteDpid, remotePort, iofSwitch.getId(), inport);
 
         LinkInfo linkInfo = new LinkInfo(System.currentTimeMillis(),
                 System.currentTimeMillis(), srcPortState, dstPortState);
@@ -499,8 +512,8 @@
             LinkInfo reverseInfo = links.get(reverseLink);
             if (reverseInfo == null) {
                 // the reverse link does not exist.
-                if (newLinkInfo.getFirstSeenTime() >
-                        System.currentTimeMillis() - LINK_TIMEOUT) {
+                if (newLinkInfo.getFirstSeenTime() > System.currentTimeMillis()
+                        - LINK_TIMEOUT) {
                     this.sendDiscoveryMessage(lt.getDst(), lt.getDstPort(), true);
                 }
             }
@@ -511,13 +524,15 @@
     }
 
     protected Command handlePacketIn(long sw, OFPacketIn pi,
-                                     FloodlightContext cntx) {
+            FloodlightContext cntx) {
         Ethernet eth =
                 IFloodlightProviderService.bcStore.get(cntx,
                         IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
+        short inport = (short) cntx.getStorage()
+                .get(IFloodlightProviderService.CONTEXT_PI_INPORT);
 
         if (eth.getEtherType() == Ethernet.TYPE_LLDP) {
-            return handleLldp((LLDP) eth.getPayload(), sw, pi);
+            return handleLldp((LLDP) eth.getPayload(), sw, pi, inport);
         } else if (eth.getEtherType() < 1500) {
             long destMac = eth.getDestinationMAC().toLong();
             if ((destMac & LINK_LOCAL_MASK) == LINK_LOCAL_VALUE) {
@@ -557,6 +572,7 @@
             // If this is the first time we've seen the link, add the Link
             // object to the data structures/indexes as well
             if (existingInfo == null) {
+                log.trace("Creating new Link: {}", lt);
                 // index it by switch source
                 if (!switchLinks.containsKey(lt.getSrc())) {
                     switchLinks.put(lt.getSrc(), new HashSet<Link>());
@@ -639,8 +655,8 @@
     }
 
     /**
-     * Handles an OFPortStatus message from a switch. We will add or
-     * delete LinkTupes as well re-compute the topology if needed.
+     * Handles an OFPortStatus message from a switch. We will add or delete
+     * LinkTupes as well re-compute the topology if needed.
      *
      * @param sw The dpid of the switch that sent the port status message
      * @param ps The OFPortStatus message
@@ -657,14 +673,14 @@
         if (log.isTraceEnabled()) {
             log.trace("handlePortStatus: Switch {} port #{} reason {}; " +
                     "config is {} state is {}",
-                    new Object[]{sw.getStringId(),
-                            ps.getDesc().getPortNumber(),
+                    new Object[] {sw.getStringId(),
+                            ps.getDesc().getPortNo(),
                             ps.getReason(),
                             ps.getDesc().getConfig(),
                             ps.getDesc().getState()});
         }
 
-        short port = ps.getDesc().getPortNumber();
+        short port = ps.getDesc().getPortNo().getShortPortNumber();
         NodePortTuple npt = new NodePortTuple(sw.getId(), port);
         boolean linkDeleted = false;
         boolean linkInfoChanged = false;
@@ -673,14 +689,12 @@
         try {
             // if ps is a delete, or a modify where the port is down or
             // configured down
-            if ((byte) OFPortReason.OFPPR_DELETE.ordinal() == ps.getReason() ||
-                    ((byte) OFPortReason.OFPPR_MODIFY.ordinal() ==
-                            ps.getReason() && !portEnabled(ps.getDesc()))) {
-
+            if (OFPortReason.DELETE == ps.getReason() ||
+                    (OFPortReason.MODIFY == ps.getReason() &&
+                    !portEnabled(ps.getDesc()))) {
                 deleteLinksOnPort(npt);
                 linkDeleted = true;
-            } else if (ps.getReason() ==
-                    (byte) OFPortReason.OFPPR_MODIFY.ordinal()) {
+            } else if (ps.getReason() == OFPortReason.MODIFY) {
                 // If ps is a port modification and the port state has changed
                 // that affects links in the topology
 
@@ -691,18 +705,22 @@
                         LinkInfo newLinkInfo = null;
 
                         if (lt.isSrcPort(npt) &&
-                                linkInfo.getSrcPortState() != ps.getDesc().getState()) {
-                            // If this port status is for the src port and the port
-                            // state has changed, create a new link info with the new state
+                                !linkInfo.getSrcPortState().equals(
+                                        ps.getDesc().getState())) {
+                            // If this port status is for the src port and the
+                            // port state has changed, create a new link info
+                            // with the new state
 
                             newLinkInfo = new LinkInfo(linkInfo.getFirstSeenTime(),
                                     linkInfo.getLastProbeReceivedTime(),
                                     ps.getDesc().getState(),
                                     linkInfo.getDstPortState());
                         } else if (lt.isDstPort(npt) &&
-                                linkInfo.getDstPortState() != ps.getDesc().getState()) {
-                            // If this port status is for the dst port and the port
-                            // state has changed, create a new link info with the new state
+                                !linkInfo.getDstPortState().equals(
+                                        ps.getDesc().getState())) {
+                            // If this port status is for the dst port and the
+                            // port state has changed, create a new link info
+                            // with the new state
 
                             newLinkInfo = new LinkInfo(linkInfo.getFirstSeenTime(),
                                     linkInfo.getLastProbeReceivedTime(),
@@ -718,13 +736,12 @@
                 }
             }
 
-
             if (!linkDeleted && !linkInfoChanged) {
                 if (log.isTraceEnabled()) {
                     log.trace("handlePortStatus: Switch {} port #{} reason {};" +
                             " no links to update/remove",
-                            new Object[]{HexString.toHexString(sw.getId()),
-                                    ps.getDesc().getPortNumber(),
+                            new Object[] {HexString.toHexString(sw.getId()),
+                                    ps.getDesc().getPortNo(),
                                     ps.getReason()});
                 }
             }
@@ -745,32 +762,37 @@
     }
 
     /**
-     * Process a new port.
-     * If link discovery is disabled on the port, then do nothing.
-     * Otherwise, send LLDP message.
+     * Process a new port. If link discovery is disabled on the port, then do
+     * nothing. Otherwise, send LLDP message.
      *
      * @param sw the dpid of the switch the port is on
      * @param p the number of the port
      */
-    private void processNewPort(long sw, short p) {
-        if (isLinkDiscoverySuppressed(sw, p)) {
+    private void processNewPort(long sw, int p) {
+        if (isLinkDiscoverySuppressed(sw, (short) p)) {
             // Do nothing as link discovery is suppressed.
             return;
         } else {
-            discover(sw, p);
+            discover(sw, (short) p);
         }
     }
 
     /**
-     * We send out LLDP messages when a switch is added to discover the topology.
+     * We send out LLDP messages when a switch is added to discover the
+     * topology.
      *
-     * @param sw The IOFSwitch that connected to the controller
+     * @param swId the datapath Id of the new switch
      */
     @Override
-    public void addedSwitch(IOFSwitch sw) {
+    public void switchActivatedMaster(long swId) {
+        IOFSwitch sw = floodlightProvider.getSwitch(swId);
+        if (sw == null) {
+            log.warn("Added switch not available {} ", swId);
+            return;
+        }
         if (sw.getEnabledPorts() != null) {
-            for (Short p : sw.getEnabledPortNumbers()) {
-                processNewPort(sw.getId(), p);
+            for (Integer p : sw.getEnabledPortNumbers()) {
+                processNewPort(swId, p);
             }
         }
     }
@@ -778,23 +800,27 @@
     /**
      * When a switch disconnects we remove any links from our map and notify.
      *
-     * @param iofSwitch the switch that was removed
+     * @param swId the datapath Id of the switch that was removed
      */
     @Override
-    public void removedSwitch(IOFSwitch iofSwitch) {
+    public void switchDisconnected(long swId) {
+        IOFSwitch sw = floodlightProvider.getSwitch(swId);
+        if (sw == null) {
+            log.warn("Removed switch not available {} ", swId);
+            return;
+        }
         // Update event history
-        long sw = iofSwitch.getId();
 
         List<Link> eraseList = new ArrayList<Link>();
         lock.writeLock().lock();
         try {
-            if (switchLinks.containsKey(sw)) {
+            if (switchLinks.containsKey(swId)) {
                 if (log.isTraceEnabled()) {
                     log.trace("Handle switchRemoved. Switch {}; removing links {}",
-                            HexString.toHexString(sw), switchLinks.get(sw));
+                            HexString.toHexString(swId), switchLinks.get(swId));
                 }
                 // add all tuples with an endpoint on this switch to erase list
-                eraseList.addAll(switchLinks.get(sw));
+                eraseList.addAll(switchLinks.get(swId));
                 deleteLinks(eraseList);
             }
         } finally {
@@ -802,14 +828,34 @@
         }
     }
 
+    @Override
+    public void switchActivatedEqual(long swId) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void switchMasterToEqual(long swId) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void switchEqualToMaster(long swId) {
+        // for now treat as switchActivatedMaster
+        switchActivatedMaster(swId);
+    }
+
     /*
-     * We don't react the port changed notifications here. we listen for
+     * We don't react to port changed notifications here. we listen for
      * OFPortStatus messages directly. Might consider using this notifier
      * instead
      */
     @Override
-    public void switchPortChanged(Long switchId) {
-        // no-op
+    public void switchPortChanged(long swId, OFPortDesc port,
+            PortChangeType changeType) {
+        // TODO Auto-generated method stub
+
     }
 
     /**
@@ -823,7 +869,7 @@
             if (log.isTraceEnabled()) {
                 log.trace("handlePortStatus: Switch {} port #{} " +
                         "removing links {}",
-                        new Object[]{HexString.toHexString(npt.getNodeId()),
+                        new Object[] {HexString.toHexString(npt.getNodeId()),
                                 npt.getPortId(),
                                 this.portLinks.get(npt)});
             }
@@ -833,8 +879,8 @@
     }
 
     /**
-     * Iterates through the list of links and deletes if the
-     * last discovery message reception time exceeds timeout values.
+     * Iterates through the list of links and deletes if the last discovery
+     * message reception time exceeds timeout values.
      */
     protected void timeOutLinks() {
         List<Link> eraseList = new ArrayList<Link>();
@@ -850,7 +896,7 @@
                 LinkInfo info = entry.getValue();
 
                 if ((info.getLastProbeReceivedTime() + (1000L * LINK_TIMEOUT)
-                        < curTime)) {
+                < curTime)) {
                     eraseList.add(entry.getKey());
                 }
             }
@@ -861,14 +907,14 @@
         }
     }
 
-    private boolean portEnabled(OFPhysicalPort port) {
+    private boolean portEnabled(OFPortDesc port) {
         if (port == null) {
             return false;
         }
-        if ((OFPortConfig.OFPPC_PORT_DOWN.getValue() & port.getConfig()) > 0) {
+        if (port.getConfig().contains(OFPortConfig.PORT_DOWN)) {
             return false;
         }
-        if ((OFPortState.OFPPS_LINK_DOWN.getValue() & port.getState()) > 0) {
+        if (port.getState().contains(OFPortState.LINK_DOWN)) {
             return false;
         }
         return true;
@@ -955,7 +1001,8 @@
     @LogMessageDocs({
             @LogMessageDoc(level = "ERROR",
                     message = "No storage source found.",
-                    explanation = "Storage source was not initialized; cannot initialize " +
+                    explanation = "Storage source was not initialized; cannot initialize "
+                            +
                             "link discovery.",
                     recommendation = LogMessageDoc.REPORT_CONTROLLER_BUG),
             @LogMessageDoc(level = "ERROR",
@@ -966,7 +1013,8 @@
                     recommendation = LogMessageDoc.REPORT_CONTROLLER_BUG),
             @LogMessageDoc(level = "ERROR",
                     message = "No storage source found.",
-                    explanation = "Storage source was not initialized; cannot initialize " +
+                    explanation = "Storage source was not initialized; cannot initialize "
+                            +
                             "link discovery.",
                     recommendation = LogMessageDoc.REPORT_CONTROLLER_BUG),
             @LogMessageDoc(level = "ERROR",
diff --git a/src/main/java/net/onrc/onos/core/linkdiscovery/LinkInfo.java b/src/main/java/net/onrc/onos/core/linkdiscovery/LinkInfo.java
index fc19951..bc11c91 100644
--- a/src/main/java/net/onrc/onos/core/linkdiscovery/LinkInfo.java
+++ b/src/main/java/net/onrc/onos/core/linkdiscovery/LinkInfo.java
@@ -1,6 +1,7 @@
 /**
  *    Copyright 2011, Big Switch Networks, Inc.
  *    Originally created by David Erickson, Stanford University
+ *
  *    Licensed under the Apache License, Version 2.0 (the "License"); you may
  *    not use this file except in compliance with the License. You may obtain
  *    a copy of the License at
@@ -12,34 +13,35 @@
  *    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  *    License for the specific language governing permissions and limitations
  *    under the License.
- */
+ **/
 
 package net.onrc.onos.core.linkdiscovery;
 
+import java.util.Set;
+
 import net.onrc.onos.core.linkdiscovery.ILinkDiscoveryService.LinkType;
 
+import org.projectfloodlight.openflow.protocol.OFPortState;
+
 import com.google.common.primitives.Longs;
 
 /**
  * Records information about a link.
  */
 public final class LinkInfo {
-
     /**
-     * The port states stored here are topology's last knowledge of
-     * the state of the port. This mostly mirrors the state
-     * maintained in the port list in IOFSwitch (i.e. the one returned
-     * from getPort), except that during a port status message the
-     * IOFSwitch port state will already have been updated with the
-     * new port state, so topology needs to keep its own copy so that
-     * it can determine if the port state has changed and therefore
-     * requires the new state to be written to storage.
-     *
-     * Note the port state values are defined in the OF 1.0 spec.
-     * These will change in some way once we move to OF 1.3.
+     * The port states stored here are topology's last knowledge of the state of
+     * the port. This mostly mirrors the state maintained in the port list in
+     * IOFSwitch (i.e. the one returned from getPort), except that during a port
+     * status message the IOFSwitch port state will already have been updated
+     * with the new port state, so topology needs to keep its own copy so that
+     * it can determine if the port state has changed and therefore requires the
+     * new state to be written to storage. Note the port state values are
+     * defined in the OF 1.0 spec. These will change in some way once we move to
+     * OF 1.3.
      */
-    private final int srcPortState;
-    private final int dstPortState;
+    private final Set<OFPortState> srcPortState;
+    private final Set<OFPortState> dstPortState;
 
     private final long firstSeenTime;
     private final long lastLldpReceivedTime;
@@ -54,8 +56,8 @@
      */
     public LinkInfo(long firstSeenTime,
             long lastLldpReceivedTime,
-            int srcPortState,
-            int dstPortState) {
+            Set<OFPortState> srcPortState,
+            Set<OFPortState> dstPortState) {
         this.srcPortState = srcPortState;
         this.dstPortState = dstPortState;
         this.firstSeenTime = firstSeenTime;
@@ -85,20 +87,47 @@
      *
      * @return the source port state, as defined in the OF1.0 spec
      */
-    public int getSrcPortState() {
+    public Set<OFPortState> getSrcPortState() {
         return srcPortState;
     }
 
+    public int getSrcPortStateInteger() {
+        return convertPortState(srcPortState);
+    }
+
     /**
      * Gets the state of the destination port.
      *
      * @return the destination port state, as defined in the OF1.0 spec
      */
-    public int getDstPortState() {
+    public Set<OFPortState> getDstPortState() {
         return dstPortState;
     }
 
     /**
+     * Gets the state of the destination port.
+     *
+     * @return the destination port state, as defined in the OF1.0 spec
+     */
+    public int getDstPortStateInteger() {
+        return convertPortState(dstPortState);
+    }
+
+    private int convertPortState(Set<OFPortState> ps) {
+        int ret = 0;
+        if (ps.contains(OFPortState.LINK_DOWN)) {
+            ret = 1 << 0;
+        }
+        if (ps.contains(OFPortState.BLOCKED)) {
+            ret = ret | 1 << 1;
+        }
+        if (ps.contains(OFPortState.LIVE)) {
+            ret = ret | 1 << 2;
+        }
+        return ret;
+    }
+
+    /**
      * Gets the link type.
      *
      * @return the link type
@@ -117,8 +146,8 @@
         int result = 1;
         result = prime * result + Longs.hashCode(firstSeenTime);
         result = prime * result + Longs.hashCode(lastLldpReceivedTime);
-        result = prime * result + srcPortState;
-        result = prime * result + dstPortState;
+        result = prime * result + convertPortState(srcPortState);
+        result = prime * result + convertPortState(dstPortState);
         return result;
     }
 
@@ -138,12 +167,11 @@
         LinkInfo other = (LinkInfo) obj;
 
         return firstSeenTime == other.firstSeenTime &&
-               lastLldpReceivedTime == other.lastLldpReceivedTime &&
-               srcPortState == other.srcPortState &&
-               dstPortState == other.dstPortState;
+                lastLldpReceivedTime == other.lastLldpReceivedTime &&
+                srcPortState == other.srcPortState &&
+                dstPortState == other.dstPortState;
     }
 
-
     /* (non-Javadoc)
      * @see java.lang.Object#toString()
      */
diff --git a/src/main/java/net/onrc/onos/core/linkdiscovery/web/LinksResource.java b/src/main/java/net/onrc/onos/core/linkdiscovery/web/LinksResource.java
index 2738041..cb83972 100644
--- a/src/main/java/net/onrc/onos/core/linkdiscovery/web/LinksResource.java
+++ b/src/main/java/net/onrc/onos/core/linkdiscovery/web/LinksResource.java
@@ -28,8 +28,8 @@
                 Link link = e.getKey();
                 LinkInfo info = e.getValue();
                 LinkWithType lwt = new LinkWithType(link,
-                        info.getSrcPortState(),
-                        info.getDstPortState(),
+                        info.getSrcPortStateInteger(),
+                        info.getDstPortStateInteger(),
                         info.getLinkType());
                 returnLinkSet.add(lwt);
             }
diff --git a/src/main/java/net/onrc/onos/core/main/IOFSwitchPortListener.java b/src/main/java/net/onrc/onos/core/main/IOFSwitchPortListener.java
index edf4539..6f6e21b 100644
--- a/src/main/java/net/onrc/onos/core/main/IOFSwitchPortListener.java
+++ b/src/main/java/net/onrc/onos/core/main/IOFSwitchPortListener.java
@@ -3,9 +3,9 @@
  */
 package net.onrc.onos.core.main;
 
+import org.projectfloodlight.openflow.protocol.OFPortDesc;
 import net.floodlightcontroller.core.IOFSwitchListener;
 
-import org.openflow.protocol.OFPhysicalPort;
 
 /**
  * Extra event handler added to IOFSwitchListener by ONOS.
@@ -15,11 +15,11 @@
     /**
      * Fired when ports on a switch area added.
      */
-    public void switchPortAdded(Long switchId, OFPhysicalPort port);
+    public void switchPortAdded(Long switchId, OFPortDesc port);
 
     /**
      * Fired when ports on a switch area removed.
      */
-    public void switchPortRemoved(Long switchId, OFPhysicalPort port);
+    public void switchPortRemoved(Long switchId, OFPortDesc port);
 
 }
diff --git a/src/main/java/net/onrc/onos/core/main/Main.java b/src/main/java/net/onrc/onos/core/main/Main.java
index 78dad3c..7c7ec03 100644
--- a/src/main/java/net/onrc/onos/core/main/Main.java
+++ b/src/main/java/net/onrc/onos/core/main/Main.java
@@ -12,8 +12,6 @@
 
 /**
  * Host for the ONOS main method.
- * <!-- CHECKSTYLE IGNORE WriteTag FOR NEXT 1 LINES -->
- * @author alexreimers
  */
 public final class Main {
 
diff --git a/src/main/java/net/onrc/onos/core/packetservice/PacketModule.java b/src/main/java/net/onrc/onos/core/packetservice/PacketModule.java
index afe2770..63143cd 100644
--- a/src/main/java/net/onrc/onos/core/packetservice/PacketModule.java
+++ b/src/main/java/net/onrc/onos/core/packetservice/PacketModule.java
@@ -30,14 +30,14 @@
 import net.onrc.onos.core.util.PortNumber;
 import net.onrc.onos.core.util.SwitchPort;
 
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFPacketOut;
-import org.openflow.protocol.OFPhysicalPort;
-import org.openflow.protocol.OFPort;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.action.OFAction;
-import org.openflow.protocol.action.OFActionOutput;
+import org.projectfloodlight.openflow.protocol.OFFactory;
+import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFPacketIn;
+import org.projectfloodlight.openflow.protocol.OFPacketOut;
+import org.projectfloodlight.openflow.protocol.OFPortDesc;
+import org.projectfloodlight.openflow.protocol.OFType;
+import org.projectfloodlight.openflow.protocol.action.OFAction;
+import org.projectfloodlight.openflow.types.OFPort;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -45,7 +45,7 @@
 import com.google.common.collect.Multimap;
 
 public class PacketModule implements IOFMessageListener, IPacketService,
-                                     IFloodlightModule {
+        IFloodlightModule {
     private static final Logger log = LoggerFactory.getLogger(PacketModule.class);
 
     private final CopyOnWriteArrayList<IPacketListener> listeners;
@@ -54,9 +54,9 @@
     private Topology topology;
     private IDatagridService datagrid;
     private IFlowPusherService flowPusher;
+    private OFFactory factory;
 
-    private IEventChannel<Long, PacketOutNotification>
-            packetOutEventChannel;
+    private IEventChannel<Long, PacketOutNotification> packetOutEventChannel;
 
     private static final String PACKET_OUT_CHANNEL_NAME =
             "onos.packet_out";
@@ -71,8 +71,9 @@
         public void entryAdded(PacketOutNotification value) {
             Multimap<Long, Short> localPorts = HashMultimap.create();
             for (IOFSwitch sw : floodlightProvider.getSwitches().values()) {
-                for (OFPhysicalPort port : sw.getEnabledPorts()) {
-                    localPorts.put(sw.getId(), port.getPortNumber());
+                for (OFPortDesc port : sw.getEnabledPorts()) {
+                    // XXX S fix this to int
+                    localPorts.put(sw.getId(), port.getPortNo().getShortPortNumber());
                 }
             }
             Multimap<Long, Short> outPorts = value.calculateOutPorts(
@@ -104,7 +105,7 @@
     public void sendPacket(Ethernet eth, SwitchPort switchPort) {
         SinglePacketOutNotification notification =
                 new SinglePacketOutNotification(eth.serialize(), 0,
-                switchPort.dpid().value(), switchPort.port().shortValue());
+                        switchPort.dpid().value(), switchPort.port().shortValue());
 
         // TODO We shouldn't care what the destination MAC is
         long dstMac = eth.getDestinationMAC().toLong();
@@ -127,7 +128,7 @@
     public void broadcastPacketOutEdge(Ethernet eth, SwitchPort inSwitchPort) {
         BroadcastPacketOutNotification notification =
                 new BroadcastPacketOutNotification(eth.serialize(), 0,
-                inSwitchPort.dpid().value(), inSwitchPort.port().shortValue());
+                        inSwitchPort.dpid().value(), inSwitchPort.port().shortValue());
 
         long dstMac = eth.getDestinationMAC().toLong();
         packetOutEventChannel.addTransientEntry(dstMac, notification);
@@ -140,7 +141,6 @@
 
     @Override
     public boolean isCallbackOrderingPrereq(OFType type, String name) {
-        // TODO Auto-generated method stub
         return false;
     }
 
@@ -156,18 +156,19 @@
             return Command.CONTINUE;
         }
 
-        OFPacketIn pi = (OFPacketIn) msg;
-
         Ethernet eth = IFloodlightProviderService.bcStore.
                 get(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
+        short inport = (short) cntx.getStorage()
+                .get(IFloodlightProviderService.CONTEXT_PI_INPORT);
 
         Switch topologySwitch;
         Port inPort;
-        final Dpid dpid = new Dpid(sw.getId());
-        topology.acquireReadLock();
         try {
+            topology.acquireReadLock();
+            Dpid dpid = new Dpid(sw.getId());
+            PortNumber p = new PortNumber(inport);
             topologySwitch = topology.getSwitch(dpid);
-            inPort = topology.getPort(dpid, new PortNumber(pi.getInPort()));
+            inPort = topology.getPort(dpid, p);
         } finally {
             topology.releaseReadLock();
         }
@@ -194,9 +195,9 @@
 
     @Override
     public Map<Class<? extends IFloodlightService>, IFloodlightService>
-    getServiceImpls() {
-        Map<Class<? extends IFloodlightService>, IFloodlightService>
-        serviceImpls = new HashMap<>();
+            getServiceImpls() {
+
+        Map<Class<? extends IFloodlightService>, IFloodlightService> serviceImpls = new HashMap<>();
         serviceImpls.put(IPacketService.class, this);
         return serviceImpls;
     }
@@ -220,12 +221,12 @@
                 .getTopology();
         datagrid = context.getServiceImpl(IDatagridService.class);
         flowPusher = context.getServiceImpl(IFlowPusherService.class);
+        factory = floodlightProvider.getOFMessageFactory_10();
     }
 
     @Override
     public void startUp(FloodlightModuleContext context) {
         floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
-
         packetOutEventChannel = datagrid.addListener(PACKET_OUT_CHANNEL_NAME,
                 packetOutEventHandler,
                 Long.class,
@@ -235,31 +236,25 @@
     private void sendPacketToSwitches(Multimap<Long, Short> outPorts,
             byte[] packetData) {
         for (Long dpid : outPorts.keySet()) {
-            OFPacketOut po = new OFPacketOut();
-            po.setInPort(OFPort.OFPP_NONE)
-              .setBufferId(OFPacketOut.BUFFER_ID_NONE)
-              .setPacketData(packetData);
-
-            List<OFAction> actions = new ArrayList<OFAction>();
-            for (Short port : outPorts.get(dpid)) {
-                actions.add(new OFActionOutput(port));
-            }
-
-            po.setActions(actions);
-            short actionsLength = (short)
-                    (actions.size() * OFActionOutput.MINIMUM_LENGTH);
-            po.setActionsLength(actionsLength);
-            po.setLengthU(OFPacketOut.MINIMUM_LENGTH + actionsLength
-                    + packetData.length);
-
             IOFSwitch sw = floodlightProvider.getSwitches().get(dpid);
 
             if (sw == null) {
-                log.warn("Switch not found when sending packet");
-                return;
+                log.warn("Switch {} not found when sending packet", dpid);
+                continue;
             }
 
+            List<OFAction> actions = new ArrayList<>();
+            for (Short port : outPorts.get(dpid)) {
+                actions.add(factory.actions().output(OFPort.of(port), Short.MAX_VALUE));
+            }
+
+            OFPacketOut po = factory.buildPacketOut()
+                    .setData(packetData)
+                    .setActions(actions)
+                    .build();
+
             flowPusher.add(sw, po);
         }
     }
+
 }
diff --git a/src/main/java/net/onrc/onos/core/registry/IControllerRegistryService.java b/src/main/java/net/onrc/onos/core/registry/IControllerRegistryService.java
index cfc47c8..ef441db 100644
--- a/src/main/java/net/onrc/onos/core/registry/IControllerRegistryService.java
+++ b/src/main/java/net/onrc/onos/core/registry/IControllerRegistryService.java
@@ -8,18 +8,18 @@
 import net.onrc.onos.core.util.OnosInstanceId;
 
 /**
- * A registry service that allows ONOS to register controllers and switches
- * in a way that is global to the entire ONOS cluster. The registry is the
- * arbiter for allowing controllers to control switches.
+ * A registry service that allows ONOS to register controllers and switches in a
+ * way that is global to the entire ONOS cluster. The registry is the arbiter
+ * for allowing controllers to control switches.
  * <p/>
  * The OVS/OF1.{2,3} fault tolerance model is a switch connects to multiple
- * controllers, and the controllers send role requests to determine what their
- * role is in controlling the switch.
+ * controllers, and the controllers send role requests to tell the switch their
+ * role in controlling the switch.
  * <p/>
  * The ONOS fault tolerance model allows only a single controller to have
  * control of a switch (MASTER role) at once. Controllers therefore need a
- * mechanism that enables them to decide who should control a each switch.
- * The registry service provides this mechanism.
+ * mechanism that enables them to decide who should control a each switch. The
+ * registry service provides this mechanism.
  */
 public interface IControllerRegistryService extends IFloodlightService {
 
@@ -29,43 +29,41 @@
     public interface ControlChangeCallback {
         /**
          * Called whenever the control changes from the point of view of the
-         * registry. The callee can check whether they have control or not
-         * using the hasControl parameter.
+         * registry. The callee can check whether they have control or not using
+         * the hasControl parameter.
          *
-         * @param dpid       The switch that control has changed for
+         * @param dpid The switch that control has changed for
          * @param hasControl Whether the listener now has control or not
          */
         void controlChanged(long dpid, boolean hasControl);
     }
 
     /**
-     * Request for control of a switch. This method does not block. When
-     * control for a switch changes, the controlChanged method on the
-     * callback object will be called. This happens any time the control
-     * changes while the request is still active (until releaseControl is
-     * called)
+     * Request for control of a switch. This method does not block. When control
+     * for a switch changes, the controlChanged method on the callback object
+     * will be called. This happens any time the control changes while the
+     * request is still active (until releaseControl is called)
      *
      * @param dpid Switch to request control for
-     * @param cb   Callback that will be used to notify caller of control
-     *             changes
+     * @param cb Callback that will be used to notify caller of control changes
      * @throws RegistryException Errors contacting the registry service
      */
     public void requestControl(long dpid, ControlChangeCallback cb)
             throws RegistryException;
 
     /**
-     * Stop trying to take control of a switch. This removes the entry
-     * for this controller requesting this switch in the registry.
-     * If the controller had control when this is called, another controller
-     * will now gain control of the switch. This call doesn't block.
+     * Stop trying to take control of a switch. This removes the entry for this
+     * controller requesting this switch in the registry. If the controller had
+     * control when this is called, another controller will now gain control of
+     * the switch. This call doesn't block.
      *
      * @param dpid Switch to release control of
      */
     public void releaseControl(long dpid);
 
     /**
-     * Check whether the controller has control of the switch
-     * This call doesn't block.
+     * Check whether the controller has control of the switch This call doesn't
+     * block.
      *
      * @param dpid Switch to check control of
      * @return true if controller has control of the switch.
@@ -73,11 +71,11 @@
     public boolean hasControl(long dpid);
 
     /**
-     * Check whether this instance is the leader for the cluster.
-     * This call doesn't block.
+     * Check whether this instance is the leader for the cluster. This call
+     * doesn't block.
      *
-     * @return true if the instance is the leader for the cluster,
-     * otherwise false.
+     * @return true if the instance is the leader for the cluster, otherwise
+     *         false.
      */
     public boolean isClusterLeader();
 
@@ -89,13 +87,13 @@
     public OnosInstanceId getOnosInstanceId();
 
     /**
-     * Register a controller to the ONOS cluster. Must be called before
-     * the registry can be used to take control of any switches.
+     * Register a controller to the ONOS cluster. Must be called before the
+     * registry can be used to take control of any switches.
      *
-     * @param controllerId A unique string ID identifying this controller
-     *                     in the cluster
+     * @param controllerId A unique string ID identifying this controller in the
+     *        cluster
      * @throws RegistryException for errors connecting to registry service,
-     *                           controllerId already registered
+     *         controllerId already registered
      */
     public void registerController(String controllerId)
             throws RegistryException;
@@ -109,9 +107,9 @@
     public Collection<String> getAllControllers() throws RegistryException;
 
     /**
-     * Get all switches in the cluster, along with which controller is
-     * in control of them (if any) and any other controllers that have
-     * requested control.
+     * Get all switches in the cluster, along with which controller is in
+     * control of them (if any) and any other controllers that have requested
+     * control.
      *
      * @return Map of all switches.
      */
@@ -149,7 +147,6 @@
      */
     public IdBlock allocateUniqueIdBlock(long range);
 
-
     /**
      * Get a globally unique ID.
      *
diff --git a/src/main/java/net/onrc/onos/core/topology/TopologyPublisher.java b/src/main/java/net/onrc/onos/core/topology/TopologyPublisher.java
index ed450f2..8b77745 100644
--- a/src/main/java/net/onrc/onos/core/topology/TopologyPublisher.java
+++ b/src/main/java/net/onrc/onos/core/topology/TopologyPublisher.java
@@ -9,20 +9,20 @@
 import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IFloodlightProviderService.Role;
 import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.core.IOFSwitch.PortChangeType;
+import net.floodlightcontroller.core.IOFSwitchListener;
 import net.floodlightcontroller.core.module.FloodlightModuleContext;
 import net.floodlightcontroller.core.module.FloodlightModuleException;
 import net.floodlightcontroller.core.module.IFloodlightModule;
 import net.floodlightcontroller.core.module.IFloodlightService;
 import net.floodlightcontroller.core.util.SingletonTask;
 import net.floodlightcontroller.threadpool.IThreadPoolService;
-import net.onrc.onos.api.registry.ILocalSwitchMastershipListener;
 import net.onrc.onos.core.hostmanager.Host;
 import net.onrc.onos.core.hostmanager.IHostListener;
 import net.onrc.onos.core.hostmanager.IHostService;
 import net.onrc.onos.core.linkdiscovery.ILinkDiscoveryListener;
 import net.onrc.onos.core.linkdiscovery.ILinkDiscoveryService;
 import net.onrc.onos.core.linkdiscovery.Link;
-import net.onrc.onos.core.main.IOFSwitchPortListener;
 import net.onrc.onos.core.registry.IControllerRegistryService;
 import net.onrc.onos.core.registry.IControllerRegistryService.ControlChangeCallback;
 import net.onrc.onos.core.registry.RegistryException;
@@ -30,8 +30,8 @@
 import net.onrc.onos.core.util.PortNumber;
 import net.onrc.onos.core.util.SwitchPort;
 
-import org.openflow.protocol.OFPhysicalPort;
-import org.openflow.util.HexString;
+import org.projectfloodlight.openflow.protocol.OFPortDesc;
+import org.projectfloodlight.openflow.util.HexString;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -40,12 +40,10 @@
  * discovery modules. These events are reformatted and relayed to the in-memory
  * topology instance.
  */
-public class TopologyPublisher implements /*IOFSwitchListener,*/
-        IOFSwitchPortListener,
+public class TopologyPublisher implements IOFSwitchListener,
         ILinkDiscoveryListener,
         IFloodlightModule,
-        IHostListener,
-        ILocalSwitchMastershipListener {
+        IHostListener {
     private static final Logger log =
             LoggerFactory.getLogger(TopologyPublisher.class);
 
@@ -65,8 +63,8 @@
     private SingletonTask cleanupTask;
 
     /**
-     * Cleanup old switches from the topology. Old switches are those
-     * which have no controller in the registry.
+     * Cleanup old switches from the topology. Old switches are those which have
+     * no controller in the registry.
      */
     private class SwitchCleanup implements ControlChangeCallback, Runnable {
         @Override
@@ -97,7 +95,8 @@
             if (log.isTraceEnabled()) {
                 log.trace("Checking for inactive switches");
             }
-            // For each switch check if a controller exists in controller registry
+            // For each switch check if a controller exists in controller
+            // registry
             for (Switch sw : switches) {
                 // FIXME How to handle case where Switch has never been
                 // registered to ZK
@@ -120,10 +119,10 @@
 
         /**
          * Second half of the switch cleanup operation. If the registry grants
-         * control of a switch, we can be sure no other instance is writing
-         * this switch to the topology, so we can remove it now.
-         *
-         * @param dpid       the dpid of the switch we requested control for
+         * control of a switch, we can be sure no other instance is writing this
+         * switch to the topology, so we can remove it now.
+         * <p>
+         * @param dpid the dpid of the switch we requested control for
          * @param hasControl whether we got control or not
          */
         @Override
@@ -150,7 +149,7 @@
         // TODO define attr name as constant somewhere.
         // TODO populate appropriate attributes.
         linkEvent.createStringAttribute(TopologyElement.TYPE,
-                                        TopologyElement.TYPE_PACKET_LAYER);
+                TopologyElement.TYPE_PACKET_LAYER);
         linkEvent.createStringAttribute(TopologyElement.ELEMENT_CONFIG_STATE,
                 ConfigState.NOT_CONFIGURED.toString());
         linkEvent.createStringAttribute(TopologyElement.ELEMENT_ADMIN_STATUS,
@@ -177,51 +176,173 @@
         // TODO define attr name as constant somewhere.
         // TODO populate appropriate attributes.
         linkEvent.createStringAttribute(TopologyElement.TYPE,
-                                        TopologyElement.TYPE_PACKET_LAYER);
+                TopologyElement.TYPE_PACKET_LAYER);
         linkEvent.freeze();
 
         if (!registryService.hasControl(link.getDst())) {
             // Don't process or send a link event if we're not master for the
             // destination switch
-            log.debug("Not the master for dst switch {}. Suppressed link remove event {}.",
+            log.debug(
+                    "Not the master for dst switch {}. Suppressed link remove event {}.",
                     link.getDst(), linkEvent);
             return;
         }
         topologyDiscoveryInterface.removeLinkDiscoveryEvent(linkEvent);
     }
 
+    /* *****************
+     * IOFSwitchListener
+     * *****************/
+
     @Override
-    public void switchPortAdded(Long switchId, OFPhysicalPort port) {
+    public void switchActivatedMaster(long swId) {
+        IOFSwitch sw = floodlightProvider.getSwitch(swId);
+        final Dpid dpid = new Dpid(swId);
+        if (sw == null) {
+            log.warn("Added switch not available {} ", dpid);
+            return;
+        }
+
+        controllerRoleChanged(dpid, Role.MASTER);
+
+        SwitchEvent switchEvent = new SwitchEvent(dpid);
+        // FIXME should be merging, with existing attrs, etc..
+        // TODO define attr name as constant somewhere.
+        // TODO populate appropriate attributes.
+        switchEvent.createStringAttribute(TopologyElement.TYPE,
+                TopologyElement.TYPE_PACKET_LAYER);
+        switchEvent.createStringAttribute("ConnectedSince",
+                sw.getConnectedSince().toString());
+        switchEvent.createStringAttribute(TopologyElement.ELEMENT_CONFIG_STATE,
+                ConfigState.NOT_CONFIGURED.toString());
+        switchEvent.createStringAttribute(TopologyElement.ELEMENT_ADMIN_STATUS,
+                AdminStatus.ACTIVE.toString());
+        switchEvent.freeze();
+        // TODO Not very robust
+        if (!registryService.hasControl(swId)) {
+            log.debug("Not the master for switch {}. Suppressed switch add event {}.",
+                    dpid, switchEvent);
+            return;
+        }
+        List<PortEvent> portEvents = new ArrayList<PortEvent>();
+        for (OFPortDesc port : sw.getPorts()) {
+            PortEvent portEvent = new PortEvent(dpid,
+                    new PortNumber(port.getPortNo().getShortPortNumber()));
+            // FIXME should be merging, with existing attrs, etc..
+            // TODO define attr name as constant somewhere.
+            // TODO populate appropriate attributes.
+            portEvent.createStringAttribute("name", port.getName());
+            portEvent.createStringAttribute(TopologyElement.TYPE,
+                    TopologyElement.TYPE_PACKET_LAYER);
+            portEvent.createStringAttribute(TopologyElement.ELEMENT_CONFIG_STATE,
+                    ConfigState.NOT_CONFIGURED.toString());
+            portEvent.createStringAttribute(TopologyElement.ELEMENT_ADMIN_STATUS,
+                    AdminStatus.ACTIVE.toString());
+
+            portEvent.freeze();
+            portEvents.add(portEvent);
+        }
+        topologyDiscoveryInterface.putSwitchDiscoveryEvent(switchEvent, portEvents);
+
+        for (OFPortDesc port : sw.getPorts()) {
+            // Allow links to be discovered on this port now that it's
+            // in the database
+            linkDiscovery.enableDiscoveryOnPort(sw.getId(),
+                    port.getPortNo().getShortPortNumber());
+        }
+    }
+
+    @Override
+    public void switchActivatedEqual(long swId) {
+        final Dpid dpid = new Dpid(swId);
+        controllerRoleChanged(dpid, Role.EQUAL);
+    }
+
+    @Override
+    public void switchMasterToEqual(long swId) {
+        final Dpid dpid = new Dpid(swId);
+        controllerRoleChanged(dpid, Role.EQUAL);
+    }
+
+    @Override
+    public void switchEqualToMaster(long swId) {
+        // for now treat as switchActivatedMaster
+        switchActivatedMaster(swId);
+    }
+
+    @Override
+    public void switchDisconnected(long swId) {
+        final Dpid dpid = new Dpid(swId);
+
+        log.debug("Local switch disconnected: dpid = {} role = {}", dpid);
+
+        Role role = Role.SLAVE; // TODO: Should be Role.UNKNOWN
+
+        MastershipEvent mastershipEvent =
+                new MastershipEvent(dpid, registryService.getOnosInstanceId(),
+                        role);
+        // FIXME should be merging, with existing attrs, etc..
+        // TODO define attr name as constant somewhere.
+        // TODO populate appropriate attributes.
+        mastershipEvent.createStringAttribute(TopologyElement.TYPE,
+                TopologyElement.TYPE_ALL_LAYERS);
+        mastershipEvent.freeze();
+        topologyDiscoveryInterface.removeSwitchMastershipEvent(mastershipEvent);
+    }
+
+    @Override
+    public void switchPortChanged(long swId, OFPortDesc port,
+            PortChangeType changeType) {
+        switch (changeType) {
+        case ADD:
+            switchPortAdded(swId, port);
+            break;
+        case DELETE:
+            switchPortRemoved(swId, port);
+            break;
+        case DOWN:
+        case UP:
+        case OTHER_UPDATE:
+        default:
+            // XXX S what is the right set of port change handlers?
+            log.debug("Topology publisher does not handle these port updates: {}",
+                        changeType);
+        }
+    }
+
+    private void switchPortAdded(long switchId, OFPortDesc port) {
         final Dpid dpid = new Dpid(switchId);
-        PortEvent portEvent = new PortEvent(dpid, new PortNumber(port.getPortNumber()));
+        PortEvent portEvent = new PortEvent(dpid,
+                new PortNumber(port.getPortNo().getShortPortNumber()));
         // FIXME should be merging, with existing attrs, etc..
         // TODO define attr name as constant somewhere.
         // TODO populate appropriate attributes.
         portEvent.createStringAttribute(TopologyElement.TYPE,
-                                        TopologyElement.TYPE_PACKET_LAYER);
+                TopologyElement.TYPE_PACKET_LAYER);
         portEvent.createStringAttribute("name", port.getName());
 
         portEvent.freeze();
 
         if (registryService.hasControl(switchId)) {
             topologyDiscoveryInterface.putPortDiscoveryEvent(portEvent);
-            linkDiscovery.enableDiscoveryOnPort(switchId, port.getPortNumber());
+            linkDiscovery.enableDiscoveryOnPort(switchId,
+                    port.getPortNo().getShortPortNumber());
         } else {
             log.debug("Not the master for switch {}. Suppressed port add event {}.",
                     new Dpid(switchId), portEvent);
         }
     }
 
-    @Override
-    public void switchPortRemoved(Long switchId, OFPhysicalPort port) {
+    private void switchPortRemoved(long switchId, OFPortDesc port) {
         final Dpid dpid = new Dpid(switchId);
 
-        PortEvent portEvent = new PortEvent(dpid, new PortNumber(port.getPortNumber()));
+        PortEvent portEvent = new PortEvent(dpid, new PortNumber(
+                port.getPortNo().getShortPortNumber()));
         // FIXME should be merging, with existing attrs, etc..
         // TODO define attr name as constant somewhere.
         // TODO populate appropriate attributes.
         portEvent.createStringAttribute(TopologyElement.TYPE,
-                                        TopologyElement.TYPE_PACKET_LAYER);
+                TopologyElement.TYPE_PACKET_LAYER);
         portEvent.createStringAttribute("name", port.getName());
 
         portEvent.freeze();
@@ -235,70 +356,8 @@
     }
 
     @Override
-    public void addedSwitch(IOFSwitch sw) {
-        final Dpid dpid = new Dpid(sw.getId());
-        SwitchEvent switchEvent = new SwitchEvent(dpid);
-        // FIXME should be merging, with existing attrs, etc..
-        // TODO define attr name as constant somewhere.
-        // TODO populate appropriate attributes.
-        switchEvent.createStringAttribute(TopologyElement.TYPE,
-                                          TopologyElement.TYPE_PACKET_LAYER);
-        switchEvent.createStringAttribute("ConnectedSince",
-                sw.getConnectedSince().toString());
-        switchEvent.createStringAttribute(TopologyElement.ELEMENT_CONFIG_STATE,
-                ConfigState.NOT_CONFIGURED.toString());
-        switchEvent.createStringAttribute(TopologyElement.ELEMENT_ADMIN_STATUS,
-                AdminStatus.ACTIVE.toString());
-        switchEvent.freeze();
-
-        // TODO Not very robust
-        if (!registryService.hasControl(sw.getId())) {
-            log.debug("Not the master for switch {}. Suppressed switch add event {}.",
-                    dpid, switchEvent);
-            return;
-        }
-
-        List<PortEvent> portEvents = new ArrayList<PortEvent>();
-        for (OFPhysicalPort port : sw.getPorts()) {
-            PortEvent portEvent = new PortEvent(dpid, new PortNumber(port.getPortNumber()));
-            // FIXME should be merging, with existing attrs, etc..
-            // TODO define attr name as constant somewhere.
-            // TODO populate appropriate attributes.
-            portEvent.createStringAttribute("name", port.getName());
-            portEvent.createStringAttribute(TopologyElement.TYPE,
-                                            TopologyElement.TYPE_PACKET_LAYER);
-            portEvent.createStringAttribute(TopologyElement.ELEMENT_CONFIG_STATE,
-                    ConfigState.NOT_CONFIGURED.toString());
-            portEvent.createStringAttribute(TopologyElement.ELEMENT_ADMIN_STATUS,
-                    AdminStatus.ACTIVE.toString());
-
-            portEvent.freeze();
-            portEvents.add(portEvent);
-        }
-        topologyDiscoveryInterface
-                .putSwitchDiscoveryEvent(switchEvent, portEvents);
-
-        for (OFPhysicalPort port : sw.getPorts()) {
-            // Allow links to be discovered on this port now that it's
-            // in the database
-            linkDiscovery.enableDiscoveryOnPort(sw.getId(), port.getPortNumber());
-        }
-    }
-
-    @Override
-    public void removedSwitch(IOFSwitch sw) {
-        // We don't use this event - switch remove is done by cleanup thread
-    }
-
-    @Override
-    public void switchPortChanged(Long switchId) {
-        // We don't use this event
-    }
-
-    @Override
     public String getName() {
-        // TODO Auto-generated method stub
-        return null;
+        return "topologyPublisher";
     }
 
     /* *****************
@@ -312,13 +371,13 @@
 
     @Override
     public Map<Class<? extends IFloodlightService>, IFloodlightService>
-    getServiceImpls() {
+            getServiceImpls() {
         return null;
     }
 
     @Override
     public Collection<Class<? extends IFloodlightService>>
-    getModuleDependencies() {
+            getModuleDependencies() {
         Collection<Class<? extends IFloodlightService>> l =
                 new ArrayList<Class<? extends IFloodlightService>>();
         l.add(IFloodlightProviderService.class);
@@ -339,8 +398,6 @@
         hostService = context.getServiceImpl(IHostService.class);
 
         topologyService = context.getServiceImpl(ITopologyService.class);
-
-        floodlightProvider.addLocalSwitchMastershipListener(this);
     }
 
     @Override
@@ -393,41 +450,23 @@
     public void hostRemoved(Host host) {
         log.debug("Called onosDeviceRemoved");
         HostEvent event = new HostEvent(host.getMacAddress());
-        //XXX shouldn't we be setting attachment points?
+        // XXX shouldn't we be setting attachment points?
         event.freeze();
         topologyDiscoveryInterface.removeHostDiscoveryEvent(event);
     }
 
-    @Override
-    public void controllerRoleChanged(Dpid dpid, Role role) {
-        log.debug("Local switch controller mastership role changed: dpid = {} role = {}", dpid, role);
+    private void controllerRoleChanged(Dpid dpid, Role role) {
+        log.debug("Local switch controller mastership role changed: dpid = {} role = {}",
+                dpid, role);
         MastershipEvent mastershipEvent =
-            new MastershipEvent(dpid, registryService.getOnosInstanceId(),
-                                role);
+                new MastershipEvent(dpid, registryService.getOnosInstanceId(),
+                        role);
         // FIXME should be merging, with existing attrs, etc..
         // TODO define attr name as constant somewhere.
         // TODO populate appropriate attributes.
         mastershipEvent.createStringAttribute(TopologyElement.TYPE,
-                                              TopologyElement.TYPE_ALL_LAYERS);
+                TopologyElement.TYPE_ALL_LAYERS);
         mastershipEvent.freeze();
         topologyDiscoveryInterface.putSwitchMastershipEvent(mastershipEvent);
     }
-
-    @Override
-    public void switchDisconnected(Dpid dpid) {
-        log.debug("Local switch disconnected: dpid = {} role = {}", dpid);
-
-        Role role = Role.SLAVE;         // TODO: Should be Role.UNKNOWN
-
-        MastershipEvent mastershipEvent =
-            new MastershipEvent(dpid, registryService.getOnosInstanceId(),
-                                role);
-        // FIXME should be merging, with existing attrs, etc..
-        // TODO define attr name as constant somewhere.
-        // TODO populate appropriate attributes.
-        mastershipEvent.createStringAttribute(TopologyElement.TYPE,
-                                              TopologyElement.TYPE_ALL_LAYERS);
-        mastershipEvent.freeze();
-        topologyDiscoveryInterface.removeSwitchMastershipEvent(mastershipEvent);
-    }
 }
