Giant patch of changes to support OpenFlow 1.3

The following people have contributed to this patch:
- Ali Al-Shabibi <alshabibi.ali@gmail.com>
- Ayaka Koshibe <ayaka@onlab.us>
- Brian O'Connor <bocon@onlab.us>
- Jonathan Hart <jono@onlab.us>
- Matteo Gerola <mgerola@create-net.org>
- Michele Santuari <michele.santuari@create-net.org>
- Pavlin Radoslavov <pavlin@onlab.us>
- Saurav Das <sauravdas@alumni.stanford.edu>
- Toshio Koide <t-koide@onlab.us>
- Yuta HIGUCHI <y-higuchi@onlab.us>

The patch includes the following changes:
- New Floodlight I/O loop / state machine
- New switch/port handling
- New role management (incl. Role.EQUAL)
- Added Floodlight debug framework
- Updates to Controller.java
- Move to Loxigen's OpenflowJ library
- Added OF1.3 support
- Added support for different switches (via DriverManager)
- Updated ONOS modules to use new APIs
- Added and updated unit tests

Change-Id: Ic70a8d50f7136946193d2ba2e4dc0b4bfac5f599
diff --git a/src/test/java/net/onrc/onos/core/flowprogrammer/FlowPusherTest.java b/src/test/java/net/onrc/onos/core/flowprogrammer/FlowPusherTest.java
index 89f188d..ae30949 100644
--- a/src/test/java/net/onrc/onos/core/flowprogrammer/FlowPusherTest.java
+++ b/src/test/java/net/onrc/onos/core/flowprogrammer/FlowPusherTest.java
@@ -1,6 +1,6 @@
 package net.onrc.onos.core.flowprogrammer;
 
-import static org.junit.Assert.assertEquals;
+
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
@@ -16,42 +16,41 @@
 import net.floodlightcontroller.core.FloodlightContext;
 import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.core.internal.OFMessageFuture;
 import net.floodlightcontroller.core.module.FloodlightModuleContext;
 import net.floodlightcontroller.threadpool.IThreadPoolService;
-import net.floodlightcontroller.util.OFMessageDamper;
-import net.onrc.onos.core.util.Dpid;
-import net.onrc.onos.core.util.FlowEntry;
-import net.onrc.onos.core.util.FlowEntryActions;
-import net.onrc.onos.core.util.FlowEntryErrorState;
-import net.onrc.onos.core.util.FlowEntryId;
-import net.onrc.onos.core.util.FlowEntryMatch;
-import net.onrc.onos.core.util.FlowEntryUserState;
-import net.onrc.onos.core.util.FlowId;
+import net.onrc.onos.core.intent.FlowEntry;
+import net.onrc.onos.core.intent.IntentOperation.Operator;
 import net.onrc.onos.core.util.IntegrationTest;
-import net.onrc.onos.core.util.PortNumber;
 
 import org.easymock.EasyMock;
