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);
-    }
 }