-import org.easymock.IAnswer;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
-import org.openflow.protocol.OFBarrierRequest;
-import org.openflow.protocol.OFFlowMod;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.action.OFAction;
-import org.openflow.protocol.factory.BasicFactory;
+import org.projectfloodlight.openflow.protocol.OFBarrierReply;
+import org.projectfloodlight.openflow.protocol.OFBarrierRequest;
+import org.projectfloodlight.openflow.protocol.OFFactories;
+import org.projectfloodlight.openflow.protocol.OFFactory;
+import org.projectfloodlight.openflow.protocol.OFFlowModify;
+import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFType;
+import org.projectfloodlight.openflow.protocol.OFVersion;
+import org.projectfloodlight.openflow.protocol.action.OFAction;
+import org.projectfloodlight.openflow.protocol.match.Match;
+import org.projectfloodlight.openflow.types.OFBufferId;
+import org.projectfloodlight.openflow.types.OFPort;
+import org.projectfloodlight.openflow.types.U64;
+
 
 @Category(IntegrationTest.class)
 public class FlowPusherTest {
     private FlowPusher pusher;
     private FloodlightContext context;
     private FloodlightModuleContext modContext;
-    private BasicFactory factory;
-    private OFMessageDamper damper;
     private IFloodlightProviderService flProviderService;
     private IThreadPoolService threadPoolService;
 
+    private OFFactory factory10 = OFFactories.getFactory(OFVersion.OF_10);
+
     /**
      * Test single OFMessage is correctly sent to single switch via MessageDamper.
      */
@@ -60,18 +59,20 @@
         beginInitMock();
 
         OFMessage msg = EasyMock.createMock(OFMessage.class);
-        EasyMock.expect(msg.getXid()).andReturn(1).anyTimes();
-        EasyMock.expect(msg.getLength()).andReturn((short) 100).anyTimes();
+        EasyMock.expect(msg.getXid()).andReturn((long) 1).anyTimes();
+        //EasyMock.expect(msg.()).andReturn((short) 100).anyTimes();
         EasyMock.replay(msg);
 
         IOFSwitch sw = createConnectedSwitchMock(1, false);
-        EasyMock.replay(sw);
+
+
 
         try {
-            EasyMock.expect(damper.write(EasyMock.eq(sw), EasyMock.eq(msg), EasyMock.eq(context)))
-                    .andReturn(true).once();
+            sw.write(EasyMock.eq(msg), EasyMock.eq((FloodlightContext) null));
+            EasyMock.expectLastCall().once();
+            EasyMock.replay(sw);
         } catch (IOException e1) {
-            fail("Failed in OFMessageDamper#write()");
+            fail("Failed in IOFSwitch#write()");
         }
 
         endInitMock();
@@ -104,25 +105,24 @@
         beginInitMock();
 
         IOFSwitch sw = createConnectedSwitchMock(1, false);
-        EasyMock.replay(sw);
+
 
         List<OFMessage> messages = new ArrayList<OFMessage>();
 
         for (int i = 0; i < numMsg; ++i) {
             OFMessage msg = EasyMock.createMock(OFMessage.class);
-            EasyMock.expect(msg.getXid()).andReturn(i).anyTimes();
-            EasyMock.expect(msg.getLength()).andReturn((short) 100).anyTimes();
+            EasyMock.expect(msg.getXid()).andReturn((long) i).anyTimes();
             EasyMock.replay(msg);
             messages.add(msg);
 
             try {
-                EasyMock.expect(damper.write(EasyMock.eq(sw), EasyMock.eq(msg), EasyMock.eq(context)))
-                        .andReturn(true).once();
+                sw.write(EasyMock.eq(msg), EasyMock.eq((FloodlightContext) null));
+                EasyMock.expectLastCall().once();
             } catch (IOException e1) {
-                fail("Failed in OFMessageDamper#write()");
+                fail("Failed in IOFSwitch#write()");
             }
         }
-
+        EasyMock.replay(sw);
         endInitMock();
         initPusher(1);
 
@@ -160,25 +160,24 @@
         Map<IOFSwitch, List<OFMessage>> swMap = new HashMap<IOFSwitch, List<OFMessage>>();
         for (int i = 0; i < numSwitch; ++i) {
             IOFSwitch sw = createConnectedSwitchMock(i, false);
-            EasyMock.replay(sw);
 
             List<OFMessage> messages = new ArrayList<OFMessage>();
 
             for (int j = 0; j < numMsg; ++j) {
                 OFMessage msg = EasyMock.createMock(OFMessage.class);
-                EasyMock.expect(msg.getXid()).andReturn(j).anyTimes();
-                EasyMock.expect(msg.getLength()).andReturn((short) 100).anyTimes();
+                EasyMock.expect(msg.getXid()).andReturn((long) j).anyTimes();
                 EasyMock.replay(msg);
                 messages.add(msg);
 
                 try {
-                    EasyMock.expect(damper.write(EasyMock.eq(sw), EasyMock.eq(msg), EasyMock.eq(context)))
-                            .andReturn(true).once();
+                    sw.write(EasyMock.eq(msg), EasyMock.eq((FloodlightContext) null));
+                    EasyMock.expectLastCall().once();
                 } catch (IOException e1) {
-                    fail("Failed in OFMessageDamper#write()");
+                    fail("Failed in IOFWrite#write()");
                 }
             }
             swMap.put(sw, messages);
+            EasyMock.replay(sw);
         }
 
         endInitMock();
@@ -223,30 +222,30 @@
         Map<IOFSwitch, List<OFMessage>> swMap = new HashMap<IOFSwitch, List<OFMessage>>();
         for (int i = 0; i < numThreads; ++i) {
             IOFSwitch sw = createConnectedSwitchMock(i, false);
-            EasyMock.replay(sw);
+            //EasyMock.replay(sw);
 
             List<OFMessage> messages = new ArrayList<OFMessage>();
 
             for (int j = 0; j < numMsg; ++j) {
                 OFMessage msg = EasyMock.createMock(OFMessage.class);
-                EasyMock.expect(msg.getXid()).andReturn(j).anyTimes();
-                EasyMock.expect(msg.getLength()).andReturn((short) 100).anyTimes();
+                EasyMock.expect(msg.getXid()).andReturn((long) j).anyTimes();
+
                 EasyMock.replay(msg);
                 messages.add(msg);
 
                 try {
-                    EasyMock.expect(damper.write(EasyMock.eq(sw), EasyMock.eq(msg), EasyMock.eq(context)))
-                            .andReturn(true).once();
+                    sw.write(EasyMock.eq(msg), EasyMock.eq((FloodlightContext) null));
+                    EasyMock.expectLastCall().once();
                 } catch (IOException e1) {
-                    fail("Failed in OFMessageDamper#write()");
+                    fail("Failed in IOFWrite#write()");
                 }
             }
             swMap.put(sw, messages);
+            EasyMock.replay(sw);
         }
 
         endInitMock();
         initPusher(numThreads);
-
         for (IOFSwitch sw : swMap.keySet()) {
             for (OFMessage msg : swMap.get(sw)) {
                 boolean addResult = pusher.add(sw, msg);
@@ -292,42 +291,35 @@
         beginInitMock();
 
         IOFSwitch sw = createConnectedSwitchMock(1, true);
-        EasyMock.replay(sw);
+        EasyMock.expect(sw.getOFVersion()).andReturn(OFVersion.OF_10).once();
+
 
         List<OFMessage> messages = new ArrayList<OFMessage>();
 
         for (int i = 0; i < numMsg; ++i) {
             OFMessage msg = EasyMock.createMock(OFMessage.class);
-            EasyMock.expect(msg.getXid()).andReturn(1).anyTimes();
-            EasyMock.expect(msg.getLength()).andReturn((short) 100).anyTimes();
-            EasyMock.expect(msg.getLengthU()).andReturn(100).anyTimes();
+            EasyMock.expect(msg.getXid()).andReturn((long) 1).anyTimes();
             EasyMock.replay(msg);
             messages.add(msg);
 
             try {
-                EasyMock.expect(damper.write(EasyMock.eq(sw), EasyMock.eq(msg), EasyMock.eq(context)))
-                        .andReturn(true).once();
-            } catch (IOException e) {
-                fail("Failed in OFMessageDamper#write()");
+                sw.write(EasyMock.eq(msg), EasyMock.eq((FloodlightContext) null));
+                EasyMock.expectLastCall().once();
+            } catch (IOException e1) {
+                fail("Failed in IOFWrite#write()");
             }
         }
 
         try {
-            EasyMock.expect(damper.write(EasyMock.eq(sw), (OFMessage) EasyMock.anyObject(), EasyMock.eq(context)))
-                    .andAnswer(new IAnswer<Boolean>() {
-                        @Override
-                        public Boolean answer() throws Throwable {
-                            OFMessage msg = (OFMessage) EasyMock.getCurrentArguments()[1];
-                            if (msg.getType() == OFType.BARRIER_REQUEST) {
-                                barrierTime = System.currentTimeMillis();
-                            }
-                            return true;
-                        }
-                    }).once();
+            sw.write(EasyMock.anyObject(OFBarrierRequest.class), EasyMock.eq((FloodlightContext) null));
+            EasyMock.expectLastCall().once();
+            barrierTime = System.currentTimeMillis();
         } catch (IOException e1) {
-            fail("Failed in OFMessageDamper#write()");
+            fail("Failed in IOFWrite#write()");
         }
 
+        EasyMock.replay(sw);
+
         endInitMock();
         initPusher(1);
 
@@ -370,19 +362,19 @@
         beginInitMock();
 
         IOFSwitch sw = createConnectedSwitchMock(1, true);
-        EasyMock.replay(sw);
+        EasyMock.expect(sw.getOFVersion()).andReturn(OFVersion.OF_10).once();
 
         try {
-            EasyMock.expect(damper.write(EasyMock.eq(sw), (OFMessage) EasyMock.anyObject(), EasyMock.eq(context)))
-                    .andReturn(true).once();
+            sw.write((OFMessage) EasyMock.anyObject(), EasyMock.eq((FloodlightContext) null));
+            EasyMock.expectLastCall().once();
         } catch (IOException e1) {
-            fail("Failed in OFMessageDamper#write()");
+            fail("Failed in IOFWrite#write()");
         }
-
+        EasyMock.replay(sw);
         endInitMock();
         initPusher(1);
 
-        OFBarrierReplyFuture future = pusher.barrierAsync(sw);
+        OFMessageFuture<OFBarrierReply> future = pusher.barrierAsync(sw);
 
         assertNotNull(future);
 
@@ -397,7 +389,7 @@
         pusher.stop();
     }
 
-    static final int XID_TO_VERIFY = 100;
+    static final long XID_TO_VERIFY = 100;
     static final long DPID_TO_VERIFY = 10;
 
     /**
@@ -407,7 +399,8 @@
     @Test
     public void testAddFlow() {
         // instantiate required objects
-        FlowEntry flowEntry1 = new FlowEntry();
+        FlowEntry flowEntry1 = new FlowEntry(DPID_TO_VERIFY, 1, 11, null, null, 0, 0, Operator.ADD);
+        /*
         flowEntry1.setDpid(new Dpid(DPID_TO_VERIFY));
         flowEntry1.setFlowId(new FlowId(1));
         flowEntry1.setInPort(new PortNumber((short) 1));
@@ -417,46 +410,42 @@
         flowEntry1.setFlowEntryActions(new FlowEntryActions());
         flowEntry1.setFlowEntryErrorState(new FlowEntryErrorState());
         flowEntry1.setFlowEntryUserState(FlowEntryUserState.FE_USER_ADD);
+        */
 
         beginInitMock();
 
-        OFFlowMod msg = EasyMock.createMock(OFFlowMod.class);
-        EasyMock.expect(msg.setIdleTimeout(EasyMock.anyShort())).andReturn(msg);
-        EasyMock.expect(msg.setHardTimeout(EasyMock.anyShort())).andReturn(msg);
-        EasyMock.expect(msg.setPriority(EasyMock.anyShort())).andReturn(msg);
-        EasyMock.expect(msg.setBufferId(EasyMock.anyInt())).andReturn(msg);
-        EasyMock.expect(msg.setCookie(EasyMock.anyLong())).andReturn(msg);
-        EasyMock.expect(msg.setCommand(EasyMock.anyShort())).andReturn(msg);
-        EasyMock.expect(msg.setMatch(EasyMock.anyObject(OFMatch.class))).andReturn(msg);
-        EasyMock.expect(msg.setActions((List<OFAction>) EasyMock.anyObject())).andReturn(msg);
-        EasyMock.expect(msg.setLengthU(EasyMock.anyShort())).andReturn(msg);
-        EasyMock.expect(msg.setOutPort(EasyMock.anyShort())).andReturn(msg).atLeastOnce();
-        EasyMock.expect(msg.getXid()).andReturn(XID_TO_VERIFY).anyTimes();
-        EasyMock.expect(msg.getType()).andReturn(OFType.FLOW_MOD).anyTimes();
-        EasyMock.expect(msg.getLength()).andReturn((short) 100).anyTimes();
-        EasyMock.replay(msg);
+        OFFlowModify fm = EasyMock.createMock(OFFlowModify.class);
 
-        EasyMock.expect(factory.getMessage(EasyMock.eq(OFType.FLOW_MOD))).andReturn(msg);
+        OFFlowModify.Builder bld = EasyMock.createMock(OFFlowModify.Builder.class);
+
+        EasyMock.expect(bld.setIdleTimeout(EasyMock.anyInt())).andReturn(bld);
+        EasyMock.expect(bld.setHardTimeout(EasyMock.anyInt())).andReturn(bld);
+        EasyMock.expect(bld.setPriority(EasyMock.anyShort())).andReturn(bld);
+        EasyMock.expect(bld.setBufferId(OFBufferId.NO_BUFFER)).andReturn(bld);
+        EasyMock.expect(bld.setCookie(U64.of(EasyMock.anyLong()))).andReturn(bld);
+        EasyMock.expect(bld.setMatch(EasyMock.anyObject(Match.class))).andReturn(bld);
+        EasyMock.expect(bld.setActions((List<OFAction>) EasyMock.anyObject())).andReturn(bld);
+        EasyMock.expect(bld.setOutPort(OFPort.of(EasyMock.anyInt()))).andReturn(bld).atLeastOnce();
+        EasyMock.expect(bld.build()).andReturn(fm);
+
+        EasyMock.expect(fm.getXid()).andReturn(XID_TO_VERIFY).anyTimes();
+        EasyMock.expect(fm.getType()).andReturn(OFType.FLOW_MOD).anyTimes();
+
+
+
 
         IOFSwitch sw = createConnectedSwitchMock(DPID_TO_VERIFY, false);
         EasyMock.expect(sw.getStringId()).andReturn("1").anyTimes();
+        EasyMock.expect(sw.getOFVersion()).andReturn(OFVersion.OF_10).once();
 
         try {
-            EasyMock.expect(damper.write(EasyMock.eq(sw), EasyMock.anyObject(OFMessage.class), EasyMock.eq(context)))
-                    .andAnswer(new IAnswer<Boolean>() {
-                        @Override
-                        public Boolean answer() throws Throwable {
-                            OFMessage msg = (OFMessage) EasyMock.getCurrentArguments()[1];
-                            if (msg.getType() == OFType.FLOW_MOD) {
-                                assertEquals(msg.getXid(), XID_TO_VERIFY);
-                            }
-                            return true;
-                        }
-                    }).atLeastOnce();
+            sw.write(EasyMock.anyObject(OFMessage.class), EasyMock.eq((FloodlightContext) null));
+            EasyMock.expectLastCall().once();
         } catch (IOException e1) {
-            fail("Failed in OFMessageDamper#write()");
+            fail("Failed in IOFWrite#write()");
         }
 
+        EasyMock.replay(bld, fm);
         EasyMock.replay(sw);
 
         endInitMock();
@@ -479,17 +468,20 @@
     private void beginInitMock() {
         context = EasyMock.createMock(FloodlightContext.class);
         modContext = EasyMock.createMock(FloodlightModuleContext.class);
-        factory = EasyMock.createMock(BasicFactory.class);
-        damper = EasyMock.createMock(OFMessageDamper.class);
+        // AAS: I don't think we should mock factories... the rabbit whole is too deep.
+        //factory10 = EasyMock.createMock(OFFactories.getFactory(OFVersion.OF_10).getClass());
         flProviderService = EasyMock.createMock(IFloodlightProviderService.class);
         threadPoolService = EasyMock.createMock(IThreadPoolService.class);
+        EasyMock.expect(flProviderService.getOFMessageFactory_10()).andReturn(factory10).anyTimes();
+        EasyMock.expect(flProviderService.getOFMessageFactory_13()).andReturn(null).anyTimes();
 
         EasyMock.expect(modContext.getServiceImpl(EasyMock.eq(IThreadPoolService.class)))
                 .andReturn(threadPoolService).once();
         EasyMock.expect(modContext.getServiceImpl(EasyMock.eq(IFloodlightProviderService.class)))
                 .andReturn(flProviderService).once();
+        // AAS: FlowPusher doesn't call the following anymore.
         flProviderService.addOFMessageListener(EasyMock.eq(OFType.BARRIER_REPLY),
-                (FlowPusher) EasyMock.anyObject());
+                EasyMock.anyObject(FlowPusher.class));
         EasyMock.expectLastCall().once();
 
         ScheduledExecutorService executor = EasyMock.createMock(ScheduledExecutorService.class);
@@ -502,8 +494,7 @@
     private void endInitMock() {
         EasyMock.replay(threadPoolService);
         EasyMock.replay(flProviderService);
-        EasyMock.replay(damper);
-        EasyMock.replay(factory);
+        //EasyMock.replay(factory10);
         EasyMock.replay(modContext);
         EasyMock.replay(context);
     }
@@ -511,15 +502,14 @@
     private void verifyAll() {
         EasyMock.verify(threadPoolService);
         EasyMock.verify(flProviderService);
-        EasyMock.verify(damper);
-        EasyMock.verify(factory);
+        //EasyMock.verify(factory10);
         EasyMock.verify(modContext);
         EasyMock.verify(context);
     }
 
     private void initPusher(int numThread) {
         pusher = new FlowPusher(numThread);
-        pusher.init(context, modContext, factory, damper);
+        pusher.init(modContext);
         pusher.start();
     }
 
@@ -528,7 +518,7 @@
         EasyMock.expect(sw.isConnected()).andReturn(true).anyTimes();
         EasyMock.expect(sw.getId()).andReturn(dpid).anyTimes();
         sw.flush();
-        EasyMock.expectLastCall().atLeastOnce();
+        EasyMock.expectLastCall().anyTimes();
         if (useBarrier) {
             prepareBarrier(sw);
         }
@@ -537,14 +527,14 @@
     }
 
     private void prepareBarrier(IOFSwitch sw) {
+        OFBarrierRequest.Builder bld = EasyMock.createMock(factory10.buildBarrierRequest().getClass());
+        EasyMock.expect(bld.setXid(EasyMock.anyInt())).andReturn(bld);
+        EasyMock.expect(bld.getXid()).andReturn((long) 1).anyTimes();
+        EasyMock.expect(bld.getType()).andReturn(OFType.BARRIER_REQUEST).anyTimes();
+
         OFBarrierRequest req = EasyMock.createMock(OFBarrierRequest.class);
-        req.setXid(EasyMock.anyInt());
-        EasyMock.expectLastCall().once();
-        EasyMock.expect(req.getXid()).andReturn(1).anyTimes();
-        EasyMock.expect(req.getType()).andReturn(OFType.BARRIER_REQUEST).anyTimes();
-        EasyMock.expect(req.getLength()).andReturn((short) 100).anyTimes();
-        EasyMock.replay(req);
-        EasyMock.expect(factory.getMessage(EasyMock.eq(OFType.BARRIER_REQUEST))).andReturn(req).anyTimes();
+        EasyMock.expect(bld.build()).andReturn(req).anyTimes();
+        EasyMock.replay(bld);
         EasyMock.expect(sw.getNextTransactionId()).andReturn(1);
     }
 
diff --git a/src/test/java/net/onrc/onos/core/flowprogrammer/FlowSynchronizerTest.java b/src/test/java/net/onrc/onos/core/flowprogrammer/FlowSynchronizerTest.java
index 4be8f97..112620e 100644
--- a/src/test/java/net/onrc/onos/core/flowprogrammer/FlowSynchronizerTest.java
+++ b/src/test/java/net/onrc/onos/core/flowprogrammer/FlowSynchronizerTest.java
@@ -6,6 +6,7 @@
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
@@ -13,7 +14,7 @@
 import net.floodlightcontroller.core.IOFSwitch;
 import net.onrc.onos.core.flowprogrammer.IFlowPusherService.MsgPriority;
 import net.onrc.onos.core.flowprogrammer.IFlowSyncService.SyncResult;
-import net.onrc.onos.core.util.FlowEntry;
+import net.onrc.onos.core.intent.FlowEntry;
 
 import org.easymock.EasyMock;
 import org.easymock.IAnswer;
@@ -22,15 +23,20 @@
 import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.openflow.protocol.OFFlowMod;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFStatisticsRequest;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.statistics.OFFlowStatisticsReply;
-import org.openflow.protocol.statistics.OFStatistics;
 import org.powermock.core.classloader.annotations.PrepareForTest;
 import org.powermock.modules.junit4.PowerMockRunner;
+import org.projectfloodlight.openflow.protocol.OFFactories;
+import org.projectfloodlight.openflow.protocol.OFFactory;
+import org.projectfloodlight.openflow.protocol.OFFlowMod;
+import org.projectfloodlight.openflow.protocol.OFFlowModCommand;
+import org.projectfloodlight.openflow.protocol.OFFlowStatsEntry;
+import org.projectfloodlight.openflow.protocol.OFFlowStatsReply;
+import org.projectfloodlight.openflow.protocol.OFFlowStatsRequest;
+import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFStatsReply;
+import org.projectfloodlight.openflow.protocol.OFType;
+import org.projectfloodlight.openflow.protocol.OFVersion;
+import org.projectfloodlight.openflow.types.U64;
 
 // Test should be fixed to fit RAMCloud basis
 @Ignore
@@ -42,8 +48,15 @@
     private List<Long> idAdded;
     private List<Long> idRemoved;
 
+    /*
+     * OF1.0 Factory for now. Change when we move to
+     * OF 1.3.
+     */
+    private static OFFactory factory10;
+
     @Before
     public void setUp() throws Exception {
+        factory10 = OFFactories.getFactory(OFVersion.OF_10);
         idAdded = new ArrayList<Long>();
         idRemoved = new ArrayList<Long>();
 
@@ -58,8 +71,8 @@
                 OFMessage msg = (OFMessage) EasyMock.getCurrentArguments()[1];
                 if (msg.getType().equals(OFType.FLOW_MOD)) {
                     OFFlowMod fm = (OFFlowMod) msg;
-                    if (fm.getCommand() == OFFlowMod.OFPFC_DELETE_STRICT) {
-                        idRemoved.add(fm.getCookie());
+                    if (fm.getCommand() == OFFlowModCommand.DELETE_STRICT) {
+                        idRemoved.add(fm.getCookie().getValue());
                     }
                 }
                 return null;
@@ -71,7 +84,7 @@
             @Override
             public Object answer() throws Throwable {
                 FlowEntry flow = (FlowEntry) EasyMock.getCurrentArguments()[1];
-                idAdded.add(flow.flowEntryId().value());
+                idAdded.add(flow.getFlowEntryId());
                 return null;
             }
         }).anyTimes();
@@ -206,13 +219,13 @@
         IOFSwitch sw = EasyMock.createMock(IOFSwitch.class);
         EasyMock.expect(sw.getId()).andReturn((long) 1).anyTimes();
 
-        List<OFStatistics> stats = new ArrayList<OFStatistics>();
+        List<OFStatsReply> stats = new ArrayList<OFStatsReply>();
         for (long cookie : cookieList) {
             stats.add(createReply(cookie));
         }
 
         @SuppressWarnings("unchecked")
-        Future<List<OFStatistics>> future = EasyMock.createMock(Future.class);
+        Future<List<OFStatsReply>> future = EasyMock.createMock(Future.class);
         try {
             EasyMock.expect(future.get()).andReturn(stats).once();
         } catch (InterruptedException e1) {
@@ -223,7 +236,7 @@
         EasyMock.replay(future);
 
         try {
-            EasyMock.expect(sw.getStatistics(EasyMock.anyObject(OFStatisticsRequest.class)))
+            EasyMock.expect(sw.getStatistics(EasyMock.anyObject(OFFlowStatsRequest.class)))
                     .andReturn(future).once();
         } catch (IOException e) {
             fail("Failed in IOFSwitch#getStatistics()");
@@ -239,13 +252,14 @@
      * @param cookie Cookie value, which indicates ID of FlowEntry installed to switch.
      * @return Created object.
      */
-    private OFFlowStatisticsReply createReply(long cookie) {
-        OFFlowStatisticsReply stat = new OFFlowStatisticsReply();
-        OFMatch match = new OFMatch();
-
-        stat.setCookie(cookie);
-        stat.setMatch(match);
-        stat.setPriority((short) 1);
+    private OFFlowStatsReply createReply(long cookie) {
+        OFFlowStatsEntry entry = factory10.buildFlowStatsEntry()
+                .setCookie(U64.of(cookie))
+                .setPriority(1)
+                .setMatch(factory10.buildMatch().build())
+                .build();
+        OFFlowStatsReply stat = factory10.buildFlowStatsReply()
+                .setEntries(Collections.singletonList(entry)).build();
 
         return stat;
     }
diff --git a/src/test/java/net/onrc/onos/core/hostmanager/HostManagerTest.java b/src/test/java/net/onrc/onos/core/hostmanager/HostManagerTest.java
index 5f22091..7e552ed 100644
--- a/src/test/java/net/onrc/onos/core/hostmanager/HostManagerTest.java
+++ b/src/test/java/net/onrc/onos/core/hostmanager/HostManagerTest.java
@@ -39,8 +39,13 @@
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFType;
+import org.projectfloodlight.openflow.protocol.OFFactories;
+import org.projectfloodlight.openflow.protocol.OFFactory;
+import org.projectfloodlight.openflow.protocol.OFPacketIn;
+import org.projectfloodlight.openflow.protocol.OFPacketInReason;
+import org.projectfloodlight.openflow.protocol.OFType;
+import org.projectfloodlight.openflow.protocol.OFVersion;
+import org.projectfloodlight.openflow.types.OFPort;
 
 /**
  * Unit tests for the Host Manager module (HostManger).
@@ -61,6 +66,7 @@
     private IEventChannel<Long, Host> eventChannel;
     private IFloodlightProviderService floodlightProvider;
     private Date lastSeenTimestamp;
+    private OFFactory ofact;
 
     @Override
     @Before
@@ -102,6 +108,8 @@
         modContext.addService(IFloodlightProviderService.class, floodlightProvider);
         modContext.getServiceImpl(IFloodlightProviderService.class);
         sw1Dpid = 1L;
+        ofact = OFFactories.getFactory(OFVersion.OF_10);
+
         sw1 = createMockSwitch(sw1Dpid);
         replay(sw1);
 
@@ -121,10 +129,8 @@
                 .setTtl((byte) 128)
                 .setSourceAddress("192.168.10.1")
                 .setDestinationAddress("192.168.255.255")
-                .setPayload(new UDP()
-                .setSourcePort((short) 5000)
-                .setDestinationPort((short) 5001)
-                .setPayload(new Data(new byte[]{0x01}))));
+                .setPayload(getUDP(new Data(new byte[]{0x01}))));
+
         /*
          * Normal IPv4 packet
          */
@@ -137,10 +143,8 @@
                 .setTtl((byte) 128)
                 .setSourceAddress("192.168.1.1")
                 .setDestinationAddress("192.168.1.2")
-                .setPayload(new UDP()
-                .setSourcePort((short) 5000)
-                .setDestinationPort((short) 5001)
-                .setPayload(new Data(new byte[]{0x01}))));
+                .setPayload(getUDP(new Data(new byte[]{0x01}))));
+
         /*
          * Same MAC header as pkt1,but not IP address set
          */
@@ -151,10 +155,8 @@
         .setPayload(
                 new IPv4()
                 .setTtl((byte) 128)
-                .setPayload(new UDP()
-                .setSourcePort((short) 5000)
-                .setDestinationPort((short) 5001)
-                .setPayload(new Data(new byte[]{0x01}))));
+                .setPayload(getUDP(new Data(new byte[]{0x01}))));
+
         /*
          * DHCP packet
          */
@@ -167,11 +169,7 @@
                 .setTtl((byte) 128)
                 .setSourceAddress("192.168.1.1")
                 .setDestinationAddress("192.168.1.2")
-                .setPayload(new UDP()
-                .setSourcePort((short) 5000)
-                .setDestinationPort((short) 5001)
-                .setChecksum((short) 0)
-                .setPayload(
+                .setPayload(getUDP(
                         new DHCP()
                         .setOpCode(DHCP.OPCODE_REPLY)
                         .setHardwareType(DHCP.HWTYPE_ETHERNET)
@@ -204,9 +202,8 @@
                 .setTargetProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.2")));
 
 
-        this.pktIn = new OFPacketIn().setInPort((short) sw1DevPort);
-
-        this.pktIn2 = new OFPacketIn().setInPort((short) sw1DevPort2);
+        this.pktIn = getPacketIn((short) sw1DevPort);
+        this.pktIn2 = getPacketIn((short) sw1DevPort2);
 
         lastSeenTimestamp = new Date(1);
     }
@@ -230,7 +227,8 @@
         Ethernet eth = (Ethernet) pkt1;
         Host srcHost = hostManager.getSourceHostFromPacket(eth, sw1Dpid, sw1DevPort);
 
-        floodlightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN), EasyMock.isA(HostManager.class));
+        floodlightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN),
+                EasyMock.isA(HostManager.class));
         srcHost.setLastSeenTimestamp(lastSeenTimestamp);
         assertEquals(lastSeenTimestamp, srcHost.getLastSeenTimestamp());
     }
@@ -278,7 +276,8 @@
 
         hostManager.init(modContext);
         hostManager.startUp(modContext);
-        Command cmd = hostManager.processPacketIn(sw1, pktIn, (Ethernet) pkt1);
+        Command cmd = hostManager.processPacketIn(
+                sw1, pktIn, (Ethernet) pkt1, (short) sw1DevPort);
         assertEquals(Command.CONTINUE, cmd);
 
         EasyMock.verify(floodlightProvider);
@@ -297,7 +296,8 @@
 
         hostManager.init(modContext);
         hostManager.startUp(modContext);
-        Command cmd = hostManager.processPacketIn(sw1, pktIn2, (Ethernet) pkt1);
+        Command cmd = hostManager.processPacketIn(
+                sw1, pktIn2, (Ethernet) pkt1, (short) sw1DevPort2);
         assertEquals(Command.CONTINUE, cmd);
 
         EasyMock.verify(floodlightProvider);
@@ -308,7 +308,8 @@
      */
     @Test
     public void testProcessPacketInStop() {
-        Command cmd = hostManager.processPacketIn(sw1, pktIn, (Ethernet) pkt0);
+        Command cmd = hostManager.processPacketIn(
+                sw1, pktIn, (Ethernet) pkt0, (short) sw1DevPort);
         assertEquals(Command.STOP, cmd);
     }
 
@@ -322,7 +323,8 @@
         Long longmac = eth.getSourceMAC().toLong();
         Host srcHost = hostManager.getSourceHostFromPacket(eth, sw1Dpid, sw1DevPort);
 
-        floodlightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN), EasyMock.isA(HostManager.class));
+        floodlightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN),
+                EasyMock.isA(HostManager.class));
         EasyMock.expectLastCall();
         floodlightProvider.publishUpdate(EasyMock.isA(IUpdate.class));
         EasyMock.expectLastCall();
@@ -344,7 +346,8 @@
         Ethernet eth = (Ethernet) pkt1;
         Host srcHost = hostManager.getSourceHostFromPacket(eth, sw1Dpid, sw1DevPort);
 
-        floodlightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN), EasyMock.isA(HostManager.class));
+        floodlightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN),
+                EasyMock.isA(HostManager.class));
         EasyMock.expectLastCall();
         floodlightProvider.publishUpdate(EasyMock.isA(IUpdate.class));
         EasyMock.expectLastCall();
@@ -366,7 +369,8 @@
         Ethernet eth = (Ethernet) pkt1;
         MACAddress mac = eth.getSourceMAC();
 
-        floodlightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN), EasyMock.isA(HostManager.class));
+        floodlightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN),
+                EasyMock.isA(HostManager.class));
         EasyMock.expectLastCall();
         floodlightProvider.publishUpdate(EasyMock.isA(IUpdate.class));
         EasyMock.expectLastCall();
@@ -378,4 +382,23 @@
 
         EasyMock.verify(floodlightProvider);
     }
+
+    /**
+     * Helper for building PacketIns. Defaults to a flowtable miss.
+     * @param inport the inport field value
+     * @return a PacketIn
+     */
+    private OFPacketIn getPacketIn(int inport) {
+        return ofact.buildPacketIn()
+                .setInPort(OFPort.of(inport))
+                .setReason(OFPacketInReason.NO_MATCH)
+                .build();
+    }
+
+    private UDP getUDP(IPacket payload) {
+        return (UDP) new UDP()
+        .setSourcePort((short) 5000)
+        .setDestinationPort((short) 5001)
+        .setPayload(payload);
+    }
 }
diff --git a/src/test/java/net/onrc/onos/core/linkdiscovery/LinkDiscoveryManagerTest.java b/src/test/java/net/onrc/onos/core/linkdiscovery/LinkDiscoveryManagerTest.java
index 37adf6b..7f848a8 100644
--- a/src/test/java/net/onrc/onos/core/linkdiscovery/LinkDiscoveryManagerTest.java
+++ b/src/test/java/net/onrc/onos/core/linkdiscovery/LinkDiscoveryManagerTest.java
@@ -26,6 +26,7 @@
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Set;
 
 import net.floodlightcontroller.core.FloodlightContext;
 import net.floodlightcontroller.core.IFloodlightProviderService;
@@ -42,15 +43,22 @@
 import net.onrc.onos.core.registry.IControllerRegistryService;
 
 import org.easymock.EasyMock;
+import org.easymock.IArgumentMatcher;
 import org.junit.Before;
 import org.junit.Test;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFPhysicalPort;
-import org.openflow.protocol.OFPortStatus;
-import org.openflow.protocol.OFPortStatus.OFPortReason;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.projectfloodlight.openflow.protocol.OFFactories;
+import org.projectfloodlight.openflow.protocol.OFFactory;
+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.OFVersion;
+import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
+import org.projectfloodlight.openflow.types.MacAddress;
+import org.projectfloodlight.openflow.types.OFPort;
 
 // CHECKSTYLE IGNORE WriteTag FOR NEXT 2 LINES
 /**
@@ -58,43 +66,109 @@
  */
 public class LinkDiscoveryManagerTest extends FloodlightTestCase {
 
-    private TestLinkDiscoveryManager ldm;
-    protected static final Logger log = LoggerFactory.getLogger(LinkDiscoveryManagerTest.class);
+    private LinkDiscoveryManager ldm;
 
-    public class TestLinkDiscoveryManager extends LinkDiscoveryManager {
-        public boolean isSendLLDPsCalled = false;
-        public boolean isClearLinksCalled = false;
+    private static final Set<OFPortState> EMPTY_PORT_STATE =
+            Collections.<OFPortState>emptySet();
 
-        @Override
-        protected void discoverOnAllPorts() {
-            isSendLLDPsCalled = true;
-            super.discoverOnAllPorts();
+    // Arbitrary MAC address that we can feed in to our mock objects. This
+    // value is never actually checked during the tests so it doesn't matter if
+    // all ports have the same MAC address.
+    private static final byte[] DEFAULT_MAC_ADDRESS =
+            new byte[] {0x0, 0x0, 0x0, 0x0, 0x0, 0x1};
+
+    private OFFactory factory10 = OFFactories.getFactory(OFVersion.OF_10);
+
+    /**
+     * EasyMock matcher to verify the value of the output port of a packet out.
+     * This is used to verify that the packet out messages generated by
+     * LinkDiscoveryManager contain the correct output port.
+     *
+     */
+    private static final class PacketOutPortMatcher implements IArgumentMatcher {
+        private final int portNumber;
+
+        public PacketOutPortMatcher(int portNumber) {
+            this.portNumber = portNumber;
         }
 
-        public void reset() {
-            isSendLLDPsCalled = false;
-            isClearLinksCalled = false;
+        @Override
+        public void appendTo(StringBuffer strBuffer) {
+            strBuffer.append("PacketOutPortMatcher failed to verify output port");
+        }
+
+        @Override
+        public boolean matches(Object object) {
+            if (!(object instanceof OFPacketOut)) {
+                return false;
+            }
+
+            OFPacketOut po = (OFPacketOut) object;
+
+            if (po.getActions().size() != 1
+                    || !(po.getActions().get(0) instanceof OFActionOutput)) {
+                return false;
+            }
+
+            OFActionOutput action = (OFActionOutput) po.getActions().get(0);
+
+            return action.getPort().getPortNumber() == portNumber;
         }
     }
 
-    public LinkDiscoveryManager getTopology() {
+    /**
+     * Matcher method to match a given output port against a packet out message
+     * passed as an argument to a mock switch.
+     *
+     * @param outPort the output port to check in the packet out
+     * @return anything of type OFPacketOut
+     */
+    private static OFPacketOut matchOutPort(int outPort) {
+        EasyMock.reportMatcher(new PacketOutPortMatcher(outPort));
+        return null;
+    }
+
+    private LinkDiscoveryManager getLinkDiscoveryManager() {
         return ldm;
     }
 
-    public IOFSwitch createMockSwitch(Long id) {
+    private IOFSwitch createMockSwitch(Long id) {
         IOFSwitch mockSwitch = createNiceMock(IOFSwitch.class);
         expect(mockSwitch.getId()).andReturn(id).anyTimes();
         expect(mockSwitch.portEnabled(EasyMock.anyShort())).andReturn(true).anyTimes();
         return mockSwitch;
     }
 
+    private OFPortDesc createMockPort(short portNumber) {
+        return createMockPortWithState(portNumber,
+               Collections.<OFPortState>emptySet());
+    }
+
+    private OFPortDesc createMockPortWithState(short portNumber,
+            Set<OFPortState> state) {
+        OFPort ofPort = EasyMock.createMock(OFPort.class);
+        expect(ofPort.getShortPortNumber()).andReturn(portNumber).anyTimes();
+
+        OFPortDesc ofPortDesc = EasyMock.createMock(OFPortDesc.class);
+        expect(ofPortDesc.getPortNo()).andReturn(ofPort).anyTimes();
+        expect(ofPortDesc.getHwAddr()).andReturn(
+                MacAddress.of(DEFAULT_MAC_ADDRESS)).anyTimes();
+        expect(ofPortDesc.getConfig()).
+                andReturn(Collections.<OFPortConfig>emptySet()).anyTimes();
+        expect(ofPortDesc.getState()).andReturn(state).anyTimes();
+
+        replay(ofPort);
+        replay(ofPortDesc);
+
+        return ofPortDesc;
+    }
+
     @Override
     @Before
     public void setUp() throws Exception {
         super.setUp();
         FloodlightModuleContext cntx = new FloodlightModuleContext();
-        ldm = new TestLinkDiscoveryManager();
-        //ldm.linkDiscoveryAware = new ArrayList<ILinkDiscoveryListener>();
+        ldm = new LinkDiscoveryManager();
         MockThreadPoolService tp = new MockThreadPoolService();
         RestApiServer restApi = new RestApiServer();
         IControllerRegistryService registry =
@@ -124,44 +198,46 @@
 
     @Test
     public void testAddOrUpdateLink() throws Exception {
-        LinkDiscoveryManager topology = getTopology();
+        LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
 
         Link lt = new Link(1L, 2, 2L, 1);
         long firstSeenTime = System.currentTimeMillis();
         LinkInfo info = new LinkInfo(firstSeenTime,
-                System.currentTimeMillis(), 0, 0);
-        topology.addOrUpdateLink(lt, info);
-
+                System.currentTimeMillis(), EMPTY_PORT_STATE,
+                EMPTY_PORT_STATE);
+        linkDiscovery.addOrUpdateLink(lt, info);
 
         NodePortTuple srcNpt = new NodePortTuple(1L, 2);
         NodePortTuple dstNpt = new NodePortTuple(2L, 1);
 
         // check invariants hold
-        assertNotNull(topology.switchLinks.get(lt.getSrc()));
-        assertTrue(topology.switchLinks.get(lt.getSrc()).contains(lt));
-        assertNotNull(topology.portLinks.get(srcNpt));
-        assertTrue(topology.portLinks.get(srcNpt).contains(lt));
-        assertNotNull(topology.portLinks.get(dstNpt));
-        assertTrue(topology.portLinks.get(dstNpt).contains(lt));
-        assertTrue(topology.links.containsKey(lt));
+        assertNotNull(linkDiscovery.switchLinks.get(lt.getSrc()));
+        assertTrue(linkDiscovery.switchLinks.get(lt.getSrc()).contains(lt));
+        assertNotNull(linkDiscovery.portLinks.get(srcNpt));
+        assertTrue(linkDiscovery.portLinks.get(srcNpt).contains(lt));
+        assertNotNull(linkDiscovery.portLinks.get(dstNpt));
+        assertTrue(linkDiscovery.portLinks.get(dstNpt).contains(lt));
+        assertTrue(linkDiscovery.links.containsKey(lt));
 
-        LinkInfo infoToVerify = topology.links.get(lt);
+        LinkInfo infoToVerify = linkDiscovery.links.get(lt);
         assertEquals(firstSeenTime, infoToVerify.getFirstSeenTime());
-        assertEquals(0, infoToVerify.getSrcPortState());
-        assertEquals(0, infoToVerify.getDstPortState());
+        assertEquals(EMPTY_PORT_STATE, infoToVerify.getSrcPortState());
+        assertEquals(EMPTY_PORT_STATE, infoToVerify.getDstPortState());
 
         // Arbitrary new port states to verify that the port state is updated
-        final int newSrcPortState = 1;
-        final int newDstPortState = 2;
+        final Set<OFPortState> newSrcPortState =
+                Collections.singleton(OFPortState.STP_BLOCK);
+        final Set<OFPortState> newDstPortState =
+                Collections.singleton(OFPortState.LINK_DOWN);
 
         // Update the last received probe timestamp and the port states
         LinkInfo infoWithStateChange = new LinkInfo(System.currentTimeMillis(),
                 System.currentTimeMillis(), newSrcPortState, newDstPortState);
 
-        topology.addOrUpdateLink(lt, infoWithStateChange);
+        linkDiscovery.addOrUpdateLink(lt, infoWithStateChange);
 
-        assertNotNull(topology.links.get(lt));
-        infoToVerify = topology.links.get(lt);
+        assertNotNull(linkDiscovery.links.get(lt));
+        infoToVerify = linkDiscovery.links.get(lt);
         // First seen time should be the original time, not the second update time
         assertEquals(firstSeenTime, infoToVerify.getFirstSeenTime());
         // Both port states should have been updated
@@ -171,114 +247,114 @@
 
     @Test
     public void testDeleteLink() throws Exception {
-        LinkDiscoveryManager topology = getTopology();
+        LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
 
         Link lt = new Link(1L, 2, 2L, 1);
         LinkInfo info = new LinkInfo(System.currentTimeMillis(),
-                System.currentTimeMillis(), 0, 0);
-        topology.addOrUpdateLink(lt, info);
-        topology.deleteLinks(Collections.singletonList(lt));
+                System.currentTimeMillis(), EMPTY_PORT_STATE, EMPTY_PORT_STATE);
+        linkDiscovery.addOrUpdateLink(lt, info);
+        linkDiscovery.deleteLinks(Collections.singletonList(lt));
 
         // check invariants hold
-        assertNull(topology.switchLinks.get(lt.getSrc()));
-        assertNull(topology.switchLinks.get(lt.getDst()));
-        assertNull(topology.portLinks.get(lt.getSrc()));
-        assertNull(topology.portLinks.get(lt.getDst()));
-        assertTrue(topology.links.isEmpty());
+        assertNull(linkDiscovery.switchLinks.get(lt.getSrc()));
+        assertNull(linkDiscovery.switchLinks.get(lt.getDst()));
+        assertNull(linkDiscovery.portLinks.get(lt.getSrc()));
+        assertNull(linkDiscovery.portLinks.get(lt.getDst()));
+        assertTrue(linkDiscovery.links.isEmpty());
     }
 
     @Test
     public void testAddOrUpdateLinkToSelf() throws Exception {
-        LinkDiscoveryManager topology = getTopology();
+        LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
 
         Link lt = new Link(1L, 2, 2L, 3);
         NodePortTuple srcNpt = new NodePortTuple(1L, 2);
         NodePortTuple dstNpt = new NodePortTuple(2L, 3);
 
         LinkInfo info = new LinkInfo(System.currentTimeMillis(),
-                System.currentTimeMillis(), 0, 0);
-        topology.addOrUpdateLink(lt, info);
+                System.currentTimeMillis(), EMPTY_PORT_STATE, EMPTY_PORT_STATE);
+        linkDiscovery.addOrUpdateLink(lt, info);
 
         // check invariants hold
-        assertNotNull(topology.switchLinks.get(lt.getSrc()));
-        assertTrue(topology.switchLinks.get(lt.getSrc()).contains(lt));
-        assertNotNull(topology.portLinks.get(srcNpt));
-        assertTrue(topology.portLinks.get(srcNpt).contains(lt));
-        assertNotNull(topology.portLinks.get(dstNpt));
-        assertTrue(topology.portLinks.get(dstNpt).contains(lt));
-        assertTrue(topology.links.containsKey(lt));
+        assertNotNull(linkDiscovery.switchLinks.get(lt.getSrc()));
+        assertTrue(linkDiscovery.switchLinks.get(lt.getSrc()).contains(lt));
+        assertNotNull(linkDiscovery.portLinks.get(srcNpt));
+        assertTrue(linkDiscovery.portLinks.get(srcNpt).contains(lt));
+        assertNotNull(linkDiscovery.portLinks.get(dstNpt));
+        assertTrue(linkDiscovery.portLinks.get(dstNpt).contains(lt));
+        assertTrue(linkDiscovery.links.containsKey(lt));
     }
 
     @Test
     public void testDeleteLinkToSelf() throws Exception {
-        LinkDiscoveryManager topology = getTopology();
+        LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
 
         Link lt = new Link(1L, 2, 1L, 3);
         NodePortTuple srcNpt = new NodePortTuple(1L, 2);
         NodePortTuple dstNpt = new NodePortTuple(2L, 3);
 
         LinkInfo info = new LinkInfo(System.currentTimeMillis(),
-                System.currentTimeMillis(), 0, 0);
-        topology.addOrUpdateLink(lt, info);
-        topology.deleteLinks(Collections.singletonList(lt));
+                System.currentTimeMillis(), EMPTY_PORT_STATE, EMPTY_PORT_STATE);
+        linkDiscovery.addOrUpdateLink(lt, info);
+        linkDiscovery.deleteLinks(Collections.singletonList(lt));
 
         // check invariants hold
-        assertNull(topology.switchLinks.get(lt.getSrc()));
-        assertNull(topology.switchLinks.get(lt.getDst()));
-        assertNull(topology.portLinks.get(srcNpt));
-        assertNull(topology.portLinks.get(dstNpt));
-        assertTrue(topology.links.isEmpty());
+        assertNull(linkDiscovery.switchLinks.get(lt.getSrc()));
+        assertNull(linkDiscovery.switchLinks.get(lt.getDst()));
+        assertNull(linkDiscovery.portLinks.get(srcNpt));
+        assertNull(linkDiscovery.portLinks.get(dstNpt));
+        assertTrue(linkDiscovery.links.isEmpty());
     }
 
     @Test
     public void testRemovedSwitch() {
-        LinkDiscoveryManager topology = getTopology();
+        LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
 
         Link lt = new Link(1L, 2, 2L, 1);
         NodePortTuple srcNpt = new NodePortTuple(1L, 2);
         NodePortTuple dstNpt = new NodePortTuple(2L, 1);
         LinkInfo info = new LinkInfo(System.currentTimeMillis(),
-                System.currentTimeMillis(), 0, 0);
-        topology.addOrUpdateLink(lt, info);
+                System.currentTimeMillis(), EMPTY_PORT_STATE, EMPTY_PORT_STATE);
+        linkDiscovery.addOrUpdateLink(lt, info);
 
         IOFSwitch sw1 = getMockFloodlightProvider().getSwitches().get(1L);
         IOFSwitch sw2 = getMockFloodlightProvider().getSwitches().get(2L);
         // Mock up our expected behavior
-        topology.removedSwitch(sw1);
+        linkDiscovery.switchDisconnected(sw1.getId());
         verify(sw1, sw2);
 
         // check invariants hold
-        assertNull(topology.switchLinks.get(lt.getSrc()));
-        assertNull(topology.switchLinks.get(lt.getDst()));
-        assertNull(topology.portLinks.get(srcNpt));
-        assertNull(topology.portLinks.get(dstNpt));
-        assertTrue(topology.links.isEmpty());
+        assertNull(linkDiscovery.switchLinks.get(lt.getSrc()));
+        assertNull(linkDiscovery.switchLinks.get(lt.getDst()));
+        assertNull(linkDiscovery.portLinks.get(srcNpt));
+        assertNull(linkDiscovery.portLinks.get(dstNpt));
+        assertTrue(linkDiscovery.links.isEmpty());
     }
 
     @Test
     public void testRemovedSwitchSelf() {
-        LinkDiscoveryManager topology = getTopology();
+        LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
         IOFSwitch sw1 = createMockSwitch(1L);
         replay(sw1);
         Link lt = new Link(1L, 2, 1L, 3);
         LinkInfo info = new LinkInfo(System.currentTimeMillis(),
-                System.currentTimeMillis(), 0, 0);
-        topology.addOrUpdateLink(lt, info);
+                System.currentTimeMillis(), EMPTY_PORT_STATE, EMPTY_PORT_STATE);
+        linkDiscovery.addOrUpdateLink(lt, info);
 
         // Mock up our expected behavior
-        topology.removedSwitch(sw1);
+        linkDiscovery.switchDisconnected(sw1.getId());
 
         verify(sw1);
         // check invariants hold
-        assertNull(topology.switchLinks.get(lt.getSrc()));
-        assertNull(topology.portLinks.get(lt.getSrc()));
-        assertNull(topology.portLinks.get(lt.getDst()));
-        assertTrue(topology.links.isEmpty());
+        assertNull(linkDiscovery.switchLinks.get(lt.getSrc()));
+        assertNull(linkDiscovery.portLinks.get(lt.getSrc()));
+        assertNull(linkDiscovery.portLinks.get(lt.getDst()));
+        assertTrue(linkDiscovery.links.isEmpty());
     }
 
     @Test
     public void testAddUpdateLinks() throws Exception {
-        LinkDiscoveryManager topology = getTopology();
+        LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
 
         Link lt = new Link(1L, 1, 2L, 1);
         NodePortTuple srcNpt = new NodePortTuple(1L, 1);
@@ -286,31 +362,34 @@
 
         LinkInfo info;
 
+        // Setting the last LLDP reception time to be 40 seconds old, so we
+        // can use this to test that an old link times out correctly
         info = new LinkInfo(System.currentTimeMillis() - 40000,
-                System.currentTimeMillis() - 40000, 0, 0);
-        topology.addOrUpdateLink(lt, info);
+                System.currentTimeMillis() - 40000,
+                EMPTY_PORT_STATE, EMPTY_PORT_STATE);
+        linkDiscovery.addOrUpdateLink(lt, info);
 
         // check invariants hold
-        assertNotNull(topology.switchLinks.get(lt.getSrc()));
-        assertTrue(topology.switchLinks.get(lt.getSrc()).contains(lt));
-        assertNotNull(topology.portLinks.get(srcNpt));
-        assertTrue(topology.portLinks.get(srcNpt).contains(lt));
-        assertNotNull(topology.portLinks.get(dstNpt));
-        assertTrue(topology.portLinks.get(dstNpt).contains(lt));
-        assertTrue(topology.links.containsKey(lt));
+        assertNotNull(linkDiscovery.switchLinks.get(lt.getSrc()));
+        assertTrue(linkDiscovery.switchLinks.get(lt.getSrc()).contains(lt));
+        assertNotNull(linkDiscovery.portLinks.get(srcNpt));
+        assertTrue(linkDiscovery.portLinks.get(srcNpt).contains(lt));
+        assertNotNull(linkDiscovery.portLinks.get(dstNpt));
+        assertTrue(linkDiscovery.portLinks.get(dstNpt).contains(lt));
+        assertTrue(linkDiscovery.links.containsKey(lt));
 
-        topology.timeOutLinks();
+        linkDiscovery.timeOutLinks();
 
-        // Add a link info based on info that would be obtained from unicast LLDP
-        // Setting the unicast LLDP reception time to be 40 seconds old, so we can use
-        // this to test timeout after this test.
+        // Setting the last LLDP reception time to be 40 seconds old, so we
+        // can use this to test that an old link times out correctly
         info = new LinkInfo(System.currentTimeMillis() - 40000,
-                System.currentTimeMillis() - 40000, 0, 0);
-        topology.addOrUpdateLink(lt, info);
+                System.currentTimeMillis() - 40000,
+                EMPTY_PORT_STATE, EMPTY_PORT_STATE);
+        linkDiscovery.addOrUpdateLink(lt, info);
 
         // Expect to timeout the unicast Valid Time, so the link should disappear
-        topology.timeOutLinks();
-        assertTrue(topology.links.get(lt) == null);
+        linkDiscovery.timeOutLinks();
+        assertTrue(linkDiscovery.links.get(lt) == null);
     }
 
     /**
@@ -322,58 +401,49 @@
      */
     @Test
     public void testSendDiscoveryMessage() throws IOException {
-        byte[] macAddress = new byte[] {0x0, 0x0, 0x0, 0x0, 0x0, 0x1};
-
-        LinkDiscoveryManager topology = getTopology();
+        LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
 
         // Mock up our expected behavior
         IOFSwitch swTest = createMockSwitch(3L);
         getMockFloodlightProvider().getSwitches().put(3L, swTest);
 
         short portNum = 1;
-        OFPhysicalPort ofpPort = new OFPhysicalPort();
-        ofpPort.setPortNumber(portNum);
-        ofpPort.setHardwareAddress(macAddress);
 
-        /* sendDiscoverMessage() should perform the following actions on
-         * IOFSwitch object
-         * - getPort() with argument as "1"
-         * - write() with OFPacketOut
-         * - flush()
-         */
-        expect(swTest.getPort(portNum)).andReturn(ofpPort).atLeastOnce();
-        swTest.write(EasyMock.anyObject(OFMessage.class), EasyMock.anyObject(FloodlightContext.class));
+        OFPortDesc ofPortDesc = createMockPort(portNum);
+
+        expect(swTest.getPort(portNum)).andReturn(ofPortDesc).atLeastOnce();
+        swTest.write(matchOutPort(portNum),
+                EasyMock.anyObject(FloodlightContext.class));
         EasyMock.expectLastCall().times(1);
         swTest.flush();
         EasyMock.expectLastCall().once();
         replay(swTest);
 
-        topology.sendDiscoveryMessage(3L, portNum, false);
+        linkDiscovery.sendDiscoveryMessage(3L, portNum, false);
 
         verify(swTest);
     }
 
     @Test
     public void testHandlePortStatusForNewPort() throws IOException {
-        byte[] macAddress = new byte[] {0x0, 0x0, 0x0, 0x0, 0x0, 0x1};
-
-        LinkDiscoveryManager linkDiscovery = getTopology();
+        LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
 
         long dpid = 3L;
         IOFSwitch sw = createMockSwitch(dpid);
         getMockFloodlightProvider().getSwitches().put(dpid, sw);
 
         short portNum = 1;
-        OFPhysicalPort ofpPort = new OFPhysicalPort();
-        ofpPort.setPortNumber(portNum);
-        ofpPort.setHardwareAddress(macAddress);
 
-        OFPortStatus portStatus = new OFPortStatus();
-        portStatus.setDesc(ofpPort);
-        portStatus.setReason((byte) OFPortReason.OFPPR_ADD.ordinal());
+        OFPortDesc ofPortDesc = createMockPort(portNum);
 
-        expect(sw.getPort(portNum)).andReturn(ofpPort).anyTimes();
-        sw.write(EasyMock.anyObject(OFMessage.class),
+        OFPortStatus portStatus = factory10.buildPortStatus()
+            .setDesc(ofPortDesc)
+            .setReason(OFPortReason.ADD)
+            .build();
+
+        expect(sw.getPort(portNum)).andReturn(ofPortDesc).once();
+
+        sw.write(matchOutPort(portNum),
                 EasyMock.anyObject(FloodlightContext.class));
         sw.flush();
 
@@ -386,47 +456,41 @@
 
     @Test
     public void testHandlePortStatusForExistingPort() {
-        byte[] macAddress = new byte[] {0x0, 0x0, 0x0, 0x0, 0x0, 0x1};
-
-        LinkDiscoveryManager linkDiscovery = getTopology();
+        LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
 
         // Add a link that we can update later during the test
         Link lt = new Link(1L, 1, 2L, 1);
         LinkInfo info = new LinkInfo(System.currentTimeMillis(),
-                System.currentTimeMillis(), 0, 0);
+                System.currentTimeMillis(), EMPTY_PORT_STATE, EMPTY_PORT_STATE);
         linkDiscovery.addOrUpdateLink(lt, info);
 
         short portNum = 1;
-        // src port
-        int srcPortState = 2;
-        OFPhysicalPort srcPort = new OFPhysicalPort();
-        srcPort.setPortNumber(portNum);
-        srcPort.setHardwareAddress(macAddress);
-        srcPort.setState(srcPortState);
 
-        // dst port
-        int dstPortState = 4;
-        OFPhysicalPort dstPort = new OFPhysicalPort();
-        dstPort.setPortNumber(portNum);
-        dstPort.setHardwareAddress(macAddress);
-        dstPort.setState(dstPortState);
+        // Arbitrary states to test state changes
+        Set<OFPortState> srcPortState =
+                Collections.singleton(OFPortState.STP_FORWARD);
+        Set<OFPortState> dstPortState =
+                Collections.singleton(OFPortState.STP_LISTEN);
 
-        OFPortStatus srcPortStatus = new OFPortStatus();
-        srcPortStatus.setDesc(srcPort);
-        srcPortStatus.setReason((byte) OFPortReason.OFPPR_MODIFY.ordinal());
+        OFPortDesc srcPortDesc = createMockPortWithState(portNum, srcPortState);
+        OFPortDesc dstPortDesc = createMockPortWithState(portNum, dstPortState);
 
-        OFPortStatus dstPortStatus = new OFPortStatus();
-        dstPortStatus.setDesc(dstPort);
-        dstPortStatus.setReason((byte) OFPortReason.OFPPR_MODIFY.ordinal());
+        OFPortStatus srcPortStatus = factory10.buildPortStatus()
+                .setDesc(srcPortDesc)
+                .setReason(OFPortReason.MODIFY)
+                .build();
+
+        OFPortStatus dstPortStatus = factory10.buildPortStatus()
+                .setDesc(dstPortDesc)
+                .setReason(OFPortReason.MODIFY)
+                .build();
 
         linkDiscovery.handlePortStatus(
                 getMockFloodlightProvider().getSwitches().get(1L), srcPortStatus);
 
-
         LinkInfo newInfo = linkDiscovery.links.get(lt);
         assertEquals(srcPortState, newInfo.getSrcPortState());
-        assertEquals(0, newInfo.getDstPortState());
-
+        assertEquals(EMPTY_PORT_STATE, newInfo.getDstPortState());
 
         linkDiscovery.handlePortStatus(
                 getMockFloodlightProvider().getSwitches().get(2L), dstPortStatus);
@@ -438,26 +502,21 @@
 
     @Test
     public void testHandlePortStatusForDeletePort() {
-        byte[] macAddress = new byte[] {0x0, 0x0, 0x0, 0x0, 0x0, 0x1};
-
-        LinkDiscoveryManager linkDiscovery = getTopology();
+        LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
 
         // Add a link that we can delete later during the test
         Link lt = new Link(1L, 1, 2L, 2);
         LinkInfo info = new LinkInfo(System.currentTimeMillis(),
-                System.currentTimeMillis(), 0, 0);
+                System.currentTimeMillis(), EMPTY_PORT_STATE, EMPTY_PORT_STATE);
         linkDiscovery.addOrUpdateLink(lt, info);
 
         short portNum = 1;
-        int srcPortState = 1;
-        OFPhysicalPort srcPort = new OFPhysicalPort();
-        srcPort.setPortNumber(portNum);
-        srcPort.setHardwareAddress(macAddress);
-        srcPort.setState(srcPortState);
 
-        OFPortStatus srcPortStatus = new OFPortStatus();
-        srcPortStatus.setDesc(srcPort);
-        srcPortStatus.setReason((byte) OFPortReason.OFPPR_DELETE.ordinal());
+        OFPortDesc srcPortDesc = createMockPort(portNum);
+        OFPortStatus srcPortStatus = factory10.buildPortStatus()
+                .setDesc(srcPortDesc)
+                .setReason(OFPortReason.DELETE)
+                .build();
 
         assertNotNull(linkDiscovery.getLinks().get(lt));
 
@@ -471,8 +530,6 @@
 
     @Test
     public void testReceive() {
-        byte[] macAddress = new byte[] {0x0, 0x0, 0x0, 0x0, 0x0, 0x1};
-
         OnosLldp lldpPacket = new OnosLldp();
         lldpPacket.setPort((short) 1);
         lldpPacket.setSwitch(1L);
@@ -480,24 +537,24 @@
 
         Ethernet ethPacket = new Ethernet();
         ethPacket.setEtherType(Ethernet.TYPE_LLDP);
-        ethPacket.setSourceMACAddress(macAddress);
+        ethPacket.setSourceMACAddress(DEFAULT_MAC_ADDRESS);
         ethPacket.setDestinationMACAddress(
                 LinkDiscoveryManager.LLDP_STANDARD_DST_MAC_STRING);
         ethPacket.setPayload(lldpPacket);
         ethPacket.setPad(true);
 
-        OFPacketIn pi = new OFPacketIn();
-        pi.setInPort((short) 2);
-        pi.setPacketData(ethPacket.serialize());
+        OFPacketIn pi = EasyMock.createMock(OFPacketIn.class);
+        expect(pi.getData()).andReturn(ethPacket.serialize()).anyTimes();
+        replay(pi);
 
-        LinkDiscoveryManager linkDiscovery = getTopology();
+        LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
 
         Link expectedLink = new Link(1L, 1, 2L, 2);
 
         assertNull(linkDiscovery.links.get(expectedLink));
 
         // Sending in the LLDP packet should cause the link to be created
-        Command command = linkDiscovery.handleLldp(lldpPacket, 2L, pi);
+        Command command = linkDiscovery.handleLldp(lldpPacket, 2L, pi, (short) 2);
 
         assertEquals(Command.STOP, command);
         assertNotNull(linkDiscovery.links.get(expectedLink));