diff --git a/src/main/java/net/floodlightcontroller/flowcache/FlowReconcileManager.java b/src/main/java/net/floodlightcontroller/flowcache/FlowReconcileManager.java
index 578a15e60d15cc41294155e052082b107b9562b2..8578fc07aa92cda233d1b9bce486f939ba8dc383 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/FlowReconcileManager.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/FlowReconcileManager.java
@@ -46,8 +46,6 @@ import org.projectfloodlight.openflow.protocol.OFType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.sun.j3d.utils.scenegraph.io.retained.Controller;
-
 public class FlowReconcileManager implements IFloodlightModule, IFlowReconcileService {
     /** The logger. */
     private static Logger logger =  LoggerFactory.getLogger(FlowReconcileManager.class);
diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntries.java b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntries.java
index 97d71ba236e28526a06b2ed4cf9b6453a86431e6..07b9fd9e019d03d30b8149f2d3fd902aa847e4a3 100644
--- a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntries.java
+++ b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntries.java
@@ -193,7 +193,6 @@ public class StaticFlowEntries {
 
 		Match match = fm.getMatch();
 		// it's a shame we can't use the MatchUtils for this. It's kind of the same thing but storing in a different place.
-		boolean setTOS = false;
 		Iterator<MatchField<?>> itr = match.getMatchFields().iterator(); // only get exact or masked fields (not fully wildcarded)
 		while(itr.hasNext()) {
 			@SuppressWarnings("rawtypes") // this is okay here
@@ -217,25 +216,11 @@ public class StaticFlowEntries {
 			case ETH_TYPE:
 				entry.put(StaticFlowEntryPusher.COLUMN_DL_TYPE, match.get(MatchField.ETH_TYPE).getValue());
 				break;
-			case IP_ECN: // TOS = [DSCP bits 0-5] + [ECN bits 6-7] --> bitwise OR to get TOS byte
-				if (setTOS) { //TODO @Ryan need to break TOS into ECN and DSCP columns
-					entry.put(StaticFlowEntryPusher.COLUMN_NW_TOS, 
-							Byte.toString((byte) (match.get(MatchField.IP_ECN).getEcnValue() 
-									| (Byte.parseByte(entry.get(StaticFlowEntryPusher.COLUMN_NW_TOS).toString())))));
-				} else {
-					entry.put(StaticFlowEntryPusher.COLUMN_NW_TOS, Byte.toString((byte) (match.get(MatchField.IP_ECN).getEcnValue())));
-				}
-				setTOS = true;
-				break;
-			case IP_DSCP:
-				if (setTOS) {
-					entry.put(StaticFlowEntryPusher.COLUMN_NW_TOS, 
-							Byte.toString((byte) (match.get(MatchField.IP_DSCP).getDscpValue() 
-									| (Byte.parseByte(entry.get(StaticFlowEntryPusher.COLUMN_NW_TOS).toString())))));
-				} else {
-					entry.put(StaticFlowEntryPusher.COLUMN_NW_TOS, Byte.toString((byte) (match.get(MatchField.IP_ECN).getEcnValue())));
-				}
-				setTOS = true;
+			case IP_ECN: // TOS = [DSCP bits 0-5] + [ECN bits 6-7] --> bitwise OR to get TOS byte (have separate columns now though)
+				entry.put(StaticFlowEntryPusher.COLUMN_NW_ECN, Byte.toString(match.get(MatchField.IP_ECN).getEcnValue()));
+				break;
+			case IP_DSCP: // Even for OF1.0, loxi will break ECN and DSCP up from the API's POV. This method is only invoked by a SFP service push from another module
+				entry.put(StaticFlowEntryPusher.COLUMN_NW_DSCP, Byte.toString((byte) (match.get(MatchField.IP_DSCP).getDscpValue())));
 				break;
 			case IP_PROTO:
 				entry.put(StaticFlowEntryPusher.COLUMN_NW_PROTO, Short.toString(match.get(MatchField.IP_PROTO).getIpProtocolNumber()));
@@ -402,9 +387,15 @@ public class StaticFlowEntries {
 			case StaticFlowEntryPusher.COLUMN_DL_TYPE:
 				entry.put(StaticFlowEntryPusher.COLUMN_DL_TYPE, jp.getText());
 				break;
-			case StaticFlowEntryPusher.COLUMN_NW_TOS:
+			case StaticFlowEntryPusher.COLUMN_NW_TOS: // only valid for OF1.0; all other should specify specifics (ECN and/or DSCP bits)
 				entry.put(StaticFlowEntryPusher.COLUMN_NW_TOS, jp.getText());
 				break;
+			case StaticFlowEntryPusher.COLUMN_NW_ECN:
+				entry.put(StaticFlowEntryPusher.COLUMN_NW_ECN, jp.getText());
+				break;
+			case StaticFlowEntryPusher.COLUMN_NW_DSCP:
+				entry.put(StaticFlowEntryPusher.COLUMN_NW_DSCP, jp.getText());
+				break;
 			case StaticFlowEntryPusher.COLUMN_NW_PROTO:
 				entry.put(StaticFlowEntryPusher.COLUMN_NW_PROTO, jp.getText());
 				ipProto = jp.getText();
diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java
index 00540929f2e1ac22746af481001a9ec864631d78..7154396b37dbd56b3ac4c10769ae0793302c8543 100644
--- a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java
+++ b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java
@@ -107,6 +107,8 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService,
 	public static final String COLUMN_DL_TYPE = MatchUtils.STR_DL_TYPE;
 
 	public static final String COLUMN_NW_TOS = MatchUtils.STR_NW_TOS;
+	public static final String COLUMN_NW_ECN = MatchUtils.STR_NW_ECN;
+	public static final String COLUMN_NW_DSCP = MatchUtils.STR_NW_DSCP;
 	public static final String COLUMN_NW_PROTO = MatchUtils.STR_NW_PROTO;
 	public static final String COLUMN_NW_SRC = MatchUtils.STR_NW_SRC; // includes CIDR-style netmask, e.g. "128.8.128.0/24"
 	public static final String COLUMN_NW_DST = MatchUtils.STR_NW_DST;
@@ -340,7 +342,7 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService,
 			}
 
 			// get the correct builder for the OF version supported by the switch
-			// TODO @Ryan this should arguably be a FlowAdd, not a FlowModify
+			// TODO @Ryan this should arguably be a FlowAdd, not a FlowModify, but it really doesn't matter
 			fmb = OFFactories.getFactory(switchService.getSwitch(DatapathId.of(switchName)).getOFFactory().getVersion()).buildFlowModify();
 
 			StaticFlowEntries.initDefaultFlowMod(fmb, entryName);
diff --git a/src/main/java/net/floodlightcontroller/storage/AbstractStorageSource.java b/src/main/java/net/floodlightcontroller/storage/AbstractStorageSource.java
index 911c1a12dcc31d06bced558ffbcc87b694eb6474..22c7656f93cf57f4f993d9dd52d30de1b35d62fc 100644
--- a/src/main/java/net/floodlightcontroller/storage/AbstractStorageSource.java
+++ b/src/main/java/net/floodlightcontroller/storage/AbstractStorageSource.java
@@ -36,7 +36,6 @@ 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.debugcounter.IDebugCounter;
 import net.floodlightcontroller.debugcounter.IDebugCounterService;
 import net.floodlightcontroller.restserver.IRestApiService;
 import net.floodlightcontroller.storage.web.StorageWebRoutable;
diff --git a/src/main/java/net/floodlightcontroller/testmodule/TestModule.java b/src/main/java/net/floodlightcontroller/testmodule/TestModule.java
index 5344ee9a78ad1f4c8e9328023653cc814577bf2c..2b3d7ec51c020b4717168104229f7b112b9c5984 100644
--- a/src/main/java/net/floodlightcontroller/testmodule/TestModule.java
+++ b/src/main/java/net/floodlightcontroller/testmodule/TestModule.java
@@ -9,6 +9,10 @@ import java.util.Map;
 import org.projectfloodlight.openflow.protocol.OFFactories;
 import org.projectfloodlight.openflow.protocol.OFFactory;
 import org.projectfloodlight.openflow.protocol.OFFlowAdd;
+import org.projectfloodlight.openflow.protocol.OFMeterBandStats;
+import org.projectfloodlight.openflow.protocol.OFMeterBandType;
+import org.projectfloodlight.openflow.protocol.OFMeterMod;
+import org.projectfloodlight.openflow.protocol.OFMeterModCommand;
 import org.projectfloodlight.openflow.protocol.OFOxmClass;
 import org.projectfloodlight.openflow.protocol.OFPortDesc;
 import org.projectfloodlight.openflow.protocol.OFSetConfig;
@@ -17,8 +21,17 @@ import org.projectfloodlight.openflow.protocol.action.OFAction;
 import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
 import org.projectfloodlight.openflow.protocol.action.OFActionSetField;
 import org.projectfloodlight.openflow.protocol.action.OFActionSetNwSrc;
+import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
+import org.projectfloodlight.openflow.protocol.instruction.OFInstructionApplyActions;
+import org.projectfloodlight.openflow.protocol.instruction.OFInstructionClearActions;
+import org.projectfloodlight.openflow.protocol.instruction.OFInstructionExperimenter;
+import org.projectfloodlight.openflow.protocol.instruction.OFInstructionGotoTable;
+import org.projectfloodlight.openflow.protocol.instruction.OFInstructionMeter;
+import org.projectfloodlight.openflow.protocol.instruction.OFInstructionWriteActions;
 import org.projectfloodlight.openflow.protocol.match.Match;
 import org.projectfloodlight.openflow.protocol.match.MatchField;
+import org.projectfloodlight.openflow.protocol.meterband.OFMeterBand;
+import org.projectfloodlight.openflow.protocol.meterband.OFMeterBandDrop;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthSrc;
 import org.projectfloodlight.openflow.types.ArpOpcode;
@@ -39,6 +52,7 @@ import org.projectfloodlight.openflow.types.OFVlanVidMatch;
 import org.projectfloodlight.openflow.types.TableId;
 import org.projectfloodlight.openflow.types.TransportPort;
 import org.projectfloodlight.openflow.types.U32;
+import org.projectfloodlight.openflow.types.U64;
 import org.projectfloodlight.openflow.types.U8;
 import org.projectfloodlight.openflow.types.VlanPcp;
 import org.projectfloodlight.openflow.types.VlanVid;
@@ -103,6 +117,18 @@ public class TestModule implements IFloodlightModule, IOFSwitchListener {
 		OFFlowAdd.Builder fmb = factory.buildFlowAdd();
 		List<OFAction> actions = new ArrayList<OFAction>();
         Match.Builder mb = factory.buildMatch();
+        List<OFInstruction> instructions = new ArrayList<OFInstruction>();
+        OFInstructionApplyActions.Builder applyActInstBldr = factory.instructions().buildApplyActions();
+        OFInstructionWriteActions.Builder writeActInstBldr = factory.instructions().buildWriteActions();
+        OFInstructionMeter.Builder mtrBldr = factory.instructions().buildMeter();
+        OFInstructionClearActions clrAct = factory.instructions().clearActions(); // no builder available (there's nothing to set anyway)
+        OFInstructionGotoTable.Builder gotoTblBldr = factory.instructions().buildGotoTable();
+        /*OFMeterBandDrop dropMeter = factory.meterBands().buildDrop().setBurstSize(100).setRate(200).build();
+        List<OFMeterBand> meterBandEntries = new ArrayList<OFMeterBand>();
+        OFMeterBandStats meterBandStats = factory.buildMeterBandStats().setPacketBandCount(U64.of(64)).setByteBandCount(U64.of(1024)).build();
+        meterBandEntries.add(meterBandStats);
+        OFMeterMod meterMod = factory.buildMeterMod().setCommand(OFMeterModCommand.ADD.ordinal()).setMeters(meterBandEntries).setMeterId(10).build();
+        factory.buildmeter*/
         
 		/*try {
 			Thread.sleep(3000);
@@ -158,6 +184,9 @@ public class TestModule implements IFloodlightModule, IOFSwitchListener {
         actions.add(factory.actions().setField(factory.oxms().ipv4Dst(IPv4Address.of("128.0.3.4")))); 
         actions.add(factory.actions().setField(factory.oxms().sctpSrc(TransportPort.of(22))));
         actions.add(factory.actions().setField(factory.oxms().sctpDst(TransportPort.of(80))));
+        actions.add(factory.actions().setField((factory.oxms().ipDscp(IpDscp.DSCP_11))));
+        actions.add(factory.actions().setField((factory.oxms().ipEcn(IpEcn.ECN_10))));
+
         fmb.setTableId(TableId.of(7));
         // these test non-set-field actions
         //actions.add(factory.actions().copyTtlOut());
@@ -174,8 +203,12 @@ public class TestModule implements IFloodlightModule, IOFSwitchListener {
         
         /* METADATA TEST 
         mb.setExact(MatchField.METADATA, OFMetadata.ofRaw(1)); */
-
-        fmb.setActions(actions);
+        //fmb.setActions(actions); // this will automatically create the apply actions instruction
+        applyActInstBldr.setActions(actions);
+        //mtrBldr.setMeterId(1);
+        instructions.add(applyActInstBldr.build());
+        //instructions.add(mtrBldr.build());
+        fmb.setInstructions(instructions);
         fmb.setMatch(mb.build());
 		        
 		sfps.addFlow("test-flow", fmb.build(), switchId);
diff --git a/src/main/java/net/floodlightcontroller/topology/NodePortTuple.java b/src/main/java/net/floodlightcontroller/topology/NodePortTuple.java
index 2e336c3b8ef270b105bdc5f40a580721b25896ea..758e50a9242cdd17df6cdc24075e532908fa5068 100644
--- a/src/main/java/net/floodlightcontroller/topology/NodePortTuple.java
+++ b/src/main/java/net/floodlightcontroller/topology/NodePortTuple.java
@@ -17,7 +17,6 @@
 package net.floodlightcontroller.topology;
 
 import net.floodlightcontroller.core.web.serializers.DPIDSerializer;
-import net.floodlightcontroller.core.web.serializers.UShortSerializer;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
diff --git a/src/main/java/net/floodlightcontroller/ui/web/StaticWebRoutable.java b/src/main/java/net/floodlightcontroller/ui/web/StaticWebRoutable.java
index aab21fb643a6634b9d7693d642e59e14945e7f3e..6470c904562639647960962221a6ad0e6c016db7 100644
--- a/src/main/java/net/floodlightcontroller/ui/web/StaticWebRoutable.java
+++ b/src/main/java/net/floodlightcontroller/ui/web/StaticWebRoutable.java
@@ -67,7 +67,6 @@ public class StaticWebRoutable implements RestletRoutable, IFloodlightModule {
     public void startUp(FloodlightModuleContext context) {
         // Add our REST API
         restApi.addRestletRoutable(this);
-        
     }
 
 	@Override
diff --git a/src/main/java/net/floodlightcontroller/util/ActionUtils.java b/src/main/java/net/floodlightcontroller/util/ActionUtils.java
index 3b0553d49a81910ed71db764beea2a8263cb932c..28d9a206f09cc2aae84f4fed2f6d1e3860124ed1 100644
--- a/src/main/java/net/floodlightcontroller/util/ActionUtils.java
+++ b/src/main/java/net/floodlightcontroller/util/ActionUtils.java
@@ -67,6 +67,7 @@ import org.projectfloodlight.openflow.types.EthType;
 import org.projectfloodlight.openflow.types.ICMPv4Code;
 import org.projectfloodlight.openflow.types.ICMPv4Type;
 import org.projectfloodlight.openflow.types.IPv4Address;
+import org.projectfloodlight.openflow.types.IpDscp;
 import org.projectfloodlight.openflow.types.IpEcn;
 import org.projectfloodlight.openflow.types.IpProtocol;
 import org.projectfloodlight.openflow.types.MacAddress;
@@ -278,9 +279,9 @@ public class ActionUtils {
                 	} else if (((OFActionSetField)a).getField() instanceof OFOxmIpv4Dst) {
                     	sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_NW_DST + MatchUtils.SET_FIELD_DELIM + ((OFOxmIpv4Dst) ((OFActionSetField) a).getField()).getValue().toString()); 
                 	} else if (((OFActionSetField)a).getField() instanceof OFOxmIpEcn) { //TODO @Ryan ECN and DSCP need to have their own columns for OF1.3....
-                    	sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_NW_TOS + MatchUtils.SET_FIELD_DELIM + Byte.toString(((OFOxmIpEcn) ((OFActionSetField) a).getField()).getValue().getEcnValue())); 
+                    	sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_NW_ECN + MatchUtils.SET_FIELD_DELIM + Byte.toString(((OFOxmIpEcn) ((OFActionSetField) a).getField()).getValue().getEcnValue())); 
                 	} else if (((OFActionSetField)a).getField() instanceof OFOxmIpDscp) {
-                    	sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_NW_TOS + MatchUtils.SET_FIELD_DELIM + Byte.toString(((OFOxmIpDscp) ((OFActionSetField) a).getField()).getValue().getDscpValue())); 
+                    	sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_NW_DSCP + MatchUtils.SET_FIELD_DELIM + Byte.toString(((OFOxmIpDscp) ((OFActionSetField) a).getField()).getValue().getDscpValue())); 
                 	} 
                 	/* TRANSPORT LAYER, TCP, UDP, and SCTP */
                 	  else if (((OFActionSetField)a).getField() instanceof OFOxmTcpSrc) {
@@ -375,7 +376,7 @@ public class ActionUtils {
 				case STR_EXPERIMENTER:
 					//no-op. Not implemented
 					break;
-				case STR_FIELD_SET:
+				case STR_FIELD_SET: /* ONLY OF1.1+ should get in here. These should only be header fields valid within a set-field. */
 					String[] actionData = pair.split(MatchUtils.SET_FIELD_DELIM);
 					if (actionData.length != 2) {
 						throw new IllegalArgumentException("[Action, Data] " + keyPair + " does not have form 'action=data' parsing " + actionData);
@@ -456,9 +457,15 @@ public class ActionUtils {
 						.setField(OFFactories.getFactory(fmb.getVersion()).oxms().buildIpv4Dst().setValue(IPv4Address.of(actionData[1])).build())
 						.build();						
 						break;
-					case MatchUtils.STR_NW_TOS:
-						//TODO @Ryan need to break this up into ECN and DSCP
-						
+					case MatchUtils.STR_NW_ECN:
+						a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetField()
+						.setField(OFFactories.getFactory(fmb.getVersion()).oxms().buildIpEcn().setValue(IpEcn.of(Byte.parseByte(actionData[1]))).build())
+						.build();
+						break;
+					case MatchUtils.STR_NW_DSCP:
+						a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetField()
+						.setField(OFFactories.getFactory(fmb.getVersion()).oxms().buildIpDscp().setValue(IpDscp.of(Byte.parseByte(actionData[1]))).build())
+						.build();
 						break;
 					case MatchUtils.STR_SCTP_SRC:
 						a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetField()
@@ -544,7 +551,7 @@ public class ActionUtils {
 					.build();							
 					break;
 				case STR_NW_TOS_SET:
-					a = decode_set_tos_bits(pair, fmb.getVersion(), log);
+					a = decode_set_tos_bits(pair, fmb.getVersion(), log); // should only be used by OF1.0
 					break;
 				case STR_NW_SRC_SET:
 					a = decode_set_src_ip(pair, fmb.getVersion(), log);
@@ -552,7 +559,7 @@ public class ActionUtils {
 				case STR_NW_DST_SET:
 					a = decode_set_dst_ip(pair, fmb.getVersion(), log);
 					break;
-				case STR_NW_ECN_SET:
+				case STR_NW_ECN_SET: // loxi does not support DSCP set for OF1.3
 					a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetNwEcn()
 					.setNwEcn(IpEcn.of(Byte.parseByte(pair)))
 					.build();							
diff --git a/src/main/java/net/floodlightcontroller/util/MatchUtils.java b/src/main/java/net/floodlightcontroller/util/MatchUtils.java
index f830ebc913338fa94579d6559bf21e614c59d99b..449055aeacbb4365071d5f8348f5f12595271650 100644
--- a/src/main/java/net/floodlightcontroller/util/MatchUtils.java
+++ b/src/main/java/net/floodlightcontroller/util/MatchUtils.java
@@ -59,6 +59,8 @@ public class MatchUtils {
 	public static final String STR_NW_SRC = "nw_src";
 	public static final String STR_NW_PROTO = "nw_proto";
 	public static final String STR_NW_TOS = "nw_tos";
+	public static final String STR_NW_ECN = "nw_ecn";
+	public static final String STR_NW_DSCP = "nw_dscp";
 
 	public static final String STR_SCTP_DST = "sctp_dst";
 	public static final String STR_SCTP_SRC = "sctp_src";
@@ -383,6 +385,12 @@ public class MatchUtils {
 				mb.setExact(MatchField.IP_ECN, IpEcn.of(U8.t(Short.valueOf(key_value[1]))));
 				mb.setExact(MatchField.IP_DSCP, IpDscp.of(U8.t(Short.valueOf(key_value[1]))));
 				break;
+			case STR_NW_ECN:
+				mb.setExact(MatchField.IP_ECN, IpEcn.of(U8.t(Short.valueOf(key_value[1]))));
+				break;
+			case STR_NW_DSCP:
+				mb.setExact(MatchField.IP_DSCP, IpDscp.of(U8.t(Short.valueOf(key_value[1]))));
+				break;
 			case STR_SCTP_DST: // for transport ports, if we don't know the transport protocol yet, postpone parsing this [key, value] pair until we know. Put it at the back of the queue.
 				if (mb.get(MatchField.IP_PROTO) == null) {
 					llValues.add(key_value); // place it back if we can't proceed yet
diff --git a/src/main/resources/floodlightdefault.properties b/src/main/resources/floodlightdefault.properties
index 3dbacb7bae8f06c048021048013811e26471de85..2aaab9fdaba5ce189f597a519d3c3066e5c84374 100644
--- a/src/main/resources/floodlightdefault.properties
+++ b/src/main/resources/floodlightdefault.properties
@@ -10,8 +10,9 @@ net.floodlightcontroller.debugevent.DebugEventService,\
 net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher,\
 net.floodlightcontroller.restserver.RestApiServer,\
 net.floodlightcontroller.topology.TopologyManager,\
-net.floodlightcontroller.forwarding.Forwarding,\
+net.floodlightcontroller.testmodule.TestModule,\
 net.floodlightcontroller.linkdiscovery.internal.LinkDiscoveryManager,\
+net.floodlightcontroller.ui.web.StaticWebRoutable,\
 net.floodlightcontroller.devicemanager.internal.DeviceManagerImpl
 org.sdnplatform.sync.internal.SyncManager.authScheme=CHALLENGE_RESPONSE
 org.sdnplatform.sync.internal.SyncManager.keyStorePath=/etc/floodlight/auth_credentials.jceks
diff --git a/src/main/resources/logback-test.xml b/src/main/resources/logback-test.xml
index 7f61e32e22bac17b1f72ccd1562370afe70d2673..c80889cac1cf1411fe6db835c25a1011e7364ad0 100644
--- a/src/main/resources/logback-test.xml
+++ b/src/main/resources/logback-test.xml
@@ -6,12 +6,12 @@
   </appender>
   <appender name="EV_WARN_ERR" class="net.floodlightcontroller.debugevent.DebugEventAppender">
   </appender>
-  <root level="DEBUG">
+  <root level="TRACE">
     <appender-ref ref="STDOUT" />
     <appender-ref ref="EV_WARN_ERR" />
   </root>
-  <logger name="org" level="DEBUG"/>
-  <logger name="LogService" level="DEBUG"/> <!-- Restlet access logging -->
+  <logger name="org" level="TRACE"/>
+  <logger name="LogService" level="TRACE"></logger> <!-- Restlet access logging -->
   <logger name="net.floodlightcontroller" level="DEBUG"/>
   <logger name="org.sdnplatform" level="INFO"></logger>
   <logger name="net.floodlightcontroller.devicemanager" level="TRACE"></logger>
diff --git a/src/test/java/net/floodlightcontroller/core/internal/OFSwitchHandshakeHandlerVer13Test.java b/src/test/java/net/floodlightcontroller/core/internal/OFSwitchHandshakeHandlerVer13Test.java
index 06b3a3bbeceea5a29c80a7f673f0bec31a8b63dd..2fc31311dbee3a36393b277a1f4abfe6ae6b9672 100644
--- a/src/test/java/net/floodlightcontroller/core/internal/OFSwitchHandshakeHandlerVer13Test.java
+++ b/src/test/java/net/floodlightcontroller/core/internal/OFSwitchHandshakeHandlerVer13Test.java
@@ -1,7 +1,6 @@
 package net.floodlightcontroller.core.internal;
 
 import static org.easymock.EasyMock.anyObject;
-import static org.easymock.EasyMock.capture;
 import static org.easymock.EasyMock.eq;
 import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.expectLastCall;
@@ -15,7 +14,6 @@ import java.util.ArrayList;
 import java.util.EnumSet;
 import java.util.List;
 
-import org.easymock.Capture;
 import org.hamcrest.CoreMatchers;
 import org.hamcrest.Matchers;
 import org.junit.Test;
@@ -29,10 +27,7 @@ import org.projectfloodlight.openflow.protocol.OFBsnControllerConnection;
 import org.projectfloodlight.openflow.protocol.OFBsnControllerConnectionState;
 import org.projectfloodlight.openflow.protocol.OFBsnControllerConnectionsReply;
 import org.projectfloodlight.openflow.protocol.OFBsnControllerConnectionsRequest;
-import org.projectfloodlight.openflow.protocol.OFBsnGentableDescStatsReply;
-import org.projectfloodlight.openflow.protocol.OFBsnGentableDescStatsRequest;
 import org.projectfloodlight.openflow.protocol.OFBsnSetAuxCxnsReply;
-import org.projectfloodlight.openflow.protocol.OFBsnSetAuxCxnsRequest;
 import org.projectfloodlight.openflow.protocol.OFCapabilities;
 import org.projectfloodlight.openflow.protocol.OFControllerRole;
 import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
@@ -47,7 +42,6 @@ import org.projectfloodlight.openflow.protocol.OFRoleReply;
 import org.projectfloodlight.openflow.protocol.OFRoleRequest;
 import org.projectfloodlight.openflow.protocol.OFVersion;
 import org.projectfloodlight.openflow.types.DatapathId;
-import org.projectfloodlight.openflow.types.GenTableId;
 import org.projectfloodlight.openflow.types.OFAuxId;
 import org.projectfloodlight.openflow.types.OFPort;
 
diff --git a/src/test/java/net/floodlightcontroller/debugevent/CircularBufferTest.java b/src/test/java/net/floodlightcontroller/debugevent/CircularBufferTest.java
deleted file mode 100644
index 5c99aae3c972735485382105b085f50a7ae62fa4..0000000000000000000000000000000000000000
--- a/src/test/java/net/floodlightcontroller/debugevent/CircularBufferTest.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package net.floodlightcontroller.debugevent;
-
-import java.util.ArrayList;
-
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import net.floodlightcontroller.test.FloodlightTestCase;
-
-public class CircularBufferTest extends FloodlightTestCase {
-    /*CircularBuffer<String> cb;
-    protected static Logger log = LoggerFactory.getLogger(CircularBufferTest.class);
-
-    @Test
-    public void testCircularNature() {
-        cb = new CircularBuffer<String>(2);
-        cb.add("String 1");
-        assertEquals(1, cb.size());
-        cb.add("String 2");
-        assertEquals(2, cb.size());
-        cb.add("String 3");
-        assertEquals(2, cb.size());
-
-        for (String s : cb) {
-            assertEquals(false, s.contains("1"));
-        }
-    }
-
-    class Elems {
-        String str;
-        Boolean boo;
-
-        public Elems(String s,boolean b) {
-            this.str = s;
-            this.boo = b;
-        }
-    }
-
-    @Test
-    public void testAdd() {
-        CircularBuffer<Elems> eb = new CircularBuffer<Elems>(2);
-        Elems theone = new Elems("String 1", false);
-        Elems ret1 = eb.add(theone);
-        assertEquals(null, ret1);
-        Elems ret2 = eb.add(new Elems("String 2", true));
-        assertEquals(null, ret2);
-        Elems ret3 = eb.add(new Elems("String 3", true));
-        // We want to see if what is returned is a reference to the original object
-        // 'theone'. So we use  '==' to compare the references
-        assertEquals(true, ret3 == theone);
-        log.info("{} {}", ret3, theone);
-    }
-
-    @Test
-    public void testAddAll() {
-        CircularBuffer<Elems> eb = new CircularBuffer<Elems>(2);
-        Elems one = new Elems("String 1", false);
-        eb.add(one);
-        ArrayList<Elems> elist = new ArrayList<Elems>();
-        Elems two = new Elems("String 2", true);
-        elist.add(two);
-        Elems three = new Elems("String 3", true);
-        elist.add(three);
-        Elems four = new Elems("String 4", true);
-        elist.add(four);
-
-        ArrayList<Elems> retlist = eb.addAll(elist, 2);
-        assertEquals(null, retlist.get(0));
-        assertEquals(true, retlist.get(1) == one);
-        assertEquals(true, retlist.get(2) == four);
-
-        ArrayList<Elems> retlist2 = eb.addAll(retlist, 3);
-        assertEquals(null, retlist2.get(0));
-        assertEquals(true, retlist2.get(1) == two);
-        assertEquals(true, retlist2.get(2) == three);
-
-        ArrayList<Elems> retlist3 = eb.addAll(retlist2, 4);
-        assertEquals(retlist3, retlist2);
-
-    }
-*/
-}
diff --git a/src/test/java/net/floodlightcontroller/debugevent/DebugEventTest.java b/src/test/java/net/floodlightcontroller/debugevent/DebugEventTest.java
index 80d06bd5e15d68f132c7d8bbd5d3d3f5fd8d6ce6..0c296ef4bc60253961c084e37a14ff439d69be3a 100644
--- a/src/test/java/net/floodlightcontroller/debugevent/DebugEventTest.java
+++ b/src/test/java/net/floodlightcontroller/debugevent/DebugEventTest.java
@@ -11,13 +11,13 @@ import net.floodlightcontroller.debugevent.IDebugEventService.EventType;
 import net.floodlightcontroller.test.FloodlightTestCase;
 
 public class DebugEventTest extends FloodlightTestCase {
-   /* DebugEvent debugEvent;
+    Event debugEvent;
     protected static Logger log = LoggerFactory.getLogger(DebugEventTest.class);
 
     @Override
     @Before
     public void setUp() throws Exception {
-        debugEvent = new DebugEvent();
+        debugEvent = new Event(System.currentTimeMillis(), 0, "test", null, 0);
 
     }
 
@@ -25,8 +25,8 @@ public class DebugEventTest extends FloodlightTestCase {
     @Test
     public void testRegisterAndUpdateEvent() throws Exception {
         assertEquals(0, debugEvent.currentEvents.size());
-        IEventUpdater<SwitchyEvent> event1 = null;
-        IEventUpdater<PacketyEvent> event2 = null;
+        IEventCategory<SwitchyEvent> event1 = null;
+        IEventCategory<PacketyEvent> event2 = null;
         event1 = debugEvent.registerEvent("dbgevtest", "switchevent",
                                            "switchtest", EventType.ALWAYS_LOG,
                                            SwitchyEvent.class, 100);
@@ -97,5 +97,5 @@ public class DebugEventTest extends FloodlightTestCase {
             this.dpid = dpid;
             this.mac = mac;
         }
-    } */
+    } 
 }
diff --git a/src/test/java/net/floodlightcontroller/debugevent/EventTest.java b/src/test/java/net/floodlightcontroller/debugevent/EventTest.java
index f3bbc52089476511e098943e397ea8ab011e7524..8ee0661cf3d4e115c0c508411d941f29673aef5e 100644
--- a/src/test/java/net/floodlightcontroller/debugevent/EventTest.java
+++ b/src/test/java/net/floodlightcontroller/debugevent/EventTest.java
@@ -14,14 +14,13 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public class EventTest {
-   /* protected static Logger log = LoggerFactory.getLogger(EventTest.class);
+    protected static Logger log = LoggerFactory.getLogger(EventTest.class);
 
     @Test
     public void testFormat() {
         River r = new River("ganges", 42);
 
-        Event e = new Event(1L, 32, "test",
-                      new RiverEvent(1L, (short)10, true, "big river", 5, 4L, r));
+        Event e = new Event(1, 32, "test", new RiverEvent(1L, (short)10, true, "big river", 5, 4L, r), 0);
 
         Map<String, String> expected = new HashMap<String, String>();
         expected.put("dpid", "00:00:00:00:00:00:00:01");
@@ -38,10 +37,6 @@ public class EventTest {
                          e.getFormattedEvent(RiverEvent.class, "test").get(elem.getKey()));
 
         // ensure timestamp comes in ISO8601 time
-        assertEquals("1969-12-31T16:00:00.001-0800",
-                     e.getFormattedEvent(RiverEvent.class, "test2").get("Timestamp")); //1L
-        // change the timestamp - the call should return cached value
-        e.setTimestamp(2L);
         assertEquals("1969-12-31T16:00:00.001-0800",
                      e.getFormattedEvent(RiverEvent.class, "test2").get("Timestamp")); //1L
 
@@ -56,19 +51,6 @@ public class EventTest {
                      e.getFormattedEvent(null, "test").get("Error"));
     }
 
-    @Test
-    public void testIncorrectAnnotation() {
-        Event e = new Event(1L, 32, "test",
-                            new LakeEvent(199)); // dpid cannot be int
-        assertEquals("java.lang.Integer cannot be cast to java.lang.Long",
-                     e.getFormattedEvent(LakeEvent.class, "test").get("Error"));
-
-        Event e2 = new Event(1L, 32, "test",
-                            new LakeEvent2(199)); // mac cannot be int
-        assertEquals("java.lang.Integer cannot be cast to java.lang.Long",
-                     e2.getFormattedEvent(LakeEvent2.class, "test").get("Error"));
-    }
-
     class RiverEvent  {
         @EventColumn(name = "dpid", description = EventFieldType.DPID)
         long dpid;
@@ -145,5 +127,5 @@ public class EventTest {
         public LakeEvent2(int mac) {
             this.mac = mac;
         }
-    } */
+    } 
 }
diff --git a/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java b/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java
index 03479e44954f0f14aa9d4cb8022f001e253c8fa0..df61c28e34730ca935489e5f1d7ce5e7d251969f 100644
--- a/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java
+++ b/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java
@@ -53,7 +53,6 @@ import net.floodlightcontroller.core.FloodlightContext;
 import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IListener.Command;
 import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.internal.RoleManager;
 import net.floodlightcontroller.core.HARole;
 import net.floodlightcontroller.core.module.FloodlightModuleContext;
 import net.floodlightcontroller.core.module.FloodlightModuleException;
@@ -90,12 +89,15 @@ import net.floodlightcontroller.topology.ITopologyService;
 import org.easymock.EasyMock;
 import org.junit.Before;
 import org.junit.Test;
+import org.projectfloodlight.openflow.protocol.OFFactories;
 import org.projectfloodlight.openflow.protocol.OFPacketIn;
-import org.projectfloodlight.openflow.protocol.OFPacketInReason;
-import org.projectfloodlight.openflow.protocol.OFPortDesc;
+import org.projectfloodlight.openflow.protocol.OFPacketInReason;import org.projectfloodlight.openflow.protocol.OFVersion;
 import org.projectfloodlight.openflow.types.DatapathId;
+import org.projectfloodlight.openflow.types.IPv4Address;
+import org.projectfloodlight.openflow.types.MacAddress;
+import org.projectfloodlight.openflow.types.OFBufferId;
 import org.projectfloodlight.openflow.types.OFPort;
-import org.projectfloodlight.openflow.protocol.OFType;
+import org.projectfloodlight.openflow.types.VlanVid;
 import org.sdnplatform.sync.IClosableIterator;
 import org.sdnplatform.sync.IStoreClient;
 import org.sdnplatform.sync.ISyncService;
@@ -106,2933 +108,2925 @@ import org.slf4j.LoggerFactory;
 
 public class DeviceManagerImplTest extends FloodlightTestCase {
 
-    protected static Logger logger =
-            LoggerFactory.getLogger(DeviceManagerImplTest.class);
-
-    protected OFPacketIn testARPReplyPacketIn_1, testARPReplyPacketIn_2;
-    protected OFPacketIn testUDPPacketIn;
-    protected IPacket testARPReplyPacket_1, testARPReplyPacket_2;
-    protected Ethernet testUDPPacket;
-    protected byte[] testARPReplyPacket_1_Srld, testARPReplyPacket_2_Srld;
-    protected byte[] testUDPPacketSrld;
-    private MockSyncService syncService;
-    private IStoreClient<String, DeviceSyncRepresentation> storeClient;
-
-    DeviceManagerImpl deviceManager;
-    MemoryStorageSource storageSource;
-    FlowReconcileManager flowReconcileMgr;
-
-    private IOFSwitch makeSwitchMock(DatapathId id) {
-        IOFSwitch mockSwitch = createMock(IOFSwitch.class);
-        OFPort port = OFPort.of(1);
-        expect(mockSwitch.getId()).andReturn(id).anyTimes();
-        expect(mockSwitch.getId().toString()).andReturn(id.toString()).anyTimes();
-        expect(mockSwitch.getPort(OFPort.of(anyShort())).getPortNo()).andReturn(port).anyTimes();
-        return mockSwitch;
-    }
-
-    /*
-     * return an EasyMock ITopologyService that's setup so that it will
-     * answer all questions a device or device manager will ask
-     * (isAttachmentPointPort, etc.) in a way so that every port is a
-     * non-BD, attachment point port.
-     * The returned mock is still in record mode
-     */
-    private ITopologyService makeMockTopologyAllPortsAp() {
-        ITopologyService mockTopology = createMock(ITopologyService.class);
-        mockTopology.isAttachmentPointPort(DatapathId.of(anyLong()), OFPort.of(anyShort()));
-        expectLastCall().andReturn(true).anyTimes();
-        mockTopology.getL2DomainId(DatapathId.of(anyLong()));
-        expectLastCall().andReturn(1L).anyTimes();
-        mockTopology.isBroadcastDomainPort(DatapathId.of(anyLong()), OFPort.of(anyShort()));
-        expectLastCall().andReturn(false).anyTimes();
-        mockTopology.isConsistent(DatapathId.of(anyLong()), OFPort.of(anyShort()), DatapathId.of(anyLong()), OFPort.of(anyShort()));
-        expectLastCall().andReturn(false).anyTimes();
-        mockTopology.isInSameBroadcastDomain(DatapathId.of(anyLong()), OFPort.of(anyShort()), DatapathId.of(anyLong()), OFPort.of(anyShort()));
-        expectLastCall().andReturn(false).anyTimes();
-        return mockTopology;
-    }
-
-    @Override
-    @Before
-    public void setUp() throws Exception {
-        doSetUp(HARole.ACTIVE);
-    }
-
-    public void doSetUp(HARole initialRole) throws Exception {
-        super.setUp();
-
-        this.syncService = new MockSyncService();
-
-        FloodlightModuleContext fmc = new FloodlightModuleContext();
-        RestApiServer restApi = new RestApiServer();
-        MockThreadPoolService tp = new MockThreadPoolService();
-        ITopologyService topology = createMock(ITopologyService.class);
-        fmc.addService(IThreadPoolService.class, tp);
-        mockFloodlightProvider = getMockFloodlightProvider();
-        mockFloodlightProvider.setRole(initialRole, "");
-        
-
-        deviceManager = new DeviceManagerImpl();
-        flowReconcileMgr = new FlowReconcileManager();
-        DefaultEntityClassifier entityClassifier = new DefaultEntityClassifier();
-        fmc.addService(IDeviceService.class, deviceManager);
-        storageSource = new MemoryStorageSource();
-        fmc.addService(IStorageSourceService.class, storageSource);
-        fmc.addService(IFloodlightProviderService.class, mockFloodlightProvider);
-        fmc.addService(IRestApiService.class, restApi);
-        fmc.addService(IFlowReconcileService.class, flowReconcileMgr);
-        fmc.addService(IEntityClassifierService.class, entityClassifier);
-        fmc.addService(ITopologyService.class, topology);
-        fmc.addService(ISyncService.class, syncService);
-        tp.init(fmc);
-        restApi.init(fmc);
-        storageSource.init(fmc);
-        deviceManager.init(fmc);
-        flowReconcileMgr.init(fmc);
-        entityClassifier.init(fmc);
-        syncService.init(fmc);
-        storageSource.startUp(fmc);
-        deviceManager.startUp(fmc);
-        flowReconcileMgr.startUp(fmc);
-        tp.startUp(fmc);
-        entityClassifier.startUp(fmc);
-        syncService.startUp(fmc);
-
-        this.storeClient =
-                this.syncService.getStoreClient(DeviceManagerImpl.DEVICE_SYNC_STORE_NAME,
-                            String.class, DeviceSyncRepresentation.class);
-
-        reset(topology);
-        topology.addListener(deviceManager);
-        expectLastCall().anyTimes();
-        replay(topology);
-
-        IOFSwitch mockSwitch1 = makeSwitchMock(DatapathId.of(1L));
-        IOFSwitch mockSwitch10 = makeSwitchMock(DatapathId.of(10L));
-        IOFSwitch mockSwitch5 = makeSwitchMock(DatapathId.of(5L));
-        IOFSwitch mockSwitch50 = makeSwitchMock(DatapathId.of(50L));
-        Map<DatapathId, IOFSwitch> switches = new HashMap<DatapathId, IOFSwitch>();
-        switches.put(DatapathId.of(1L), mockSwitch1);
-        switches.put(DatapathId.of(10L), mockSwitch10);
-        switches.put(DatapathId.of(5L), mockSwitch5);
-        switches.put(DatapathId.of(50L), mockSwitch50);
-        mockFloodlightProvider.setSwitches(switches);
-
-        replay(mockSwitch1, mockSwitch5, mockSwitch10, mockSwitch50);
-
-        // Build our test packet
-        this.testARPReplyPacket_1 = new Ethernet()
-        .setSourceMACAddress("00:44:33:22:11:01")
-        .setDestinationMACAddress("00:11:22:33:44:55")
-        .setEtherType(Ethernet.TYPE_ARP)
-        .setVlanID((short)5)
-        .setPayload(
-                    new ARP()
-                    .setHardwareType(ARP.HW_TYPE_ETHERNET)
-                    .setProtocolType(ARP.PROTO_TYPE_IP)
-                    .setHardwareAddressLength((byte) 6)
-                    .setProtocolAddressLength((byte) 4)
-                    .setOpCode(ARP.OP_REPLY)
-                    .setSenderHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:01"))
-                    .setSenderProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.1"))
-                    .setTargetHardwareAddress(Ethernet.toMACAddress("00:11:22:33:44:55"))
-                    .setTargetProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.2")));
-        this.testARPReplyPacket_1_Srld = testARPReplyPacket_1.serialize();
-
-        // Another test packet with the same ARP payload as packet 1 but with
-        // a different source MAC. (i.e., sender MAC and source MAC differ)
-        this.testARPReplyPacket_2 = new Ethernet()
-        .setSourceMACAddress("00:99:88:77:66:55")
-        .setDestinationMACAddress("00:11:22:33:44:55")
-        .setEtherType(Ethernet.TYPE_ARP)
-        .setVlanID((short)5)
-        .setPayload(
-                    new ARP()
-                    .setHardwareType(ARP.HW_TYPE_ETHERNET)
-                    .setProtocolType(ARP.PROTO_TYPE_IP)
-                    .setHardwareAddressLength((byte) 6)
-                    .setProtocolAddressLength((byte) 4)
-                    .setOpCode(ARP.OP_REPLY)
-                    .setSenderHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:01"))
-                    .setSenderProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.1"))
-                    .setTargetHardwareAddress(Ethernet.toMACAddress("00:11:22:33:44:55"))
-                    .setTargetProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.2")));
-        this.testARPReplyPacket_2_Srld = testARPReplyPacket_2.serialize();
-
-        // This packet reverses the MACs and IP from testARPReplyPacket_1
-        this.testUDPPacket = (Ethernet) new Ethernet()
-        .setSourceMACAddress("00:11:22:33:44:55")
-        .setDestinationMACAddress("00:44:33:22:11:01")
-        .setEtherType(Ethernet.TYPE_IPv4)
-        .setVlanID((short)5)
-        .setPayload(
-                    new IPv4()
-                    .setTtl((byte) 128)
-                    .setSourceAddress("192.168.1.2")
-                    .setDestinationAddress("192.168.1.1")
-                    .setPayload(new UDP()
-                    .setSourcePort((short) 5000)
-                    .setDestinationPort((short) 5001)
-                    .setPayload(new Data(new byte[] {0x01}))));
-        updateUDPPacketIn();
-
-        // Build the PacketIn
-        this.testARPReplyPacketIn_1 = ((OFPacketIn) mockFloodlightProvider.
-                getOFMessageFactory().getMessage(OFType.PACKET_IN))
-                .setBufferId(-1)
-                .setInPort((short) 1)
-                .setPacketData(this.testARPReplyPacket_1_Srld)
-                .setReason(OFPacketInReason.NO_MATCH)
-                .setTotalLength((short) this.testARPReplyPacket_1_Srld.length);
-
-        // Build the PacketIn
-        this.testARPReplyPacketIn_2 = ((OFPacketIn) mockFloodlightProvider.
-                getOFMessageFactory().getMessage(OFType.PACKET_IN))
-                .setBufferId(-1)
-                .setInPort((short) 1)
-                .setPacketData(this.testARPReplyPacket_2_Srld)
-                .setReason(OFPacketInReason.NO_MATCH)
-                .setTotalLength((short) this.testARPReplyPacket_2_Srld.length);
-
-
-    }
-
-    /**
-     * Updates testUDPPacketIn and testUDPPacketSrld from testUDPPacket
-     * To be called after testUDPPacket has been mangled.
-     */
-    private void updateUDPPacketIn() {
-        this.testUDPPacketSrld = this.testUDPPacket.serialize();
-        // Build the PacketIn
-        this.testUDPPacketIn = ((OFPacketIn) mockFloodlightProvider.
-                getOFMessageFactory().getMessage(OFType.PACKET_IN))
-                .setBufferId(-1)
-                .setInPort((short) 3)
-                .setPacketData(this.testUDPPacketSrld)
-                .setReason(OFPacketInReason.NO_MATCH)
-                .setTotalLength((short) this.testUDPPacketSrld.length);
-    }
-
-    @Test
-    public void testLastSeen() throws Exception {
-        Calendar c = Calendar.getInstance();
-        Date d1 = c.getTime();
-        Entity entity1 = new Entity(1L, null, null, null, null, d1);
-        c.add(Calendar.SECOND, 1);
-        Entity entity2 = new Entity(1L, null, 1, null, null, c.getTime());
-
-        IDevice d = deviceManager.learnDeviceByEntity(entity2);
-        assertEquals(c.getTime(), d.getLastSeen());
-        d = deviceManager.learnDeviceByEntity(entity1);
-        assertEquals(c.getTime(), d.getLastSeen());
-
-        deviceManager.startUp(null);
-        d = deviceManager.learnDeviceByEntity(entity1);
-        assertEquals(d1, d.getLastSeen());
-        d = deviceManager.learnDeviceByEntity(entity2);
-        assertEquals(c.getTime(), d.getLastSeen());
-    }
-
-
-    @Test
-    public void testEntityLearning() throws Exception {
-        IDeviceListener mockListener =
-                createMock(IDeviceListener.class);
-        expect(mockListener.getName()).andReturn("mockListener").atLeastOnce();
-        expect(mockListener.isCallbackOrderingPostreq((String)anyObject(), (String)anyObject()))
-        .andReturn(false).atLeastOnce();
-        expect(mockListener.isCallbackOrderingPrereq((String)anyObject(), (String)anyObject()))
-        .andReturn(false).atLeastOnce();
-
-        replay(mockListener);
-        deviceManager.addListener(mockListener);
-        verify(mockListener);
-        reset(mockListener);
-        deviceManager.entityClassifier= new MockEntityClassifier();
-        deviceManager.startUp(null);
-
-        ITopologyService mockTopology = createMock(ITopologyService.class);
-        expect(mockTopology.getL2DomainId(anyLong())).
-        andReturn(1L).anyTimes();
-        expect(mockTopology.isBroadcastDomainPort(anyLong(), anyShort())).
-        andReturn(false).anyTimes();
-
-        expect(mockTopology.isAttachmentPointPort(anyLong(),
-                                                  anyShort())).andReturn(true).anyTimes();
-        expect(mockTopology.isConsistent(10L, (short)1, 10L, (short)1)).
-        andReturn(true).anyTimes();
-        expect(mockTopology.isConsistent(1L, (short)1, 1L, (short)1)).
-        andReturn(true).anyTimes();
-        expect(mockTopology.isConsistent(50L, (short)3, 50L, (short)3)).
-        andReturn(true).anyTimes();
-
-        Date topologyUpdateTime = new Date();
-        expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
-        anyTimes();
-
-        deviceManager.topology = mockTopology;
-
-        Entity entity1 = new Entity(1L, null, null, 1L, 1, new Date());
-        Entity entity2 = new Entity(1L, null, null, 10L, 1, new Date());
-        Entity entity3 = new Entity(1L, null, 1, 10L, 1, new Date());
-        Entity entity4 = new Entity(1L, null, 1, 1L, 1, new Date());
-        Entity entity5 = new Entity(2L, (short)4, 1, 5L, 2, new Date());
-        Entity entity6 = new Entity(2L, (short)4, 1, 50L, 3, new Date());
-        Entity entity7 = new Entity(2L, (short)4, 2, 50L, 3, new Date());
-
-        mockListener.deviceAdded(isA(IDevice.class));
-        replay(mockListener, mockTopology);
-
-        Device d1 = deviceManager.learnDeviceByEntity(entity1);
-        assertSame(d1, deviceManager.learnDeviceByEntity(entity1));
-        assertSame(d1, deviceManager.findDeviceByEntity(entity1));
-        assertEquals(DefaultEntityClassifier.entityClass ,
-                          d1.getEntityClass());
-        assertArrayEquals(new Short[] { -1 }, d1.getVlanId());
-        assertArrayEquals(new Integer[] { }, d1.getIPv4Addresses());
-
-        assertEquals(1, deviceManager.getAllDevices().size());
-        verify(mockListener);
-
-        reset(mockListener);
-        mockListener.deviceAdded(isA(IDevice.class));
-        replay(mockListener);
-
-        Device d2 = deviceManager.learnDeviceByEntity(entity2);
-        assertFalse(d1.equals(d2));
-        assertNotSame(d1, d2);
-        assertNotSame(d1.getDeviceKey(), d2.getDeviceKey());
-        assertEquals(MockEntityClassifier.testEC, d2.getEntityClass());
-        assertArrayEquals(new Short[] { -1 }, d2.getVlanId());
-        assertArrayEquals(new Integer[] { }, d2.getIPv4Addresses());
-
-        assertEquals(2, deviceManager.getAllDevices().size());
-        verify(mockListener);
-
-        reset(mockListener);
-        mockListener.deviceIPV4AddrChanged(isA(IDevice.class));
-        replay(mockListener);
-
-        Device d3 = deviceManager.learnDeviceByEntity(entity3);
-        assertNotSame(d2, d3);
-        assertEquals(d2.getDeviceKey(), d3.getDeviceKey());
-        assertEquals(MockEntityClassifier.testEC, d3.getEntityClass());
-        assertArrayEquals(new Integer[] { 1 },
-                          d3.getIPv4Addresses());
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(10L, 1) },
-                          d3.getAttachmentPoints());
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(10L, 1) },
-                          d3.getAttachmentPoints(true));
-        assertArrayEquals(new Short[] { -1 },
-                          d3.getVlanId());
-
-        assertEquals(2, deviceManager.getAllDevices().size());
-        verify(mockListener);
-
-        reset(mockListener);
-        mockListener.deviceIPV4AddrChanged(isA(IDevice.class));
-        replay(mockListener);
-
-        Device d4 = deviceManager.learnDeviceByEntity(entity4);
-        assertNotSame(d1, d4);
-        assertEquals(d1.getDeviceKey(), d4.getDeviceKey());
-        assertEquals(DefaultEntityClassifier.entityClass, d4.getEntityClass());
-        assertArrayEquals(new Integer[] { 1 },
-                          d4.getIPv4Addresses());
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1) },
-                          d4.getAttachmentPoints());
-        assertArrayEquals(new Short[] { -1 },
-                          d4.getVlanId());
-
-        assertEquals(2, deviceManager.getAllDevices().size());
-        verify(mockListener);
-
-        reset(mockListener);
-        mockListener.deviceAdded((isA(IDevice.class)));
-        replay(mockListener);
-
-        Device d5 = deviceManager.learnDeviceByEntity(entity5);
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(5L, 2) },
-                          d5.getAttachmentPoints());
-        assertArrayEquals(new Short[] { (short) 4 },
-                          d5.getVlanId());
-        assertEquals(2L, d5.getMACAddress());
-        assertEquals("00:00:00:00:00:02", d5.getMACAddressString());
-        verify(mockListener);
-
-        reset(mockListener);
-        mockListener.deviceAdded(isA(IDevice.class));
-        replay(mockListener);
-
-        Device d6 = deviceManager.learnDeviceByEntity(entity6);
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(50L, 3) },
-                          d6.getAttachmentPoints());
-        assertArrayEquals(new Short[] { (short) 4 },
-                          d6.getVlanId());
-
-        assertEquals(4, deviceManager.getAllDevices().size());
-        verify(mockListener);
-
-        reset(mockListener);
-        mockListener.deviceIPV4AddrChanged(isA(IDevice.class));
-        replay(mockListener);
-
-        Device d7 = deviceManager.learnDeviceByEntity(entity7);
-        assertNotSame(d6, d7);
-        assertEquals(d6.getDeviceKey(), d7.getDeviceKey());
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(50L, 3) },
-                          d7.getAttachmentPoints());
-        assertArrayEquals(new Short[] { (short) 4 },
-                          d7.getVlanId());
-
-        assertEquals(4, deviceManager.getAllDevices().size());
-        verify(mockListener);
-
-
-        reset(mockListener);
-        replay(mockListener);
-
-        reset(deviceManager.topology);
-        deviceManager.topology.addListener(deviceManager);
-        expectLastCall().times(1);
-        replay(deviceManager.topology);
-
-        deviceManager.entityClassifier = new MockEntityClassifierMac();
-        deviceManager.startUp(null);
-        Entity entityNoClass = new Entity(5L, (short)1, 5, -1L, 1, new Date());
-        assertEquals(null, deviceManager.learnDeviceByEntity(entityNoClass));
-
-        verify(mockListener);
-    }
-
-
-    private void doTestEntityOrdering(boolean computeInsertionPoint) throws Exception {
-        Entity e = new Entity(10L, null, null, null, null, null);
-        IEntityClass ec = createNiceMock(IEntityClass.class);
-        Device d = new Device(deviceManager, 1L, e, ec);
-
-        int expectedLength = 1;
-        Long[] macs = new Long[] {  5L,  // new first element
-                                   15L,  // new last element
-                                    7L,  // insert in middle
-                                   12L,  // insert in middle
-                                    6L,  // insert at idx 1
-                                   14L,  // insert at idx length-2
-                                    1L,
-                                   20L
-                                  };
-
-        for (Long mac: macs) {
-            e = new Entity(mac, null, null, null, null, null);
-            int insertionPoint;
-            if (computeInsertionPoint) {
-                insertionPoint = -(Arrays.binarySearch(d.entities, e)+1);
-            } else {
-                insertionPoint = -1;
-            }
-            d = deviceManager.allocateDevice(d, e, insertionPoint);
-            expectedLength++;
-            assertEquals(expectedLength, d.entities.length);
-            for (int i = 0; i < d.entities.length-1; i++)
-                assertEquals(-1, d.entities[i].compareTo(d.entities[i+1]));
-        }
-    }
-
-    @Test
-    public void testEntityOrderingExternal() throws Exception {
-        doTestEntityOrdering(true);
-    }
-
-    @Test
-    public void testEntityOrderingInternal() throws Exception {
-        doTestEntityOrdering(false);
-    }
-
-    @Test
-    public void testAttachmentPointLearning() throws Exception {
-        IDeviceListener mockListener =
-                createMock(IDeviceListener.class);
-        expect(mockListener.getName()).andReturn("mockListener").atLeastOnce();
-        expect(mockListener.isCallbackOrderingPostreq((String)anyObject(), (String)anyObject()))
-        .andReturn(false).atLeastOnce();
-        expect(mockListener.isCallbackOrderingPrereq((String)anyObject(), (String)anyObject()))
-        .andReturn(false).atLeastOnce();
-
-        replay(mockListener);
-        deviceManager.addListener(mockListener);
-        verify(mockListener);
-        reset(mockListener);
-
-        ITopologyService mockTopology = createMock(ITopologyService.class);
-        expect(mockTopology.getL2DomainId(1L)).
-        andReturn(1L).anyTimes();
-        expect(mockTopology.getL2DomainId(5L)).
-        andReturn(1L).anyTimes();
-        expect(mockTopology.getL2DomainId(10L)).
-        andReturn(10L).anyTimes();
-        expect(mockTopology.getL2DomainId(50L)).
-        andReturn(10L).anyTimes();
-        expect(mockTopology.isBroadcastDomainPort(anyLong(), anyShort())).
-        andReturn(false).anyTimes();
-        expect(mockTopology.isInSameBroadcastDomain(anyLong(), anyShort(),
-                                                    anyLong(), anyShort())).andReturn(false).anyTimes();
-
-        expect(mockTopology.isAttachmentPointPort(anyLong(),
-                                                  anyShort())).andReturn(true).anyTimes();
-        expect(mockTopology.isConsistent(1L, (short)1, 5L, (short)1)).
-        andReturn(false).anyTimes();
-        expect(mockTopology.isConsistent(5L, (short)1, 10L, (short)1)).
-        andReturn(false).anyTimes();
-        expect(mockTopology.isConsistent(10L, (short)1, 50L, (short)1)).
-        andReturn(false).anyTimes();
-
-        Date topologyUpdateTime = new Date();
-        expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
-        anyTimes();
-
-        replay(mockTopology);
-
-        deviceManager.topology = mockTopology;
-
-        Calendar c = Calendar.getInstance();
-        Entity entity1 = new Entity(1L, null, 1, 1L, 1, c.getTime());
-        Entity entity0 = new Entity(1L, null, null, null, null, c.getTime());
-        c.add(Calendar.SECOND, 1);
-        Entity entity2 = new Entity(1L, null, null, 5L, 1, c.getTime());
-        c.add(Calendar.SECOND, 1);
-        Entity entity3 = new Entity(1L, null, null, 10L, 1, c.getTime());
-        c.add(Calendar.SECOND, 1);
-        Entity entity4 = new Entity(1L, null, null, 50L, 1, c.getTime());
-
-        IDevice d;
-        SwitchPort[] aps;
-        Integer[] ips;
-
-        mockListener.deviceAdded(isA(IDevice.class));
-        replay(mockListener);
-
-        deviceManager.learnDeviceByEntity(entity1);
-        d = deviceManager.learnDeviceByEntity(entity0);
-        assertEquals(1, deviceManager.getAllDevices().size());
-        aps = d.getAttachmentPoints();
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1) }, aps);
-        ips = d.getIPv4Addresses();
-        assertArrayEquals(new Integer[] { 1 }, ips);
-        verify(mockListener);
-
-        reset(mockListener);
-        mockListener.deviceMoved((isA(IDevice.class)));
-        replay(mockListener);
-
-        d = deviceManager.learnDeviceByEntity(entity2);
-        assertEquals(1, deviceManager.getAllDevices().size());
-        aps = d.getAttachmentPoints();
-
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(5L, 1) }, aps);
-        ips = d.getIPv4Addresses();
-        assertArrayEquals(new Integer[] { 1 }, ips);
-        verify(mockListener);
-
-        reset(mockListener);
-        mockListener.deviceMoved((isA(IDevice.class)));
-        replay(mockListener);
-
-        d = deviceManager.learnDeviceByEntity(entity3);
-        assertEquals(1, deviceManager.getAllDevices().size());
-        aps = d.getAttachmentPoints();
-        assertArrayEquals(new SwitchPort[] {new SwitchPort(5L, 1), new SwitchPort(10L, 1)}, aps);
-        ips = d.getIPv4Addresses();
-        assertArrayEquals(new Integer[] { 1 }, ips);
-        verify(mockListener);
-
-        reset(mockListener);
-        mockListener.deviceMoved((isA(IDevice.class)));
-        replay(mockListener);
-
-        d = deviceManager.learnDeviceByEntity(entity4);
-        assertEquals(1, deviceManager.getAllDevices().size());
-        aps = d.getAttachmentPoints();
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(5L, 1),
-                                             new SwitchPort(50L, 1) }, aps);
-        ips = d.getIPv4Addresses();
-        assertArrayEquals(new Integer[] { 1 }, ips);
-        verify(mockListener);
-    }
-
-    /**
-     * In this test, a device is moved from attachment point (1,1) to (5,1)
-     * and then moved back to (1,1) within 30 seconds.  Both the moves should
-     * generate device moved notification.
-     * @throws Exception
-     */
-    @Test
-    public void testAttachmentPointMovingBack() throws Exception {
-        IDeviceListener mockListener =
-                createMock(IDeviceListener.class);
-        expect(mockListener.getName()).andReturn("mockListener").atLeastOnce();
-        expect(mockListener.isCallbackOrderingPostreq((String)anyObject(), (String)anyObject()))
-        .andReturn(false).atLeastOnce();
-        expect(mockListener.isCallbackOrderingPrereq((String)anyObject(), (String)anyObject()))
-        .andReturn(false).atLeastOnce();
-
-        replay(mockListener);
-        deviceManager.addListener(mockListener);
-        verify(mockListener);
-        reset(mockListener);
-
-        ITopologyService mockTopology = createMock(ITopologyService.class);
-        expect(mockTopology.getL2DomainId(1L)).
-        andReturn(1L).anyTimes();
-        expect(mockTopology.getL2DomainId(5L)).
-        andReturn(1L).anyTimes();
-        expect(mockTopology.isBroadcastDomainPort(anyLong(), anyShort())).
-        andReturn(false).anyTimes();
-        expect(mockTopology.isInSameBroadcastDomain(anyLong(), anyShort(),
-                                                    anyLong(), anyShort()))
-                                                    .andReturn(false).anyTimes();
-
-        expect(mockTopology.isAttachmentPointPort(anyLong(),
-                                                  anyShort())).andReturn(true).anyTimes();
-        expect(mockTopology.isConsistent(1L, (short)1, 5L, (short)1)).
-        andReturn(false).anyTimes();
-
-        Date topologyUpdateTime = new Date();
-        expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
-        anyTimes();
-
-        replay(mockTopology);
-
-        deviceManager.topology = mockTopology;
-
-        Calendar c = Calendar.getInstance();
-        Entity entity1 = new Entity(1L, null, null, 1L, 1, c.getTime());
-        c.add(Calendar.SECOND, 1);
-        Entity entity2 = new Entity(1L, null, null, 5L, 1, c.getTime());
-        c.add(Calendar.SECOND, 1);
-        Entity entity3 = new Entity(1L, null, null, 1L, 1, c.getTime());
-        c.add(Calendar.SECOND, 1);
-        Entity entity4 = new Entity(1L, null, null, 5L, 1, c.getTime());
-
-        IDevice d;
-        SwitchPort[] aps;
-
-        mockListener.deviceAdded(isA(IDevice.class));
-        replay(mockListener);
-
-        d = deviceManager.learnDeviceByEntity(entity1);
-        assertEquals(1, deviceManager.getAllDevices().size());
-        aps = d.getAttachmentPoints();
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1) }, aps);
-        verify(mockListener);
-
-        reset(mockListener);
-        mockListener.deviceMoved((isA(IDevice.class)));
-        replay(mockListener);
-
-        d = deviceManager.learnDeviceByEntity(entity2);
-        assertEquals(1, deviceManager.getAllDevices().size());
-        aps = d.getAttachmentPoints();
-
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(5L, 1) }, aps);
-        verify(mockListener);
-
-        reset(mockListener);
-        mockListener.deviceMoved((isA(IDevice.class)));
-        replay(mockListener);
-
-        d = deviceManager.learnDeviceByEntity(entity3);
-        assertEquals(1, deviceManager.getAllDevices().size());
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1),
-                new SwitchPort(5L, 1, ErrorStatus.DUPLICATE_DEVICE)},
-                                              d.getAttachmentPoints(true));
-        verify(mockListener);
-
-        // Generate a packet-in again from 5,1 and ensure that it doesn't
-        // create a device moved event.
-        reset(mockListener);
-        replay(mockListener);
-        d = deviceManager.learnDeviceByEntity(entity4);
-        assertEquals(1, deviceManager.getAllDevices().size());
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1),
-                new SwitchPort(5L, 1, ErrorStatus.DUPLICATE_DEVICE)},
-                                              d.getAttachmentPoints(true));
-        verify(mockListener);
-    }
-
-    private void verifyEntityArray(Entity[] expected, Device d) {
-        Arrays.sort(expected);
-        assertArrayEquals(expected, d.entities);
-    }
-
-    @Test
-    public void testNoLearningOnInternalPorts() throws Exception {
-        IDeviceListener mockListener =
-                createMock(IDeviceListener.class);
-
-        expect(mockListener.getName()).andReturn("mockListener").anyTimes();
-        expect(mockListener.isCallbackOrderingPostreq((String)anyObject(), (String)anyObject()))
-        .andReturn(false).atLeastOnce();
-        expect(mockListener.isCallbackOrderingPrereq((String)anyObject(), (String)anyObject()))
-        .andReturn(false).atLeastOnce();
-
-        replay(mockListener);
-        deviceManager.addListener(mockListener);
-        verify(mockListener);
-        reset(mockListener);
-
-        ITopologyService mockTopology = createMock(ITopologyService.class);
-        expect(mockTopology.getL2DomainId(1L)).
-        andReturn(1L).anyTimes();
-        expect(mockTopology.getL2DomainId(2L)).
-        andReturn(1L).anyTimes();
-        expect(mockTopology.getL2DomainId(3L)).
-        andReturn(1L).anyTimes();
-        expect(mockTopology.getL2DomainId(4L)).
-        andReturn(1L).anyTimes();
-        expect(mockTopology.isBroadcastDomainPort(anyLong(), anyShort()))
-                .andReturn(false).anyTimes();
-        expect(mockTopology.isInSameBroadcastDomain(anyLong(), anyShort(),
-                                                    anyLong(), anyShort()))
-                .andReturn(false).anyTimes();
-
-        expect(mockTopology.isAttachmentPointPort(or(eq(1L), eq(3L)), anyShort()))
-                .andReturn(true).anyTimes();
-        // Switches 2 and 4 have only internal ports
-        expect(mockTopology.isAttachmentPointPort(or(eq(2L), eq(4L)), anyShort()))
-                .andReturn(false).anyTimes();
-
-        expect(mockTopology.isConsistent(1L, (short)1, 3L, (short)1))
-                .andReturn(false).once();
-
-        Date topologyUpdateTime = new Date();
-        expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
-        anyTimes();
-
-        replay(mockTopology);
-
-        deviceManager.topology = mockTopology;
-
-        Calendar c = Calendar.getInstance();
-        Entity entity1 = new Entity(1L, null, 1, 1L, 1, c.getTime());
-        c.add(Calendar.SECOND, 1);
-        Entity entity2 = new Entity(1L, null, 2, 2L, 1, c.getTime());
-        c.add(Calendar.SECOND, 1);
-        Entity entity3 = new Entity(1L, null, 3, 3L, 1, c.getTime());
-        c.add(Calendar.SECOND, 1);
-        Entity entity4 = new Entity(1L, null, 4, 4L, 1, c.getTime());
-
-        IDevice d;
-        SwitchPort[] aps;
-        Integer[] ips;
-
-        mockListener.deviceAdded(isA(IDevice.class));
-        expectLastCall().once();
-        replay(mockListener);
-
-        // cannot learn device internal ports
-        d = deviceManager.learnDeviceByEntity(entity2);
-        assertNull(d);
-        d = deviceManager.learnDeviceByEntity(entity4);
-        assertNull(d);
-
-        d = deviceManager.learnDeviceByEntity(entity1);
-        assertEquals(1, deviceManager.getAllDevices().size());
-        aps = d.getAttachmentPoints();
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1) }, aps);
-        verifyEntityArray(new Entity[] { entity1 } , (Device)d);
-        ips = d.getIPv4Addresses();
-        assertArrayEquals(new Integer[] { 1 }, ips);
-        verify(mockListener);
-
-        reset(mockListener);
-        replay(mockListener);
-
-        // don't learn
-        d = deviceManager.learnDeviceByEntity(entity2);
-        assertEquals(1, deviceManager.getAllDevices().size());
-        aps = d.getAttachmentPoints();
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1) }, aps);
-        verifyEntityArray(new Entity[] { entity1 } , (Device)d);
-        ips = d.getIPv4Addresses();
-        assertArrayEquals(new Integer[] { 1 }, ips);
-        verify(mockListener);
-
-        reset(mockListener);
-        mockListener.deviceMoved(isA(IDevice.class));
-        mockListener.deviceIPV4AddrChanged(isA(IDevice.class));
-        replay(mockListener);
-
-        // learn
-        d = deviceManager.learnDeviceByEntity(entity3);
-        assertEquals(1, deviceManager.getAllDevices().size());
-        aps = d.getAttachmentPoints();
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(3L, 1) }, aps);
-        verifyEntityArray(new Entity[] { entity1, entity3 } , (Device)d);
-        ips = d.getIPv4Addresses();
-        Arrays.sort(ips);
-        assertArrayEquals(new Integer[] { 1, 3 }, ips);
-        verify(mockListener);
-
-        reset(mockListener);
-        replay(mockListener);
-
-        // don't learn
-        d = deviceManager.learnDeviceByEntity(entity4);
-        assertEquals(1, deviceManager.getAllDevices().size());
-        aps = d.getAttachmentPoints();
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(3L, 1) }, aps);
-        verifyEntityArray(new Entity[] { entity1, entity3 } , (Device)d);
-        ips = d.getIPv4Addresses();
-        Arrays.sort(ips);
-        assertArrayEquals(new Integer[] { 1, 3 }, ips);
-        verify(mockListener);
-    }
-
-    @Test
-    public void testAttachmentPointSuppression() throws Exception {
-        IDeviceListener mockListener =
-                createMock(IDeviceListener.class);
-
-        expect(mockListener.getName()).andReturn("mockListener").anyTimes();
-        expect(mockListener.isCallbackOrderingPostreq((String)anyObject(), (String)anyObject()))
-        .andReturn(false).atLeastOnce();
-        expect(mockListener.isCallbackOrderingPrereq((String)anyObject(), (String)anyObject()))
-        .andReturn(false).atLeastOnce();
-
-        replay(mockListener);
-        deviceManager.addListener(mockListener);
-        verify(mockListener);
-        reset(mockListener);
-
-        ITopologyService mockTopology = createMock(ITopologyService.class);
-        expect(mockTopology.getL2DomainId(1L)).
-        andReturn(1L).anyTimes();
-        expect(mockTopology.getL2DomainId(5L)).
-        andReturn(1L).anyTimes();
-        expect(mockTopology.getL2DomainId(10L)).
-        andReturn(10L).anyTimes();
-        expect(mockTopology.getL2DomainId(50L)).
-        andReturn(10L).anyTimes();
-        expect(mockTopology.isBroadcastDomainPort(anyLong(), anyShort()))
-                .andReturn(false).anyTimes();
-        expect(mockTopology.isInSameBroadcastDomain(anyLong(), anyShort(),
-                                                    anyLong(), anyShort()))
-                .andReturn(false).anyTimes();
-
-        expect(mockTopology.isAttachmentPointPort(anyLong(), anyShort()))
-                .andReturn(true).anyTimes();
-        expect(mockTopology.isConsistent(5L, (short)1, 50L, (short)1))
-                .andReturn(false).anyTimes();
-
-        Date topologyUpdateTime = new Date();
-        expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
-        anyTimes();
-
-        replay(mockTopology);
-
-        deviceManager.topology = mockTopology;
-        // suppress (1L, 1) and (10L, 1)
-        deviceManager.addSuppressAPs(1L, (short)1);
-        deviceManager.addSuppressAPs(10L, (short)1);
-
-        Calendar c = Calendar.getInstance();
-        Entity entity0 = new Entity(1L, null, null, null, null, c.getTime());
-        // No attachment point should be learnt on 1L, 1
-        Entity entity1 = new Entity(1L, null, 1, 1L, 1, c.getTime());
-        c.add(Calendar.SECOND, 1);
-        Entity entity2 = new Entity(1L, null, 1, 5L, 1, c.getTime());
-        c.add(Calendar.SECOND, 1);
-        Entity entity3 = new Entity(1L, null, null, 10L, 1, c.getTime());
-        c.add(Calendar.SECOND, 1);
-        Entity entity4 = new Entity(1L, null, null, 50L, 1, c.getTime());
-
-        IDevice d;
-        SwitchPort[] aps;
-        Integer[] ips;
-
-        mockListener.deviceAdded(isA(IDevice.class));
-        mockListener.deviceIPV4AddrChanged((isA(IDevice.class)));
-        replay(mockListener);
-
-        // TODO: we currently do learn entities on suppressed APs
-        // // cannot learn device on suppressed AP
-        // d = deviceManager.learnDeviceByEntity(entity1);
-        // assertNull(d);
-
-        deviceManager.learnDeviceByEntity(entity0);
-        d = deviceManager.learnDeviceByEntity(entity1);
-        assertEquals(1, deviceManager.getAllDevices().size());
-        aps = d.getAttachmentPoints();
-        assertEquals(aps.length, 0);
-        verifyEntityArray(new Entity[] { entity0, entity1} , (Device)d);
-        ips = d.getIPv4Addresses();
-        assertArrayEquals(new Integer[] { 1 }, ips);
-        verify(mockListener);
-
-        reset(mockListener);
-        mockListener.deviceMoved((isA(IDevice.class)));
-        //mockListener.deviceIPV4AddrChanged((isA(IDevice.class)));
-        replay(mockListener);
-        d = deviceManager.learnDeviceByEntity(entity2);
-        assertEquals(1, deviceManager.getAllDevices().size());
-        aps = d.getAttachmentPoints();
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(5L, 1) }, aps);
-        verifyEntityArray(new Entity[] { entity0, entity1, entity2 } , (Device)d);
-        ips = d.getIPv4Addresses();
-        assertArrayEquals(new Integer[] { 1 }, ips);
-        verify(mockListener);
-
-        reset(mockListener);
-        replay(mockListener);
-
-        d = deviceManager.learnDeviceByEntity(entity3);
-        assertEquals(1, deviceManager.getAllDevices().size());
-        aps = d.getAttachmentPoints();
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(5L, 1) }, aps);
-        verifyEntityArray(new Entity[] { entity0, entity1, entity2, entity3 } , (Device)d);
-        ips = d.getIPv4Addresses();
-        assertArrayEquals(new Integer[] { 1 }, ips);
-        verify(mockListener);
-
-        reset(mockListener);
-        mockListener.deviceMoved((isA(IDevice.class)));
-        replay(mockListener);
-
-        d = deviceManager.learnDeviceByEntity(entity4);
-        assertEquals(1, deviceManager.getAllDevices().size());
-        aps = d.getAttachmentPoints();
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(5L, 1),
-                                             new SwitchPort(50L, 1) }, aps);
-        verifyEntityArray(new Entity[] { entity0, entity1, entity2, entity3, entity4} , (Device)d);
-        ips = d.getIPv4Addresses();
-        assertArrayEquals(new Integer[] { 1 }, ips);
-        verify(mockListener);
-    }
-
-    @Test
-    public void testBDAttachmentPointLearning() throws Exception {
-        ITopologyService mockTopology = createMock(ITopologyService.class);
-        expect(mockTopology.getL2DomainId(anyLong())).
-        andReturn(1L).anyTimes();
-        expect(mockTopology.isAttachmentPointPort(anyLong(), anyShort())).
-        andReturn(true).anyTimes();
-        expect(mockTopology.isBroadcastDomainPort(1L, (short)1)).
-        andReturn(false).anyTimes();
-        expect(mockTopology.isBroadcastDomainPort(1L, (short)2)).
-        andReturn(true).anyTimes();
-        expect(mockTopology.isInSameBroadcastDomain(1L, (short)1,
-                                                    1L, (short)2)).andReturn(true).anyTimes();
-        expect(mockTopology.isInSameBroadcastDomain(1L, (short)2,
-                                                    1L, (short)1)).andReturn(true).anyTimes();
-        expect(mockTopology.isConsistent(anyLong(), anyShort(), anyLong(), anyShort())).andReturn(false).anyTimes();
-
-        Date topologyUpdateTime = new Date();
-        expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
-        anyTimes();
-
-        replay(mockTopology);
-
-        deviceManager.topology = mockTopology;
-
-        Calendar c = Calendar.getInstance();
-        Entity entity1 = new Entity(1L, null, 1, 1L, 1, c.getTime());
-        c.add(Calendar.MILLISECOND,
-              (int)AttachmentPoint.OPENFLOW_TO_EXTERNAL_TIMEOUT/ 2);
-        Entity entity2 = new Entity(1L, null, null, 1L, 2, c.getTime());
-        c.add(Calendar.MILLISECOND,
-              (int)AttachmentPoint.OPENFLOW_TO_EXTERNAL_TIMEOUT / 2 + 1);
-        Entity entity3 = new Entity(1L, null, null, 1L, 2, c.getTime());
-
-        IDevice d;
-        SwitchPort[] aps;
-
-        d = deviceManager.learnDeviceByEntity(entity1);
-        assertEquals(1, deviceManager.getAllDevices().size());
-        aps = d.getAttachmentPoints();
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1) }, aps);
-
-        // this timestamp is too soon; don't switch
-        d = deviceManager.learnDeviceByEntity(entity2);
-        assertEquals(1, deviceManager.getAllDevices().size());
-        aps = d.getAttachmentPoints();
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1) }, aps);
-
-        // it should switch when we learn with a timestamp after the
-        // timeout
-        d = deviceManager.learnDeviceByEntity(entity3);
-        assertEquals(1, deviceManager.getAllDevices().size());
-        aps = d.getAttachmentPoints();
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 2) }, aps);
-    }
-
-    /**
-     * This test verifies that the learning behavior on OFPP_LOCAL ports.
-     * Once a host is learned on OFPP_LOCAL, it is allowed to move only from
-     * one OFPP_LOCAL to another OFPP_LOCAL port.
-     * @throws Exception
-     */
-    @Test
-    public void testLOCALAttachmentPointLearning() throws Exception {
-        ITopologyService mockTopology = createMock(ITopologyService.class);
-        expect(mockTopology.getL2DomainId(anyLong())).
-        andReturn(1L).anyTimes();
-        expect(mockTopology.isAttachmentPointPort(anyLong(), anyShort())).
-        andReturn(true).anyTimes();
-        expect(mockTopology.isBroadcastDomainPort(1L, (short)1)).
-        andReturn(false).anyTimes();
-        expect(mockTopology.isBroadcastDomainPort(1L, OFPort.OFPP_LOCAL.getValue())).
-        andReturn(false).anyTimes();
-        expect(mockTopology.isBroadcastDomainPort(1L, (short)2)).
-        andReturn(true).anyTimes();
-        expect(mockTopology.isInSameBroadcastDomain(1L, (short)1,
-                                                    1L, OFPort.OFPP_LOCAL.getValue())).andReturn(true).anyTimes();
-        expect(mockTopology.isInSameBroadcastDomain(1L, OFPort.OFPP_LOCAL.getValue(),
-                                                    1L, (short)2)).andReturn(true).anyTimes();
-        expect(mockTopology.isInSameBroadcastDomain(1L, (short)2,
-                                                    1L, OFPort.OFPP_LOCAL.getValue())).andReturn(true).anyTimes();
-        expect(mockTopology.isConsistent(anyLong(), anyShort(), anyLong(), anyShort())).andReturn(false).anyTimes();
-
-        Date topologyUpdateTime = new Date();
-        expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
-        anyTimes();
-
-        replay(mockTopology);
-
-        deviceManager.topology = mockTopology;
-
-        Calendar c = Calendar.getInstance();
-        Entity entity1 = new Entity(1L, null, 1, 1L, 1, c.getTime());
-        c.add(Calendar.MILLISECOND,
-              (int)AttachmentPoint.OPENFLOW_TO_EXTERNAL_TIMEOUT/ 2);
-        Entity entity2 = new Entity(1L, null, null, 1L, (int)OFPort.OFPP_LOCAL.getValue(), c.getTime());
-        c.add(Calendar.MILLISECOND,
-              (int)AttachmentPoint.OPENFLOW_TO_EXTERNAL_TIMEOUT + 1);
-        Entity entity3 = new Entity(1L, null, null, 1L, 2, c.getTime());
-
-        IDevice d;
-        SwitchPort[] aps;
-
-        d = deviceManager.learnDeviceByEntity(entity1);
-        assertEquals(1, deviceManager.getAllDevices().size());
-        aps = d.getAttachmentPoints();
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1) }, aps);
-
-        // Ensure that the attachment point changes to OFPP_LOCAL
-        d = deviceManager.learnDeviceByEntity(entity2);
-        assertEquals(1, deviceManager.getAllDevices().size());
-        aps = d.getAttachmentPoints();
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, OFPort.OFPP_LOCAL.getValue()) }, aps);
-
-        // Even though the new attachment point is consistent with old
-        // and the time has elapsed, OFPP_LOCAL attachment point should
-        // be maintained.
-        d = deviceManager.learnDeviceByEntity(entity3);
-        assertEquals(1, deviceManager.getAllDevices().size());
-        aps = d.getAttachmentPoints();
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, OFPort.OFPP_LOCAL.getValue()) }, aps);
-    }
-
-    private static void
-            mockTopologyForPacketInTests(ITopologyService mockTopology) {
-        expect(mockTopology.isAttachmentPointPort(anyLong(),
-                anyShort())).
-                andReturn(true).
-                anyTimes();
-        expect(mockTopology.isConsistent(EasyMock.anyLong(),
-                EasyMock.anyShort(),
-                EasyMock.anyLong(),
-                EasyMock.anyShort())).andReturn(false).
-                anyTimes();
-        expect(mockTopology.isBroadcastDomainPort(EasyMock.anyLong(),
-                EasyMock.anyShort()))
-                .andReturn(false)
-                .anyTimes();
-        expect(mockTopology.getL2DomainId(anyLong())).andReturn(1L).anyTimes();
-        expect(mockTopology.isInSameBroadcastDomain(anyLong(),
-                                                    anyShort(),
-                                                    anyLong(),
-                                                    anyShort()))
-                .andReturn(false).anyTimes();
-
-    }
-
-    private Command dispatchPacketIn(long swId, OFPacketIn pi,
-                                     FloodlightContext cntx) {
-        IOFSwitch sw = mockFloodlightProvider.getSwitch(swId);
-        Ethernet eth = new Ethernet();
-        eth.deserialize(pi.getPacketData(), 0, pi.getPacketData().length);
-        IFloodlightProviderService.bcStore.put(cntx,
-                IFloodlightProviderService.CONTEXT_PI_PAYLOAD,
-                eth);
-        return deviceManager.receive(sw, pi, cntx);
-    }
-
-    /**
-     * Verify that the given device exactly matches the given fields. E.g.,
-     * if ip is not null we expect the device to have exactly one IP address.
-     * swId and port are the attachment point port.
-     * Vlan and ip are optional all other fields must be specified.
-     * @return
-     */
-    private static void verifyDevice(IDevice d, long mac, Short vlan, Integer ip,
-                                long swId, int port) {
-        assertNotNull(d);
-        assertEquals(mac, d.getMACAddress());
-        if (vlan == null)
-            assertArrayEquals(new Short[0], d.getVlanId());
-        else
-            assertArrayEquals(new Short[] { vlan }, d.getVlanId());
-
-        if (ip == null)
-            assertArrayEquals(new Integer[0], d.getIPv4Addresses());
-        else
-            assertArrayEquals(new Integer[] { ip }, d.getIPv4Addresses());
-
-        SwitchPort expectedAp = new SwitchPort(swId, port);
-        assertArrayEquals(new SwitchPort[] { expectedAp },
-                          d.getAttachmentPoints());
-    }
-
-
-    @Test
-    public void testPacketInBasic() throws Exception {
-        byte[] deviceMac =
-                ((Ethernet)this.testARPReplyPacket_1).getSourceMACAddress();
-        OFPacketIn packetIn = testARPReplyPacketIn_1;
-        Integer ipaddr = IPv4.toIPv4Address("192.168.1.1");
-
-        // Mock up our expected behavior
-        ITopologyService mockTopology = createMock(ITopologyService.class);
-        deviceManager.topology = mockTopology;
-        mockTopologyForPacketInTests(mockTopology);
-        replay(mockTopology);
-
-        FloodlightContext cntx = new FloodlightContext();
-        Command cmd = dispatchPacketIn(1L, packetIn, cntx);
-        verify(mockTopology);
-        assertEquals(Command.CONTINUE, cmd);
-        // Verify the device
-        Device rdevice = (Device)
-                deviceManager.findDevice(Ethernet.toLong(deviceMac),
-                        (short)5, null, null, null);
-        verifyDevice(rdevice, Ethernet.toLong(deviceMac),
-                     (short)5, ipaddr, 1L, 1);
-        IDevice cntxSrcDev = IDeviceService.fcStore.get(cntx,
-                IDeviceService.CONTEXT_SRC_DEVICE);
-        assertEquals(rdevice, cntxSrcDev);
-        IDevice cntxDstDev = IDeviceService.fcStore.get(cntx,
-                IDeviceService.CONTEXT_DST_DEVICE);
-        assertNull(cntxDstDev);
-
-        Device result = null;
-        Iterator<? extends IDevice> dstiter =
-                deviceManager.queryDevices(null, null, ipaddr,
-                        null, null);
-        if (dstiter.hasNext()) {
-            result = (Device)dstiter.next();
-        }
-        assertFalse("There shouldn't be more than 1 device", dstiter.hasNext());
-        assertEquals(rdevice, result);
-
-
-        //-----------------
-        // Test packetIn again with a different source port. Should be
-        // the same device
-        reset(mockTopology);
-        mockTopologyForPacketInTests(mockTopology);
-        replay(mockTopology);
-
-        // trigger the packet in
-        cntx = new FloodlightContext();
-        packetIn.setInPort((short)2);
-        cmd = dispatchPacketIn(5L, packetIn, cntx);
-        verify(mockTopology);
-        // Verify the replay matched our expectations
-        assertEquals(Command.CONTINUE, cmd);
-
-        // Verify the device
-        rdevice = (Device)
-                deviceManager.findDevice(Ethernet.toLong(deviceMac),
-                        (short)5, null, null, null);
-        verifyDevice(rdevice, Ethernet.toLong(deviceMac),
-                     (short)5, ipaddr, 5L, 2);
-        cntxSrcDev = IDeviceService.fcStore.get(cntx,
-                IDeviceService.CONTEXT_SRC_DEVICE);
-        assertEquals(rdevice, cntxSrcDev);
-        cntxDstDev = IDeviceService.fcStore.get(cntx,
-                IDeviceService.CONTEXT_DST_DEVICE);
-        assertNull(cntxDstDev);
-        // There can be only one device
-        assertEquals(1, deviceManager.getAllDevices().size());
-
-        //----------------------------
-        // Test packetIn with a different packet going the reverse direction.
-        // We should now get source and dest device in the context
-        //==> The destination device in this step has been learned just before
-        long srcMac = Ethernet.toLong(testUDPPacket.getSourceMACAddress());
-        long dstMac = Ethernet.toLong(deviceMac);
-        reset(mockTopology);
-        mockTopologyForPacketInTests(mockTopology);
-        replay(mockTopology);
-        // trigger the packet in
-        cntx = new FloodlightContext();
-        cmd = dispatchPacketIn(1L, testUDPPacketIn, cntx);
-        verify(mockTopology);
-
-        assertEquals(Command.CONTINUE, cmd);
-        IDevice srcDev =
-                deviceManager.findDevice(srcMac, (short)5, null, null, null);
-        verifyDevice(srcDev, srcMac, (short)5, null,
-                     1L, testUDPPacketIn.getInPort());
-
-        IDevice dstDev =
-                deviceManager.findDevice(dstMac, (short)5, null, null, null);
-        verifyDevice(dstDev, dstMac, (short)5, ipaddr, 5L, 2);
-
-        cntxSrcDev = IDeviceService.fcStore.get(cntx,
-                IDeviceService.CONTEXT_SRC_DEVICE);
-        assertEquals(srcDev, cntxSrcDev);
-
-        cntxDstDev = IDeviceService.fcStore.get(cntx,
-                IDeviceService.CONTEXT_DST_DEVICE);
-        assertEquals(dstDev, cntxDstDev);
-
-        assertEquals(2, deviceManager.getAllDevices().size());
-    }
-
-    /**
-     * This test ensures the device manager learns the source device
-     * corresponding to the senderHardwareAddress and senderProtocolAddress
-     * in an ARP response whenever the senderHardwareAddress is different
-     * from the source MAC address of the Ethernet frame.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void testDeviceLearningFromArpResponseData() throws Exception {
-        ARP arp = (ARP)((Ethernet)this.testARPReplyPacket_2).getPayload();
-        long senderMac = Ethernet.toLong(arp.getSenderHardwareAddress());
-        long sourceMac =
-                Ethernet.toLong(((Ethernet)this.testARPReplyPacket_2)
-                                .getSourceMACAddress());
-        Integer ipaddr = IPv4.toIPv4Address("192.168.1.1");
-        OFPacketIn packetIn = testARPReplyPacketIn_2;
-
-        // Mock up our expected behavior
-        ITopologyService mockTopology = createMock(ITopologyService.class);
-        deviceManager.topology = mockTopology;
-        mockTopologyForPacketInTests(mockTopology);
-        replay(mockTopology);
-
-
-        FloodlightContext cntx = new FloodlightContext();
-        Command cmd = dispatchPacketIn(1L, packetIn, cntx);
-        verify(mockTopology);
-        assertEquals(Command.CONTINUE, cmd);
-        // Verify the device for the sender HW address
-        Device senderDev = (Device)
-                deviceManager.findDevice(senderMac, (short)5, null, null, null);
-        verifyDevice(senderDev, senderMac, (short)5, ipaddr, 1L, 1);
-
-        Device result = null;
-        Iterator<? extends IDevice> dstiter =
-                deviceManager.queryDevices(null, null, ipaddr,
-                        null, null);
-        if (dstiter.hasNext()) {
-            result = (Device)dstiter.next();
-        }
-        assertFalse("There shouldn't be more than 1 device", dstiter.hasNext());
-        assertEquals(senderDev, result);
-
-
-
-        // Verify the device for the source MAC
-        Device srcDev = (Device)
-                deviceManager.findDevice(sourceMac, (short)5, null, null, null);
-        // must NOT learn IP on this device
-        verifyDevice(srcDev, sourceMac, (short)5, null, 1L, 1);
-        assertFalse("Device must differ", srcDev.equals(senderDev));
-        // Context is annotated with this device, not the device associated
-        // with ARP sender address
-        IDevice cntxSrcDev = IDeviceService.fcStore.get(cntx,
-                IDeviceService.CONTEXT_SRC_DEVICE);
-        assertEquals(srcDev, cntxSrcDev);
-
-        assertEquals(2, deviceManager.getAllDevices().size());
-    }
-
-
-    @Test
-    public void testPacketInInvalidSrcMac() throws Exception {
-        // Mock up our expected behavior
-        ITopologyService mockTopology = createMock(ITopologyService.class);
-        deviceManager.topology = mockTopology;
-        mockTopologyForPacketInTests(mockTopology);
-        replay(mockTopology);
-        FloodlightContext cntx = new FloodlightContext();
-
-        testUDPPacket.setSourceMACAddress(Ethernet.toByteArray(0L));
-        updateUDPPacketIn();
-        Command cmd = dispatchPacketIn(1L, testUDPPacketIn, cntx);
-        assertEquals(Command.STOP, cmd);
-        IDevice cntxSrcDev = IDeviceService.fcStore.get(cntx,
-                IDeviceService.CONTEXT_SRC_DEVICE);
-        assertNull(cntxSrcDev);
-        IDevice cntxDstDev = IDeviceService.fcStore.get(cntx,
-                IDeviceService.CONTEXT_DST_DEVICE);
-        assertNull(cntxDstDev);
-
-        testUDPPacket.setSourceMACAddress(Ethernet.toByteArray(-1L));
-        updateUDPPacketIn();
-        cmd = dispatchPacketIn(1L, testUDPPacketIn, cntx);
-        assertEquals(Command.STOP, cmd);
-        cntxSrcDev = IDeviceService.fcStore.get(cntx,
-                IDeviceService.CONTEXT_SRC_DEVICE);
-        assertNull(cntxSrcDev);
-        cntxDstDev = IDeviceService.fcStore.get(cntx,
-                IDeviceService.CONTEXT_DST_DEVICE);
-        assertNull(cntxDstDev);
-
-        // MAC with only the multicast bit set
-        testUDPPacket.setSourceMACAddress(new byte[] { 1, 0, 0, 0, 0, 0 });
-        updateUDPPacketIn();
-        cmd = dispatchPacketIn(1L, testUDPPacketIn, cntx);
-        assertEquals(Command.STOP, cmd);
-        cntxSrcDev = IDeviceService.fcStore.get(cntx,
-                IDeviceService.CONTEXT_SRC_DEVICE);
-        assertNull(cntxSrcDev);
-        cntxDstDev = IDeviceService.fcStore.get(cntx,
-                IDeviceService.CONTEXT_DST_DEVICE);
-        assertNull(cntxDstDev);
-
-        // Now use a real MAC. We should get a src device
-        testUDPPacket.setSourceMACAddress(Ethernet.toByteArray(1L));
-        updateUDPPacketIn();
-        cmd = dispatchPacketIn(1L, testUDPPacketIn, cntx);
-        assertEquals(Command.CONTINUE, cmd);
-        cntxSrcDev = IDeviceService.fcStore.get(cntx,
-                IDeviceService.CONTEXT_SRC_DEVICE);
-        verifyDevice(cntxSrcDev, 1L, (short)5, null,
-                     1L, testUDPPacketIn.getInPort());
-
-        cntxDstDev = IDeviceService.fcStore.get(cntx,
-                IDeviceService.CONTEXT_DST_DEVICE);
-        assertNull(cntxDstDev);
-        verify(mockTopology);
-    }
-
-
-    @Test
-    public void testPacketInInvalidDstMac() throws Exception {
-        // Mock up our expected behavior
-        ITopologyService mockTopology = createMock(ITopologyService.class);
-        deviceManager.topology = mockTopology;
-        mockTopologyForPacketInTests(mockTopology);
-        replay(mockTopology);
-        FloodlightContext cntx = new FloodlightContext();
-
-        long srcMac = Ethernet.toLong(testUDPPacket.getSourceMACAddress());
-        long dstMac = Ethernet.toLong(testUDPPacket.getDestinationMACAddress());
-
-        // Prime device manager with the source device
-        Command cmd = dispatchPacketIn(1L, testUDPPacketIn, cntx);
-        assertEquals(Command.CONTINUE, cmd);
-        IDevice cntxSrcDev = IDeviceService.fcStore.get(cntx,
-                IDeviceService.CONTEXT_SRC_DEVICE);
-        verifyDevice(cntxSrcDev, srcMac, (short)5, null,
-                     1L, testUDPPacketIn.getInPort());
-        IDevice cntxDstDev = IDeviceService.fcStore.get(cntx,
-                IDeviceService.CONTEXT_DST_DEVICE);
-        assertNull(cntxDstDev);
-        IDevice expectedSrcDev = cntxSrcDev;
-
-        // Create a device for the destination. We can use testARPPacketIn_1
-        // for that.
-        cntx = new FloodlightContext();
-        // Prime device manager with the source device
-        cmd = dispatchPacketIn(1L, testARPReplyPacketIn_1, cntx);
-        assertEquals(Command.CONTINUE, cmd);
-        cntxSrcDev = IDeviceService.fcStore.get(cntx,
-                IDeviceService.CONTEXT_SRC_DEVICE);
-        // yes: we check that cntxSrcDev matched dstMAC because we are
-        // just adding the dest device
-        int ip = IPv4.toIPv4Address("192.168.1.1");
-        verifyDevice(cntxSrcDev, dstMac, (short)5, ip,
-                     1L, testARPReplyPacketIn_1.getInPort());
-        // yes: we set the expected dst device to the current srcDev
-        IDevice expectedDstDev = cntxSrcDev;
-
-        //-------------------------------
-        // Let the real tests begin
-
-        cntx = new FloodlightContext();
-        testUDPPacket.setDestinationMACAddress(Ethernet.toByteArray(0L));
-        updateUDPPacketIn();
-        cmd = dispatchPacketIn(1L, testUDPPacketIn, cntx);
-        assertEquals(Command.STOP, cmd);
-        cntxDstDev = IDeviceService.fcStore.get(cntx,
-                IDeviceService.CONTEXT_DST_DEVICE);
-        assertNull(cntxDstDev);
-
-        // use a real dest mac
-        cntx = new FloodlightContext();
-        testUDPPacket.setDestinationMACAddress(Ethernet.toByteArray(dstMac));
-        updateUDPPacketIn();
-        cmd = dispatchPacketIn(1L, testUDPPacketIn, cntx);
-        assertEquals(Command.CONTINUE, cmd);
-        cntxSrcDev = IDeviceService.fcStore.get(cntx,
-                IDeviceService.CONTEXT_SRC_DEVICE);
-        assertEquals(expectedSrcDev, cntxSrcDev);
-        cntxDstDev = IDeviceService.fcStore.get(cntx,
-                IDeviceService.CONTEXT_DST_DEVICE);
-        assertEquals(expectedDstDev, cntxDstDev);
-
-        verify(mockTopology);
-    }
-
-    /**
-     * Note: Entity expiration does not result in device moved notification.
-     * @throws Exception
-     */
-    public void doTestEntityExpiration() throws Exception {
-        IDeviceListener mockListener =
-                createMock(IDeviceListener.class);
-        expect(mockListener.getName()).andReturn("mockListener").anyTimes();
-        expect(mockListener.isCallbackOrderingPostreq((String)anyObject(), (String)anyObject()))
-        .andReturn(false).atLeastOnce();
-        expect(mockListener.isCallbackOrderingPrereq((String)anyObject(), (String)anyObject()))
-        .andReturn(false).atLeastOnce();
-
-        ITopologyService mockTopology = createMock(ITopologyService.class);
-        expect(mockTopology.isAttachmentPointPort(anyLong(),
-                                                  anyShort())).
-                                                  andReturn(true).anyTimes();
-
-        expect(mockTopology.isBroadcastDomainPort(1L, (short)1)).andReturn(false).anyTimes();
-        expect(mockTopology.isBroadcastDomainPort(5L, (short)1)).andReturn(false).anyTimes();
-        expect(mockTopology.getL2DomainId(1L)).andReturn(1L).anyTimes();
-        expect(mockTopology.getL2DomainId(5L)).andReturn(5L).anyTimes();
-        expect(mockTopology.isConsistent(1L, (short)1, 5L, (short)1)).
-        andReturn(false).anyTimes();
-
-        Date topologyUpdateTime = new Date();
-        expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
-        anyTimes();
-
-        replay(mockTopology);
-        deviceManager.topology = mockTopology;
-
-        Calendar c = Calendar.getInstance();
-        Entity entity1 = new Entity(1L, null, 2, 1L, 1, c.getTime());
-        c.add(Calendar.MILLISECOND, -DeviceManagerImpl.ENTITY_TIMEOUT-1);
-        Entity entity2 = new Entity(1L, null, 1, 5L, 1, c.getTime());
-
-        deviceManager.learnDeviceByEntity(entity1);
-        IDevice d = deviceManager.learnDeviceByEntity(entity2);
-        assertArrayEquals(new Integer[] { 1, 2 }, d.getIPv4Addresses());
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1),
-                                             new SwitchPort(5L, 1)},
-                                             d.getAttachmentPoints());
-        Iterator<? extends IDevice> diter =
-                deviceManager.queryClassDevices(d.getEntityClass(),
-                                                null, null, 1, null, null);
-        assertTrue(diter.hasNext());
-        assertEquals(d.getDeviceKey(), diter.next().getDeviceKey());
-        diter = deviceManager.queryClassDevices(d.getEntityClass(),
-                                                null, null, 2, null, null);
-        assertTrue(diter.hasNext());
-        assertEquals(d.getDeviceKey(), diter.next().getDeviceKey());
-
-        replay(mockListener);
-        deviceManager.addListener(mockListener);
-        verify(mockListener);
-        reset(mockListener);
-
-        mockListener.deviceIPV4AddrChanged(isA(IDevice.class));
-        replay(mockListener);
-        deviceManager.entityCleanupTask.reschedule(0, null);
-
-        d = deviceManager.getDevice(d.getDeviceKey());
-        assertArrayEquals(new Integer[] { 2 }, d.getIPv4Addresses());
-
-        // Attachment points are not removed, previous ones are still valid.
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1),
-                                             new SwitchPort(5L, 1) },
-                          d.getAttachmentPoints());
-        diter = deviceManager.queryClassDevices(d.getEntityClass(),
-                                                null, null, 2, null, null);
-        assertTrue(diter.hasNext());
-        assertEquals(d.getDeviceKey(), diter.next().getDeviceKey());
-        diter = deviceManager.queryClassDevices(d.getEntityClass(),
-                                                null, null, 1, null, null);
-        assertFalse(diter.hasNext());
-
-        d = deviceManager.findDevice(1L, null, null, null, null);
-        assertArrayEquals(new Integer[] { 2 }, d.getIPv4Addresses());
-
-        // Attachment points are not removed, previous ones are still valid.
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1),
-                                             new SwitchPort(5L, 1) },
-                          d.getAttachmentPoints());
-
-        verify(mockListener);
-    }
-
-    public void doTestDeviceExpiration() throws Exception {
-        IDeviceListener mockListener =
-                createMock(IDeviceListener.class);
-        expect(mockListener.getName()).andReturn("mockListener").anyTimes();
-        expect(mockListener.isCallbackOrderingPostreq((String)anyObject(), (String)anyObject()))
-        .andReturn(false).atLeastOnce();
-        expect(mockListener.isCallbackOrderingPrereq((String)anyObject(), (String)anyObject()))
-        .andReturn(false).atLeastOnce();
-
-        Calendar c = Calendar.getInstance();
-        c.add(Calendar.MILLISECOND, -DeviceManagerImpl.ENTITY_TIMEOUT-1);
-        Entity entity1 = new Entity(1L, null, 1, 1L, 1, c.getTime());
-        Entity entity2 = new Entity(1L, null, 2, 5L, 1, c.getTime());
-
-        ITopologyService mockTopology = createMock(ITopologyService.class);
-        deviceManager.topology = mockTopology;
-
-        expect(mockTopology.isAttachmentPointPort(EasyMock.anyLong(),
-                                           EasyMock.anyShort())).
-                                           andReturn(true).
-                                           anyTimes();
-        expect(mockTopology.getL2DomainId(1L)).andReturn(1L).anyTimes();
-        expect(mockTopology.getL2DomainId(5L)).andReturn(1L).anyTimes();
-        expect(mockTopology.isConsistent(EasyMock.anyLong(),
-                                         EasyMock.anyShort(),
-                                         EasyMock.anyLong(),
-                                         EasyMock.anyShort())).andReturn(false).
-                                         anyTimes();
-        expect(mockTopology.isBroadcastDomainPort(EasyMock.anyLong(),
-                                                  EasyMock.anyShort())).
-                                                  andReturn(false).anyTimes();
-        replay(mockTopology);
-
-        IDevice d = deviceManager.learnDeviceByEntity(entity2);
-        d = deviceManager.learnDeviceByEntity(entity1);
-        assertArrayEquals(new Integer[] { 1, 2 }, d.getIPv4Addresses());
-
-        replay(mockListener);
-        deviceManager.addListener(mockListener);
-        verify(mockListener);
-        reset(mockListener);
-
-        mockListener.deviceRemoved(isA(IDevice.class));
-        replay(mockListener);
-        deviceManager.entityCleanupTask.reschedule(0, null);
-
-        IDevice r = deviceManager.getDevice(d.getDeviceKey());
-        assertNull(r);
-        Iterator<? extends IDevice> diter =
-                deviceManager.queryClassDevices(d.getEntityClass(),
-                                                null, null, 1, null, null);
-        assertFalse(diter.hasNext());
-
-        r = deviceManager.findDevice(1L, null, null, null, null);
-        assertNull(r);
-
-        verify(mockListener);
-    }
-
-    /*
-     * A ConcurrentHashMap for devices (deviceMap) that can be used to test
-     * code that specially handles concurrent modification situations. In
-     * particular, we overwrite values() and will replace / remove all the
-     * elements returned by values.
-     *
-     * The remove flag in the constructor specifies if devices returned by
-     * values() should be removed or replaced.
-     */
-    protected static class ConcurrentlyModifiedDeviceMap
-                            extends ConcurrentHashMap<Long, Device> {
-        private static final long serialVersionUID = 7784938535441180562L;
-        protected boolean remove;
-        public ConcurrentlyModifiedDeviceMap(boolean remove) {
-            super();
-            this.remove = remove;
-        }
-
-        @Override
-        public Collection<Device> values() {
-            // Get the values from the real map and copy them since
-            // the collection returned by values can reflect changed
-            Collection<Device> devs = new ArrayList<Device>(super.values());
-            for (Device d: devs) {
-                if (remove) {
-                    // We remove the device from the underlying map
-                    super.remove(d.getDeviceKey());
-                } else {
-                    super.remove(d.getDeviceKey());
-                    // We add a different Device instance with the same
-                    // key to the map. We'll do some hackery so the device
-                    // is different enough to compare differently in equals
-                    // but otherwise looks the same.
-                    // It's ugly but it works.
-                    // clone entities
-                    Device newDevice = d;
-                    for (Entity e: d.getEntities()) {
-                        Entity newEntity = new Entity (e.macAddress,
-                                                       e.vlan,
-                                                       e.ipv4Address,
-                                                       e.switchDPID,
-                                                       e.switchPort,
-                                                       e.lastSeenTimestamp);
-                        if (e.vlan == null)
-                            newEntity.vlan = (short)1;
-                        else
-                             newEntity.vlan = (short)((e.vlan + 1 % 4095)+1);
-                        newDevice = new Device(newDevice, newEntity, -1);
-                    }
-                    assertEquals(false, newDevice.equals(d));
-                    super.put(newDevice.getDeviceKey(), newDevice);
-                }
-            }
-            return devs;
-        }
-    }
-
-    @Test
-    public void testEntityExpiration() throws Exception {
-        doTestEntityExpiration();
-    }
-
-    @Test
-    public void testDeviceExpiration() throws Exception {
-        doTestDeviceExpiration();
-    }
-
-    /* Test correct entity cleanup behavior when a concurrent modification
-     * occurs.
-     */
-    @Test
-    public void testEntityExpirationConcurrentModification() throws Exception {
-        deviceManager.deviceMap = new ConcurrentlyModifiedDeviceMap(false);
-        doTestEntityExpiration();
-    }
-
-    /* Test correct entity cleanup behavior when a concurrent remove
-     * occurs.
-     */
-    @Test
-    public void testDeviceExpirationConcurrentRemove() throws Exception {
-        deviceManager.deviceMap = new ConcurrentlyModifiedDeviceMap(true);
-        doTestDeviceExpiration();
-    }
-
-    /* Test correct entity cleanup behavior when a concurrent modification
-     * occurs.
-     */
-    @Test
-    public void testDeviceExpirationConcurrentModification() throws Exception {
-        deviceManager.deviceMap = new ConcurrentlyModifiedDeviceMap(false);
-        doTestDeviceExpiration();
-    }
-
-
-    @Test
-    public void testAttachmentPointFlapping() throws Exception {
-        Calendar c = Calendar.getInstance();
-
-        ITopologyService mockTopology = createMock(ITopologyService.class);
-        expect(mockTopology.isAttachmentPointPort(anyLong(),
-                                                  anyShort())).andReturn(true).anyTimes();
-        expect(mockTopology.isBroadcastDomainPort(anyLong(),
-                                                  anyShort())).
-                                                  andReturn(false).anyTimes();
-        expect(mockTopology.isInSameBroadcastDomain(anyLong(), anyShort(),
-                                                    anyLong(), anyShort())).andReturn(false).anyTimes();
-        expect(mockTopology.getL2DomainId(anyLong())).
-        andReturn(1L).anyTimes();
-        expect(mockTopology.isConsistent(1L, (short)1, 1L, (short)1)).
-        andReturn(true).anyTimes();
-        expect(mockTopology.isConsistent(1L, (short)1, 5L, (short)1)).
-        andReturn(false).anyTimes();
-        expect(mockTopology.isConsistent(1L, (short)1, 10L, (short)1)).
-        andReturn(false).anyTimes();
-        expect(mockTopology.isConsistent(5L, (short)1, 10L, (short)1)).
-        andReturn(false).anyTimes();
-        expect(mockTopology.isConsistent(10L, (short)1, 1L, (short)1)).
-        andReturn(false).anyTimes();
-        expect(mockTopology.isConsistent(5L, (short)1, 1L, (short)1)).
-        andReturn(false).anyTimes();
-        expect(mockTopology.isConsistent(10L, (short)1, 5L, (short)1)).
-        andReturn(false).anyTimes();
-
-        Date topologyUpdateTime = new Date();
-        expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
-        anyTimes();
-
-
-        replay(mockTopology);
-        deviceManager.topology = mockTopology;
-
-        Entity entity1 = new Entity(1L, null, null, 1L, 1, c.getTime());
-        Entity entity1a = new Entity(1L, null, 1, 1L, 1, c.getTime());
-        Entity entity2 = new Entity(1L, null, null, 5L, 1, c.getTime());
-        Entity entity3 = new Entity(1L, null, null, 10L, 1, c.getTime());
-        entity1.setLastSeenTimestamp(c.getTime());
-        c.add(Calendar.MILLISECOND, Entity.ACTIVITY_TIMEOUT/2);
-        entity1a.setLastSeenTimestamp(c.getTime());
-        c.add(Calendar.MILLISECOND, 1);
-        entity2.setLastSeenTimestamp(c.getTime());
-        c.add(Calendar.MILLISECOND, 1);
-        entity3.setLastSeenTimestamp(c.getTime());
-
-
-
-        IDevice d;
-        d = deviceManager.learnDeviceByEntity(entity1);
-        d = deviceManager.learnDeviceByEntity(entity1a);
-        d = deviceManager.learnDeviceByEntity(entity2);
-        d = deviceManager.learnDeviceByEntity(entity3);
-
-        // all entities are active, so entity3 should win
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(10L, 1) },
-                          d.getAttachmentPoints());
-
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(10L, 1),},
-                              d.getAttachmentPoints(true));
-
-        c.add(Calendar.MILLISECOND, Entity.ACTIVITY_TIMEOUT/4);
-        entity1.setLastSeenTimestamp(c.getTime());
-        d = deviceManager.learnDeviceByEntity(entity1);
-
-        // all are still active; entity3 should still win
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1) },
-                          d.getAttachmentPoints());
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1),
-                                             new SwitchPort(5L, 1,
-                                                            ErrorStatus.DUPLICATE_DEVICE),
-                                                            new SwitchPort(10L, 1,
-                                                                           ErrorStatus.DUPLICATE_DEVICE) },
-                                                                           d.getAttachmentPoints(true));
-
-        c.add(Calendar.MILLISECOND, Entity.ACTIVITY_TIMEOUT+2000);
-        entity1.setLastSeenTimestamp(c.getTime());
-        d = deviceManager.learnDeviceByEntity(entity1);
-
-        assertEquals(entity1.getActiveSince(), entity1.getLastSeenTimestamp());
-        // entity1 should now be the only active entity
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1) },
-                          d.getAttachmentPoints());
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1) },
-                          d.getAttachmentPoints(true));
-    }
-
-
-    @Test
-    public void testAttachmentPointFlappingTwoCluster() throws Exception {
-        Calendar c = Calendar.getInstance();
-
-        ITopologyService mockTopology = createMock(ITopologyService.class);
-        expect(mockTopology.isAttachmentPointPort(anyLong(),
-                                                  anyShort())).andReturn(true).anyTimes();
-        expect(mockTopology.isBroadcastDomainPort(anyLong(),
-                                                  anyShort())).
-                                                  andReturn(false).anyTimes();
-        expect(mockTopology.isInSameBroadcastDomain(anyLong(), anyShort(),
-                                                    anyLong(), anyShort())).andReturn(false).anyTimes();
-        expect(mockTopology.getL2DomainId(1L)).
-        andReturn(1L).anyTimes();
-        expect(mockTopology.getL2DomainId(5L)).
-        andReturn(5L).anyTimes();
-        expect(mockTopology.isConsistent(1L, (short)1, 1L, (short)2)).
-        andReturn(false).anyTimes();
-        expect(mockTopology.isConsistent(1L, (short)2, 5L, (short)1)).
-        andReturn(false).anyTimes();
-        expect(mockTopology.isConsistent(5L, (short)1, 5L, (short)2)).
-        andReturn(false).anyTimes();
-        expect(mockTopology.isConsistent(1L, (short)2, 1L, (short)1)).
-        andReturn(false).anyTimes();
-        expect(mockTopology.isConsistent(1L, (short)1, 5L, (short)1)).
-        andReturn(false).anyTimes();
-        expect(mockTopology.isConsistent(1L, (short)1, 5L, (short)2)).
-        andReturn(false).anyTimes();
-        expect(mockTopology.isConsistent(5L, (short)2, 5L, (short)1)).
-        andReturn(false).anyTimes();
-
-        Date topologyUpdateTime = new Date();
-        expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
-        anyTimes();
-
-        replay(mockTopology);
-        deviceManager.topology = mockTopology;
-
-        Entity entity1 = new Entity(1L, null, null, 1L, 1, c.getTime());
-        Entity entity2 = new Entity(1L, null, null, 1L, 2, c.getTime());
-        Entity entity3 = new Entity(1L, null, null, 5L, 1, c.getTime());
-        Entity entity4 = new Entity(1L, null, null, 5L, 2, c.getTime());
-        entity1.setLastSeenTimestamp(c.getTime());
-        c.add(Calendar.MILLISECOND, Entity.ACTIVITY_TIMEOUT/2);
-        c.add(Calendar.MILLISECOND, 1);
-        entity2.setLastSeenTimestamp(c.getTime());
-        c.add(Calendar.MILLISECOND, 1);
-        entity3.setLastSeenTimestamp(c.getTime());
-        c.add(Calendar.MILLISECOND, 1);
-        entity4.setLastSeenTimestamp(c.getTime());
-
-        deviceManager.learnDeviceByEntity(entity1);
-        deviceManager.learnDeviceByEntity(entity2);
-        deviceManager.learnDeviceByEntity(entity3);
-        IDevice d = deviceManager.learnDeviceByEntity(entity4);
-
-        // all entities are active, so entities 2,4 should win
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 2),
-                                             new SwitchPort(5L, 2) },
-                                             d.getAttachmentPoints());
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 2),
-                                             new SwitchPort(5L, 2)},
-                                             d.getAttachmentPoints(true));
-
-        c.add(Calendar.MILLISECOND, 1);
-        entity1.setLastSeenTimestamp(c.getTime());
-        d = deviceManager.learnDeviceByEntity(entity1);
-
-        // all entities are active, so entities 2,4 should win
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1),
-                                             new SwitchPort(5L, 2) },
-                                             d.getAttachmentPoints());
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1),
-                                             new SwitchPort(5L, 2),
-                                             new SwitchPort(1L, 2, ErrorStatus.DUPLICATE_DEVICE)},
-                                             d.getAttachmentPoints(true));
-
-        c.add(Calendar.MILLISECOND, Entity.ACTIVITY_TIMEOUT+1);
-        entity1.setLastSeenTimestamp(c.getTime());
-        d = deviceManager.learnDeviceByEntity(entity1);
-
-        // entities 3,4 are still in conflict, but 1 should be resolved
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1),
-                                             new SwitchPort(5L, 2) },
-                                             d.getAttachmentPoints());
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1),
-                                             new SwitchPort(5L, 2)},
-                                             d.getAttachmentPoints(true));
-
-        entity3.setLastSeenTimestamp(c.getTime());
-        d = deviceManager.learnDeviceByEntity(entity3);
-
-        // no conflicts, 1 and 3 will win
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1),
-                                             new SwitchPort(5L, 1) },
-                                             d.getAttachmentPoints());
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1),
-                                             new SwitchPort(5L, 1) },
-                                             d.getAttachmentPoints(true));
-
-    }
-
-    protected void doTestDeviceQuery() throws Exception {
-        Entity entity1 = new Entity(1L, (short)1, 1, 1L, 1, new Date());
-        Entity entity2 = new Entity(2L, (short)2, 2, 1L, 2, new Date());
-        Entity entity3 = new Entity(3L, (short)3, 3, 5L, 1, new Date());
-        Entity entity4 = new Entity(4L, (short)4, 3, 5L, 2, new Date());
-        Entity entity5 = new Entity(1L, (short)4, 3, 5L, 2, new Date());
-
-        Device d1 = deviceManager.learnDeviceByEntity(entity1);
-        deviceManager.learnDeviceByEntity(entity2);
-        Device d3 = deviceManager.learnDeviceByEntity(entity3);
-        Device d4 = deviceManager.learnDeviceByEntity(entity4);
-
-        IDevice d;
-
-        Iterator<? extends IDevice> iter =
-                deviceManager.queryDevices(null, (short)1, 1, null, null);
-        int count = 0;
-        while (iter.hasNext()) {
-            count += 1;
-            d = iter.next();
-            assertEquals(d1.getDeviceKey(), d.getDeviceKey());
-        }
-        assertEquals(1, count);
-
-        iter = deviceManager.queryDevices(null, (short)3, 3, null, null);
-        count = 0;
-        while (iter.hasNext()) {
-            count += 1;
-            d = iter.next();
-            assertEquals(d3.getDeviceKey(), d.getDeviceKey());
-        }
-        assertEquals(1, count);
-
-        iter = deviceManager.queryDevices(null, (short)1, 3, null, null);
-        count = 0;
-        while (iter.hasNext()) {
-            count += 1;
-            iter.next();
-        }
-        assertEquals(0, count);
-
-        Device d5 = deviceManager.learnDeviceByEntity(entity5);
-        iter = deviceManager.queryDevices(null, (short)4, 3, null, null);
-        count = 0;
-        Set<Long> deviceKeysFromIterator = new HashSet<Long>();
-        while (iter.hasNext()) {
-            count += 1;
-            d = iter.next();
-            deviceKeysFromIterator.add(d.getDeviceKey());
-        }
-        Set<Long> expectedDeviceKeys = new HashSet<Long>();
-        expectedDeviceKeys.add(d4.getDeviceKey());
-        expectedDeviceKeys.add(d5.getDeviceKey());
-        assertEquals(expectedDeviceKeys, deviceKeysFromIterator);
-        assertEquals(2, count);
-
-
-        iter = deviceManager.queryDevices(1L, null, null, null, null);
-        count = 0;
-        deviceKeysFromIterator = new HashSet<Long>();
-        while (iter.hasNext()) {
-            count += 1;
-            d = iter.next();
-            deviceKeysFromIterator.add(d.getDeviceKey());
-        }
-        expectedDeviceKeys = new HashSet<Long>();
-        expectedDeviceKeys.add(d1.getDeviceKey());
-        expectedDeviceKeys.add(d5.getDeviceKey());
-        assertEquals(expectedDeviceKeys, deviceKeysFromIterator);
-        assertEquals(2, count);
-    }
-
-    @Test
-    public void testDeviceIndex() throws Exception {
-        EnumSet<IDeviceService.DeviceField> indexFields =
-                EnumSet.noneOf(IDeviceService.DeviceField.class);
-        indexFields.add(IDeviceService.DeviceField.IPV4);
-        indexFields.add(IDeviceService.DeviceField.VLAN);
-        deviceManager.addIndex(false, indexFields);
-
-        indexFields = EnumSet.noneOf(IDeviceService.DeviceField.class);
-        deviceManager.addIndex(false, indexFields);
-
-        ITopologyService mockTopology = createMock(ITopologyService.class);
-        deviceManager.topology = mockTopology;
-        expect(mockTopology.isAttachmentPointPort(anyLong(),
-                                                  anyShort())).
-                                                  andReturn(true).anyTimes();
-        expect(mockTopology.getL2DomainId(EasyMock.anyLong())).andReturn(1L).anyTimes();
-        replay(mockTopology);
-        doTestDeviceQuery();
-    }
-
-    @Test
-    public void testDeviceQuery() throws Exception {
-        ITopologyService mockTopology = createMock(ITopologyService.class);
-        deviceManager.topology = mockTopology;
-        expect(mockTopology.isAttachmentPointPort(anyLong(),
-                                                  anyShort())).
-                                                  andReturn(true).anyTimes();
-        expect(mockTopology.getL2DomainId(EasyMock.anyLong())).andReturn(1L).anyTimes();
-        replay(mockTopology);
-
-        doTestDeviceQuery();
-    }
-
-    protected void doTestDeviceClassQuery() throws Exception {
-        Entity entity1 = new Entity(1L, (short)1, 1, 1L, 1, new Date());
-        Entity entity2 = new Entity(2L, (short)2, 2, 1L, 2, new Date());
-        Entity entity3 = new Entity(3L, (short)3, 3, 5L, 1, new Date());
-        Entity entity4 = new Entity(4L, (short)4, 3, 5L, 2, new Date());
-        Entity entity5 = new Entity(1L, (short)4, 3, 5L, 2, new Date());
-
-        IDevice d1 = deviceManager.learnDeviceByEntity(entity1);
-        IDevice d2 = deviceManager.learnDeviceByEntity(entity2);
-        IDevice d3 = deviceManager.learnDeviceByEntity(entity3);
-        IDevice d4 = deviceManager.learnDeviceByEntity(entity4);
-        assertEquals(d1.getEntityClass(), d2.getEntityClass());
-        assertEquals(d1.getEntityClass(), d3.getEntityClass());
-        assertEquals(d1.getEntityClass(), d4.getEntityClass());
-
-        IDevice d;
-
-        Iterator<? extends IDevice> iter =
-                deviceManager.queryClassDevices(d1.getEntityClass(), null,
-                                                (short)1, 1, null, null);
-        int count = 0;
-        while (iter.hasNext()) {
-            count += 1;
-            d = iter.next();
-            assertEquals(d1.getDeviceKey(), d.getDeviceKey());
-        }
-        assertEquals(1, count);
-
-        iter = deviceManager.queryClassDevices(d1.getEntityClass(), null,
-                                               (short)3, 3, null, null);
-        count = 0;
-        while (iter.hasNext()) {
-            count += 1;
-            d = iter.next();
-            assertEquals(d3.getDeviceKey(), d.getDeviceKey());
-
-        }
-        assertEquals(1, count);
-
-        iter = deviceManager.queryClassDevices(d1.getEntityClass(), null,
-                                               (short)1, 3, null, null);
-        count = 0;
-        while (iter.hasNext()) {
-            count += 1;
-            iter.next();
-        }
-        assertEquals(0, count);
-
-        IDevice d5 = deviceManager.learnDeviceByEntity(entity5);
-        assertEquals(d1.getEntityClass(), d5.getEntityClass());
-        iter = deviceManager.queryClassDevices(d1.getEntityClass(), null,
-                                               (short)4, 3, null, null);
-        count = 0;
-        Set<Long> deviceKeysFromIterator = new HashSet<Long>();
-        while (iter.hasNext()) {
-            count += 1;
-            d = iter.next();
-            deviceKeysFromIterator.add(d.getDeviceKey());
-        }
-        Set<Long> expectedDeviceKeys = new HashSet<Long>();
-        expectedDeviceKeys.add(d4.getDeviceKey());
-        expectedDeviceKeys.add(d5.getDeviceKey());
-        assertEquals(expectedDeviceKeys, deviceKeysFromIterator);
-        assertEquals(2, count);
-    }
-
-    @Test
-    public void testDeviceClassIndex() throws Exception {
-        EnumSet<IDeviceService.DeviceField> indexFields =
-                EnumSet.noneOf(IDeviceService.DeviceField.class);
-        indexFields.add(IDeviceService.DeviceField.IPV4);
-        indexFields.add(IDeviceService.DeviceField.VLAN);
-        deviceManager.addIndex(true, indexFields);
-
-        ITopologyService mockTopology = createMock(ITopologyService.class);
-        deviceManager.topology = mockTopology;
-        expect(mockTopology.isAttachmentPointPort(anyLong(),
-                                                  anyShort())).
-                                                  andReturn(true).anyTimes();
-        expect(mockTopology.getL2DomainId(EasyMock.anyLong())).andReturn(1L).anyTimes();
-        replay(mockTopology);
-
-        doTestDeviceClassQuery();
-    }
-
-    @Test
-    public void testDeviceClassQuery() throws Exception {
-        ITopologyService mockTopology = createMock(ITopologyService.class);
-        deviceManager.topology = mockTopology;
-        expect(mockTopology.isAttachmentPointPort(anyLong(),
-                                                  anyShort())).
-                                                  andReturn(true).anyTimes();
-        expect(mockTopology.getL2DomainId(EasyMock.anyLong())).andReturn(1L).anyTimes();
-        replay(mockTopology);
-
-        doTestDeviceClassQuery();
-    }
-
-    @Test
-    public void testFindDevice() throws FloodlightModuleException {
-        boolean exceptionCaught;
-        deviceManager.entityClassifier= new MockEntityClassifierMac();
-        deviceManager.startUp(null);
-
-        ITopologyService mockTopology = createMock(ITopologyService.class);
-        deviceManager.topology = mockTopology;
-        expect(mockTopology.isAttachmentPointPort(anyLong(),
-                                                  anyShort())).
-                                                  andReturn(true).anyTimes();
-        expect(mockTopology.getL2DomainId(EasyMock.anyLong())).andReturn(1L).anyTimes();
-        replay(mockTopology);
-
-        Entity entity1 = new Entity(1L, (short)1, 1, 1L, 1, new Date());
-        Entity entity2 = new Entity(2L, (short)2, 2, 1L, 2, new Date());
-        Entity entity2b = new Entity(22L, (short)2, 2, 1L, 2, new Date());
-
-        Entity entity3 = new Entity(3L, (short)1, 3, 2L, 1, new Date());
-        Entity entity4 = new Entity(4L, (short)2, 4, 2L, 2, new Date());
-
-        Entity entity5 = new Entity(5L, (short)1, 5, 3L, 1, new Date());
-
-
-        IDevice d1 = deviceManager.learnDeviceByEntity(entity1);
-        IDevice d2 = deviceManager.learnDeviceByEntity(entity2);
-        IDevice d3 = deviceManager.learnDeviceByEntity(entity3);
-        IDevice d4 = deviceManager.learnDeviceByEntity(entity4);
-        IDevice d5 = deviceManager.learnDeviceByEntity(entity5);
-
-        // Make sure the entity classifier worked as expected
-        assertEquals(MockEntityClassifierMac.testECMac1, d1.getEntityClass());
-        assertEquals(MockEntityClassifierMac.testECMac1, d2.getEntityClass());
-        assertEquals(MockEntityClassifierMac.testECMac2, d3.getEntityClass());
-        assertEquals(MockEntityClassifierMac.testECMac2, d4.getEntityClass());
-        assertEquals(DefaultEntityClassifier.entityClass,
-                     d5.getEntityClass());
-
-        // Look up the device using findDevice() which uses only the primary
-        // index
-        assertEquals(d1, deviceManager.findDevice(entity1.getMacAddress(),
-                                                  entity1.getVlan(),
-                                                  entity1.getIpv4Address(),
-                                                  entity1.getSwitchDPID(),
-                                                  entity1.getSwitchPort()));
-        // port changed. Device will be found through class index
-        assertEquals(d1, deviceManager.findDevice(entity1.getMacAddress(),
-                                                  entity1.getVlan(),
-                                                  entity1.getIpv4Address(),
-                                                  entity1.getSwitchDPID(),
-                                                  entity1.getSwitchPort()+1));
-        // VLAN changed. No device matches
-        assertEquals(null, deviceManager.findDevice(entity1.getMacAddress(),
-                                                  (short)42,
-                                                  entity1.getIpv4Address(),
-                                                  entity1.getSwitchDPID(),
-                                                  entity1.getSwitchPort()));
-        assertEquals(null, deviceManager.findDevice(entity1.getMacAddress(),
-                                                  null,
-                                                  entity1.getIpv4Address(),
-                                                  entity1.getSwitchDPID(),
-                                                  entity1.getSwitchPort()));
-        assertEquals(d2, deviceManager.findDeviceByEntity(entity2));
-        assertEquals(null, deviceManager.findDeviceByEntity(entity2b));
-        assertEquals(d3, deviceManager.findDevice(entity3.getMacAddress(),
-                                                  entity3.getVlan(),
-                                                  entity3.getIpv4Address(),
-                                                  entity3.getSwitchDPID(),
-                                                  entity3.getSwitchPort()));
-        // switch and port not set. throws exception
-        exceptionCaught = false;
-        try {
-            assertEquals(null, deviceManager.findDevice(entity3.getMacAddress(),
-                                                        entity3.getVlan(),
-                                                        entity3.getIpv4Address(),
-                                                        null,
-                                                        null));
-        }
-        catch (IllegalArgumentException e) {
-            exceptionCaught = true;
-        }
-        if (!exceptionCaught)
-            fail("findDevice() did not throw IllegalArgumentException");
-        assertEquals(d4, deviceManager.findDeviceByEntity(entity4));
-        assertEquals(d5, deviceManager.findDevice(entity5.getMacAddress(),
-                                                  entity5.getVlan(),
-                                                  entity5.getIpv4Address(),
-                                                  entity5.getSwitchDPID(),
-                                                  entity5.getSwitchPort()));
-        // switch and port not set. throws exception (swith/port are key
-        // fields of IEntityClassifier but not d5.entityClass
-        exceptionCaught = false;
-        try {
-            assertEquals(d5, deviceManager.findDevice(entity5.getMacAddress(),
-                                                      entity5.getVlan(),
-                                                      entity5.getIpv4Address(),
-                                                      null,
-                                                      null));
-        }
-        catch (IllegalArgumentException e) {
-            exceptionCaught = true;
-        }
-        if (!exceptionCaught)
-            fail("findDevice() did not throw IllegalArgumentException");
-
-
-        Entity entityNoClass = new Entity(5L, (short)1, 5, -1L, 1, new Date());
-        assertEquals(null, deviceManager.findDeviceByEntity(entityNoClass));
-
-
-        // Now look up destination devices
-        assertEquals(d1, deviceManager.findClassDevice(d2.getEntityClass(),
-                                                  entity1.getMacAddress(),
-                                                  entity1.getVlan(),
-                                                  entity1.getIpv4Address()));
-        assertEquals(d1, deviceManager.findClassDevice(d2.getEntityClass(),
-                                                  entity1.getMacAddress(),
-                                                  entity1.getVlan(),
-                                                  null));
-        assertEquals(null, deviceManager.findClassDevice(d2.getEntityClass(),
-                                                  entity1.getMacAddress(),
-                                                  (short) -1,
-                                                  0));
-    }
-
-
-
-    @Test
-    public void testGetIPv4Addresses() {
-        // Looks like Date is only 1s granularity
-
-        ITopologyService mockTopology = createMock(ITopologyService.class);
-        deviceManager.topology = mockTopology;
-        expect(mockTopology.isAttachmentPointPort(anyLong(),
-                                                  anyShort())).
-                                                  andReturn(true).anyTimes();
-        expect(mockTopology.getL2DomainId(anyLong())).andReturn(1L).anyTimes();
-        expect(mockTopology.isConsistent(EasyMock.anyLong(),
-                                         EasyMock.anyShort(),
-                                         EasyMock.anyLong(),
-                                         EasyMock.anyShort()))
-                                         .andReturn(false)
-                                         .anyTimes();
-        expect(mockTopology.isBroadcastDomainPort(EasyMock.anyLong(),
-                                                  EasyMock.anyShort()))
-                                                  .andReturn(false)
-                                                  .anyTimes();
-        expect(mockTopology.isInSameBroadcastDomain(EasyMock.anyLong(),
-                                                    EasyMock.anyShort(),
-                                                    EasyMock.anyLong(),
-                                                    EasyMock.anyShort())).
-                                                    andReturn(false).anyTimes();
-        replay(mockTopology);
-
-        Entity e1 = new Entity(1L, (short)1, null, null, null, new Date(2000));
-        Device d1 = deviceManager.learnDeviceByEntity(e1);
-        assertArrayEquals(new Integer[0], d1.getIPv4Addresses());
-
-
-        Entity e2 = new Entity(2L, (short)2, 2, null, null, new Date(2000));
-        Device d2 = deviceManager.learnDeviceByEntity(e2);
-        d2 = deviceManager.learnDeviceByEntity(e2);
-        assertArrayEquals(new Integer[] { 2 }, d2.getIPv4Addresses());
-        // More than one entity
-        Entity e2b = new Entity(2L, (short)2, null, 2L, 2, new Date(3000));
-        d2 = deviceManager.learnDeviceByEntity(e2b);
-        assertEquals(2, d2.entities.length);
-        assertArrayEquals(new Integer[] { 2 }, d2.getIPv4Addresses());
-        // and now add an entity with an IP
-        Entity e2c = new Entity(2L, (short)2, 2, 2L, 3, new Date(3000));
-        d2 = deviceManager.learnDeviceByEntity(e2c);
-        assertArrayEquals(new Integer[] { 2 }, d2.getIPv4Addresses());
-        assertEquals(3, d2.entities.length);
-
-        // Other devices with different IPs shouldn't interfere
-        Entity e3 = new Entity(3L, (short)3, 3, null, null, new Date(4000));
-        Entity e3b = new Entity(3L, (short)3, 3, 3L, 3, new Date(4400));
-        Device d3 = deviceManager.learnDeviceByEntity(e3);
-        d3 = deviceManager.learnDeviceByEntity(e3b);
-        assertArrayEquals(new Integer[] { 2 }, d2.getIPv4Addresses());
-        assertArrayEquals(new Integer[] { 3 }, d3.getIPv4Addresses());
-
-        // Add another IP to d3
-        Entity e3c = new Entity(3L, (short)3, 33, 3L, 3, new Date(4400));
-        d3 = deviceManager.learnDeviceByEntity(e3c);
-        Integer[] ips = d3.getIPv4Addresses();
-        Arrays.sort(ips);
-        assertArrayEquals(new Integer[] { 3, 33 }, ips);
-
-        // Add another device that also claims IP2 but is older than e2
-        Entity e4 = new Entity(4L, (short)4, 2, null, null, new Date(1000));
-        Entity e4b = new Entity(4L, (short)4, null, 4L, 4, new Date(1000));
-        Device d4 = deviceManager.learnDeviceByEntity(e4);
-        assertArrayEquals(new Integer[] { 2 }, d2.getIPv4Addresses());
-        assertArrayEquals(new Integer[0],  d4.getIPv4Addresses());
-        // add another entity to d4
-        d4 = deviceManager.learnDeviceByEntity(e4b);
-        assertArrayEquals(new Integer[0], d4.getIPv4Addresses());
-
-        // Make e4 and e4a newer
-        Entity e4c = new Entity(4L, (short)4, 2, null, null, new Date(5000));
-        Entity e4d = new Entity(4L, (short)4, null, 4L, 5, new Date(5000));
-        d4 = deviceManager.learnDeviceByEntity(e4c);
-        d4 = deviceManager.learnDeviceByEntity(e4d);
-        assertArrayEquals(new Integer[0], d2.getIPv4Addresses());
-        // FIXME: d4 should not return IP4
-        assertArrayEquals(new Integer[] { 2 }, d4.getIPv4Addresses());
-
-        // Add another newer entity to d2 but with different IP
-        Entity e2d = new Entity(2L, (short)2, 22, 4L, 6, new Date(6000));
-        d2 = deviceManager.learnDeviceByEntity(e2d);
-        assertArrayEquals(new Integer[] { 22 }, d2.getIPv4Addresses());
-        assertArrayEquals(new Integer[] { 2 }, d4.getIPv4Addresses());
-
-        // new IP for d2,d4 but with same timestamp. Both devices get the IP
-        Entity e2e = new Entity(2L, (short)2, 42, 2L, 4, new Date(7000));
-        d2 = deviceManager.learnDeviceByEntity(e2e);
-        ips= d2.getIPv4Addresses();
-        Arrays.sort(ips);
-        assertArrayEquals(new Integer[] { 22, 42 }, ips);
-        Entity e4e = new Entity(4L, (short)4, 42, 4L, 7, new Date(7000));
-        d4 = deviceManager.learnDeviceByEntity(e4e);
-        ips= d4.getIPv4Addresses();
-        Arrays.sort(ips);
-        assertArrayEquals(new Integer[] { 2, 42 }, ips);
-
-        // add a couple more IPs
-        Entity e2f = new Entity(2L, (short)2, 4242, 2L, 5, new Date(8000));
-        d2 = deviceManager.learnDeviceByEntity(e2f);
-        ips= d2.getIPv4Addresses();
-        Arrays.sort(ips);
-        assertArrayEquals(new Integer[] { 22, 42, 4242 }, ips);
-        Entity e4f = new Entity(4L, (short)4, 4242, 4L, 8, new Date(9000));
-        d4 = deviceManager.learnDeviceByEntity(e4f);
-        ips= d4.getIPv4Addresses();
-        Arrays.sort(ips);
-        assertArrayEquals(new Integer[] { 2, 42, 4242 }, ips);
-    }
-
-    // TODO: this test should really go into a separate class that collects
-    // unit tests for Device
-    @Test
-    public void testGetSwitchPortVlanId() {
-            Entity entity1 = new Entity(1L, (short)1, null, 10L, 1, new Date());
-            Entity entity2 = new Entity(1L, null, null, 10L, 1, new Date());
-            Entity entity3 = new Entity(1L, (short)3, null,  1L, 1, new Date());
-            Entity entity4 = new Entity(1L, (short)42, null,  1L, 1, new Date());
-            Entity[] entities = new Entity[] { entity1, entity2,
-                                               entity3, entity4
-                                             };
-            Device d = new Device(null,1L, null, null, null,
-                                  Arrays.asList(entities), null);
-            SwitchPort swp1x1 = new SwitchPort(1L, 1);
-            SwitchPort swp1x2 = new SwitchPort(1L, 2);
-            SwitchPort swp2x1 = new SwitchPort(2L, 1);
-            SwitchPort swp10x1 = new SwitchPort(10L, 1);
-            assertArrayEquals(new Short[] { -1, 1},
-                              d.getSwitchPortVlanIds(swp10x1));
-            assertArrayEquals(new Short[] { 3, 42},
-                              d.getSwitchPortVlanIds(swp1x1));
-            assertArrayEquals(new Short[0],
-                              d.getSwitchPortVlanIds(swp1x2));
-            assertArrayEquals(new Short[0],
-                              d.getSwitchPortVlanIds(swp2x1));
-    }
-
-    @Test
-    public void testReclassifyDevice() throws FloodlightModuleException {
-        MockFlexEntityClassifier flexClassifier =
-                new MockFlexEntityClassifier();
-        deviceManager.entityClassifier= flexClassifier;
-        deviceManager.startUp(null);
-
-        ITopologyService mockTopology = createMock(ITopologyService.class);
-        deviceManager.topology = mockTopology;
-        expect(mockTopology.isAttachmentPointPort(anyLong(),
-                                                  anyShort())).
-                                                  andReturn(true).anyTimes();
-        expect(mockTopology.getL2DomainId(anyLong())).andReturn(1L).anyTimes();
-        expect(mockTopology.isConsistent(EasyMock.anyLong(),
-                                         EasyMock.anyShort(),
-                                         EasyMock.anyLong(),
-                                         EasyMock.anyShort()))
-                                         .andReturn(false)
-                                         .anyTimes();
-        expect(mockTopology.isBroadcastDomainPort(EasyMock.anyLong(),
-                                                  EasyMock.anyShort()))
-                                                  .andReturn(false)
-                                                  .anyTimes();
-        replay(mockTopology);
-
-        //flexClassifier.createTestEntityClass("Class1");
-
-        Entity entity1 = new Entity(1L, (short)1, 1, 1L, 1, new Date());
-        Entity entity1b = new Entity(1L, (short)2, 1, 1L, 1, new Date());
-        Entity entity2 = new Entity(2L, (short)1, 2, 2L, 2, new Date());
-        Entity entity2b = new Entity(2L, (short)2, 2, 2L, 2, new Date());
-
-
-        Device d1 = deviceManager.learnDeviceByEntity(entity1);
-        Device d2 = deviceManager.learnDeviceByEntity(entity2);
-        Device d1b = deviceManager.learnDeviceByEntity(entity1b);
-        Device d2b = deviceManager.learnDeviceByEntity(entity2b);
-
-        d1 = deviceManager.getDeviceIteratorForQuery(entity1.getMacAddress(),
-                        entity1.getVlan(), entity1.getIpv4Address(),
-                        entity1.getSwitchDPID(), entity1.getSwitchPort())
-                        .next();
-        d1b = deviceManager.getDeviceIteratorForQuery(entity1b.getMacAddress(),
-                entity1b.getVlan(), entity1b.getIpv4Address(),
-                entity1b.getSwitchDPID(), entity1b.getSwitchPort()).next();
-
-        assertEquals(d1, d1b);
-
-        d2 = deviceManager.getDeviceIteratorForQuery(entity2.getMacAddress(),
-                entity2.getVlan(), entity2.getIpv4Address(),
-                entity2.getSwitchDPID(), entity2.getSwitchPort()).next();
-        d2b = deviceManager.getDeviceIteratorForQuery(entity2b.getMacAddress(),
-                entity2b.getVlan(), entity2b.getIpv4Address(),
-                entity2b.getSwitchDPID(), entity2b.getSwitchPort()).next();
-        assertEquals(d2, d2b);
-
-        IEntityClass eC1 = flexClassifier.createTestEntityClass("C1");
-        IEntityClass eC2 = flexClassifier.createTestEntityClass("C2");
-
-        flexClassifier.addVlanEntities((short)1, eC1);
-        flexClassifier.addVlanEntities((short)2, eC1);
-
-        deviceManager.reclassifyDevice(d1);
-        deviceManager.reclassifyDevice(d2);
-
-        d1 = deviceManager.deviceMap.get(
-                deviceManager.primaryIndex.findByEntity(entity1));
-        d1b = deviceManager.deviceMap.get(
-                deviceManager.primaryIndex.findByEntity(entity1b));
-
-        assertEquals(d1, d1b);
-
-        d2 = deviceManager.deviceMap.get(
-                deviceManager.primaryIndex.findByEntity(entity2));
-        d2b = deviceManager.deviceMap.get(
-                deviceManager.primaryIndex.findByEntity(entity2b));
-
-        assertEquals(d2, d2b);
-
-        flexClassifier.addVlanEntities((short)1, eC2);
-
-        deviceManager.reclassifyDevice(d1);
-        deviceManager.reclassifyDevice(d2);
-        d1 = deviceManager.deviceMap.get(
-                deviceManager.primaryIndex.findByEntity(entity1));
-        d1b = deviceManager.deviceMap.get(
-                deviceManager.primaryIndex.findByEntity(entity1b));
-        d2 = deviceManager.deviceMap.get(
-                deviceManager.primaryIndex.findByEntity(entity2));
-        d2b = deviceManager.deviceMap.get(
-                deviceManager.primaryIndex.findByEntity(entity2b));
-
-        assertNotSame(d1, d1b);
-
-        assertNotSame(d2, d2b);
-
-        flexClassifier.addVlanEntities((short)1, eC1);
-        deviceManager.reclassifyDevice(d1);
-        deviceManager.reclassifyDevice(d2);
-        ClassState classState = deviceManager.classStateMap.get(eC1.getName());
-
-        Long deviceKey1 = null;
-        Long deviceKey1b = null;
-        Long deviceKey2 = null;
-        Long deviceKey2b = null;
-
-        deviceKey1 =
-                classState.classIndex.findByEntity(entity1);
-        deviceKey1b =
-                classState.classIndex.findByEntity(entity1b);
-        deviceKey2 =
-                classState.classIndex.findByEntity(entity2);
-        deviceKey2b =
-                classState.classIndex.findByEntity(entity2b);
-
-        assertEquals(deviceKey1, deviceKey1b);
-
-        assertEquals(deviceKey2, deviceKey2b);
-    }
-
-    @Test
-    public void testSyncEntity() {
-        Date d1 = new Date();
-        Date d2 = new Date(0);
-        Entity e1 = new Entity(1L, (short)2, 3, 4L, 5, d1);
-        e1.setActiveSince(d2);
-        SyncEntity se1 = new SyncEntity(e1);
-        assertEntityEquals(e1, se1);
-        assertEquals(1L, se1.macAddress);
-        assertEquals(Short.valueOf((short)2), se1.vlan);
-        assertEquals(Integer.valueOf(3), se1.ipv4Address);
-        assertEquals(Long.valueOf(4L), se1.switchDPID);
-        assertEquals(Integer.valueOf(5), se1.switchPort);
-        assertEquals(d1, se1.lastSeenTimestamp);
-        assertEquals(d2, se1.activeSince);
-        assertNotSame(d1, se1.lastSeenTimestamp);
-        assertNotSame(d2, se1.activeSince);
-
-        Entity e2 = new Entity(42L, null, null, null, null, null);
-        SyncEntity se2 = new SyncEntity(e2);
-        assertEntityEquals(e2, se2);
-
-        SyncEntity se3 = new SyncEntity();
-        SyncEntity se4 = new SyncEntity();
-        se3.lastSeenTimestamp = new Date(1000);
-        se4.lastSeenTimestamp = new Date(2000);
-        assertTrue("", se3.compareTo(se4) < 0);
-        assertTrue("", se4.compareTo(se3) > 0);
-        se4.lastSeenTimestamp = new Date(1000);
-        assertTrue("", se3.compareTo(se4) == 0);
-        assertTrue("", se4.compareTo(se3) == 0);
-        se4.lastSeenTimestamp = new Date(500);
-        assertTrue("", se3.compareTo(se4) > 0);
-        assertTrue("", se4.compareTo(se3) < 0);
-    }
-
-    /* Test basic DeviceSyncRepresentation behavior */
-    @Test
-    public void testDeviceSyncRepresentationBasics() {
-        DeviceSyncRepresentation dsr = new DeviceSyncRepresentation();
-        assertNull(dsr.getKey());
-        assertNull(dsr.getEntities());
-        dsr.setKey("MyKey");
-        assertEquals("MyKey", dsr.getKey());
-        assertEquals("MyKey", dsr.toString());
-
-        List<SyncEntity> entities = new ArrayList<SyncEntity>();
-        Entity e1a = new Entity(1L, (short)2, 3, 4L, 5, new Date(1000));
-        Entity e1b = new Entity(1L, (short)2, null, 4L, 5, new Date(0));
-        entities.add(new SyncEntity(e1a));
-        entities.add(new SyncEntity(e1b));
-        // e1b comes before e1 (lastSeen) but we add it after it to test
-        // sorting
-        dsr.setEntities(entities);
-
-        assertEquals(2, dsr.getEntities().size());
-        // e1b has earlier time
-        assertEquals(e1b, dsr.getEntities().get(0).asEntity());
-        assertEquals(e1a, dsr.getEntities().get(1).asEntity());
-
-        dsr.setKey(null);
-        dsr.setEntities(null);
-        assertNull(dsr.getKey());
-        assertNull(dsr.getEntities());
-    }
-
-    @Test
-    public void testDeviceSyncRepresentationFromDevice() {
-        ITopologyService mockTopology = makeMockTopologyAllPortsAp();
-        replay(mockTopology);
-        deviceManager.topology = mockTopology;
-
-        deviceManager.entityClassifier = new MockEntityClassifier();
-
-        //**************************************
-        // Test 1: a single entity
-        Entity e1 = new Entity(1L, (short)2, 3, 4L, 5, new Date(1000));
-        Device d1 = deviceManager.learnDeviceByEntity(e1);
-        assertEquals("Sanity check failed. Device doesn't have the expected " +
-                     "entity class. Something with the test setup is strange",
-                     "DefaultEntityClass", d1.getEntityClass().getName());
-        assertEquals("Sanity check failed. Device doesn't have the expected " +
-                     "entity class. Something with the test setup is strange",
-                     EnumSet.of(DeviceField.MAC, DeviceField.VLAN),
-                     d1.getEntityClass().getKeyFields());
-
-        Long deviceKey = d1.getDeviceKey();
-        DeviceSyncRepresentation dsr1 = new DeviceSyncRepresentation(d1);
-        assertEquals("DefaultEntityClass::00:00:00:00:00:01::[2]::",
-                     dsr1.getKey());
-        assertEquals(1, dsr1.getEntities().size());
-        assertEquals(e1, dsr1.getEntities().get(0).asEntity());
-
-        //**************************************
-        // Test 1b: same device, now with a second entity (no IP).
-        // this second entity has a lastSeen time that is earlier than the
-        // first entity
-        Entity e1b = new Entity(1L, (short)2, null, 4L, 5, new Date(0));
-        d1 = deviceManager.learnDeviceByEntity(e1b);
-        assertEquals("Sanity check failed. Should still be same device but " +
-                     "deviceKeys differs", deviceKey, d1.getDeviceKey());
-        dsr1 = new DeviceSyncRepresentation(d1);
-        assertEquals("DefaultEntityClass::00:00:00:00:00:01::[2]::",
-                     dsr1.getKey());
-        assertEquals(2, dsr1.getEntities().size());
-        // Entities are ordered by their lastSeen time. e1b should come
-        // before e1.
-        assertEquals(e1, dsr1.getEntities().get(1).asEntity());
-        assertEquals(e1b, dsr1.getEntities().get(0).asEntity());
-
-        //**************************************
-        // Test 1c: same device with a third entity that does not have a
-        // switch port. It should be added to the DeviceSyncRepresentation
-        Entity e1c = new Entity(1L, (short)2, 33, null, null, new Date(2000));
-        d1 = deviceManager.learnDeviceByEntity(e1c);
-        assertEquals("Sanity check failed. Should still be same device but " +
-                     "deviceKeys differs", deviceKey, d1.getDeviceKey());
-        dsr1 = new DeviceSyncRepresentation(d1);
-        assertEquals("DefaultEntityClass::00:00:00:00:00:01::[2]::",
-                     dsr1.getKey());
-        assertEquals(3, dsr1.getEntities().size());
-        // Entities are ordered by their lastSeen time
-        assertEquals(e1c, dsr1.getEntities().get(2).asEntity());
-        assertEquals(e1, dsr1.getEntities().get(1).asEntity());
-        assertEquals(e1b, dsr1.getEntities().get(0).asEntity());
-
-        //**************************************
-        // Test 1d: same device with a fourth entity that has a different
-        // attachment point and that is newer. Device should move and
-        // non-attachment point entities should be removed (e1b). Although
-        // e1 is non-attachment point it will remain because it has an IP
-        Entity e1d = new Entity(1L, (short)2, 33, 4L, 6, new Date(3000));
-        d1 = deviceManager.learnDeviceByEntity(e1d);
-        assertEquals("Sanity check failed. Should still be same device but " +
-                     "deviceKeys differs", deviceKey, d1.getDeviceKey());
-        dsr1 = new DeviceSyncRepresentation(d1);
-        assertEquals("DefaultEntityClass::00:00:00:00:00:01::[2]::",
-                     dsr1.getKey());
-        assertEquals(3, dsr1.getEntities().size());
-        assertEquals(e1, dsr1.getEntities().get(0).asEntity());
-        assertEquals(e1c, dsr1.getEntities().get(1).asEntity());
-        assertEquals(e1d, dsr1.getEntities().get(2).asEntity());
-
-        d1 = null;
-
-
-        //**************************************
-        // Test 2: a second device with a different entity class. The
-        // mock entity classifier will return an entity class where all
-        // fields are keys if the DPID is > 10L
-        Entity e2 = new Entity(2L, (short)23, 24, 11L, 1, new Date(0));
-        Device d2 = deviceManager.learnDeviceByEntity(e2);
-        DeviceSyncRepresentation dsr2 = new DeviceSyncRepresentation(d2);
-        assertEquals("Sanity check failed. Device doesn't have the expected " +
-                     "entity class. Something with the test setup is strange",
-                     "TestEntityClass", d2.getEntityClass().getName());
-        assertEquals("Sanity check failed. Device doesn't have the expected " +
-                     "entity class. Something with the test setup is strange",
-                     EnumSet.of(DeviceField.MAC, DeviceField.VLAN,
-                                DeviceField.SWITCH, DeviceField.PORT),
-                     d2.getEntityClass().getKeyFields());
-        SwitchPort swp = new SwitchPort(11L, 1, null);
-        assertEquals("TestEntityClass::00:00:00:00:00:02::[23]::[" +
-                     swp.toString() + "]::",
-                     dsr2.getKey());
-    }
-
-    /* interate through all entries in the sync store and return them as
-     * list. We don't return the key from the store however, we assert
-     * that the key from the store matches the key in the representation.
-     * If we have a null value (tombstone) we simply add the null value to
-     * the list to return.
-     */
-    private List<DeviceSyncRepresentation> getEntriesFromStore()
-            throws Exception {
-        List<DeviceSyncRepresentation> entries =
-                new ArrayList<DeviceSyncRepresentation>();
-        IClosableIterator<Entry<String, Versioned<DeviceSyncRepresentation>>> iter =
-                storeClient.entries();
-        try {
-            while(iter.hasNext()) {
-                Entry<String, Versioned<DeviceSyncRepresentation>> entry =
-                        iter.next();
-                DeviceSyncRepresentation dsr = entry.getValue().getValue();
-                if (dsr != null)
-                    assertEquals(entry.getKey(), dsr.getKey());
-                entries.add(dsr);
-            }
-        } finally {
-            if (iter != null)
-                iter.close();
-        }
-        return entries;
-    }
-
-    /*
-     * assert whether the given Entity expected is equals to the given
-     * SyncEntity actual. This method also compares the times (lastSeen,
-     * activeSince). Entity.equals will not do that!
-     */
-    private static void assertEntityEquals(Entity expected, SyncEntity actual) {
-        assertNotNull(actual);
-        assertNotNull(expected);
-        Entity actualEntity = actual.asEntity();
-        assertEquals("entityFields", expected, actualEntity);
-        assertEquals("lastSeenTimestamp",
-                     expected.getLastSeenTimestamp(),
-                     actualEntity.getLastSeenTimestamp());
-        assertEquals("activeSince",
-                     expected.getActiveSince(), actualEntity.getActiveSince());
-    }
-
-    /* This test tests the normal operation as master when we write to the sync
-     * store or delete from the store.
-     */
-    @Test
-    public void testWriteToSyncStore() throws Exception {
-        int syncStoreIntervalMs = 50;
-        ITopologyService mockTopology = makeMockTopologyAllPortsAp();
-        replay(mockTopology);
-        deviceManager.topology = mockTopology;
-        deviceManager.setSyncStoreWriteInterval(syncStoreIntervalMs);
-
-        Entity e1a = new Entity(1L, (short)2, 3, 4L, 5, new Date(1000));
-        e1a.setActiveSince(new Date(0));
-        deviceManager.learnDeviceByEntity(e1a);
-
-        //storeClient.put("FooBar", new DeviceSyncRepresentation());
-
-        List<DeviceSyncRepresentation> entries = getEntriesFromStore();
-        assertEquals(1, entries.size());
-        DeviceSyncRepresentation dsr1 = entries.get(0);
-        assertEquals(1, dsr1.getEntities().size());
-        assertEntityEquals(e1a, dsr1.getEntities().get(0));
-
-        // Same entity but newer timestamp. Since the device hasn't changed,
-        // only the timestamp is updated and the write should be throttled.
-        Entity e1b = new Entity(1L, (short)2, 3, 4L, 5, new Date(2000));
-        e1b.setActiveSince(new Date(0));
-        deviceManager.learnDeviceByEntity(e1a);
-        entries = getEntriesFromStore();
-        assertEquals(1, entries.size());
-        dsr1 = entries.get(0);
-        assertEquals(1, dsr1.getEntities().size());
-        assertEntityEquals(e1a, dsr1.getEntities().get(0)); //e1a not e1b !!!
-
-        // Wait for the write interval to expire then write again.
-        Thread.sleep(syncStoreIntervalMs+5);
-        Entity e1c = new Entity(1L, (short)2, 3, 4L, 5, new Date(3000));
-        e1c.setActiveSince(new Date(0));
-        deviceManager.learnDeviceByEntity(e1c);
-        entries = getEntriesFromStore();
-        assertEquals(1, entries.size());
-        dsr1 = entries.get(0);
-        assertEquals(1, dsr1.getEntities().size());
-        assertEntityEquals(e1c, dsr1.getEntities().get(0)); // e1c !!
-
-        // Entity for same device but with different IP. should be added
-        // immediately
-        Entity e1d = new Entity(1L, (short)2, 33, 4L, 5, new Date(4000));
-        e1d.setActiveSince(new Date(0));
-        deviceManager.learnDeviceByEntity(e1d);
-        entries = getEntriesFromStore();
-        assertEquals(1, entries.size());
-        dsr1 = entries.get(0);
-        assertEquals(2, dsr1.getEntities().size());
-        assertEntityEquals(e1c, dsr1.getEntities().get(0)); // e1c !!
-        assertEntityEquals(e1d, dsr1.getEntities().get(1)); // e1d !!
-
-        // Entity for same device with new switch port ==> moved ==> write
-        // update immediately without throttle.
-        // Note: the previous entities will still be there because they have
-        // IPs (even though they aren't for the current attachment point)
-        Entity e1e = new Entity(1L, (short)2, 33, 4L, 6, new Date(5000));
-        e1e.setActiveSince(new Date(0));
-        deviceManager.learnDeviceByEntity(e1e);
-        entries = getEntriesFromStore();
-        assertEquals(1, entries.size());
-        dsr1 = entries.get(0);
-        assertEquals(3, dsr1.getEntities().size());
-        assertEntityEquals(e1c, dsr1.getEntities().get(0));
-        assertEntityEquals(e1d, dsr1.getEntities().get(1));
-        assertEntityEquals(e1e, dsr1.getEntities().get(2));
-
-        // Add a second device
-        Entity e2 = new Entity(2L, null, null, 5L, 5, new Date());
-        deviceManager.learnDeviceByEntity(e2);
-        entries = getEntriesFromStore();
-        assertEquals(2, entries.size());
-        for (DeviceSyncRepresentation dsr: entries) {
-            // This is a kinda ugly way to ensure we have the two
-            // devices we need..... but it will work for now
-            if (dsr.getKey().contains("::00:00:00:00:00:01::")) {
-                assertEquals(3, dsr.getEntities().size());
-                assertEntityEquals(e1c, dsr.getEntities().get(0));
-                assertEntityEquals(e1d, dsr.getEntities().get(1));
-                assertEntityEquals(e1e, dsr.getEntities().get(2));
-            } else if (dsr.getKey().contains("::00:00:00:00:00:02::")) {
-                assertEquals(1, dsr.getEntities().size());
-                assertEntityEquals(e2, dsr.getEntities().get(0));
-            } else {
-                fail("Unknown entry in store: " + dsr);
-            }
-        }
-
-
-        // Run entity cleanup. Since we've used phony time stamps for
-        // device 1 its entities should be cleared and the device should be
-        // removed from the store. Device 2 should remain in the store.
-        deviceManager.cleanupEntities();
-        entries = getEntriesFromStore();
-        assertEquals(2, entries.size());
-        for (DeviceSyncRepresentation dsr: entries) {
-            if (dsr == null) {
-                // pass
-            } else if (dsr.getKey().contains("::00:00:00:00:00:02::")) {
-                assertEquals(1, dsr.getEntities().size());
-                assertEntityEquals(e2, dsr.getEntities().get(0));
-            } else {
-                fail("Unknown entry in store: " + dsr);
-            }
-        }
-    }
-
-
-    private void assertDeviceIps(Integer[] expected, IDevice d) {
-        List<Integer> expectedList = Arrays.asList(expected);
-        Collections.sort(expectedList);
-        List<Integer> actualList = Arrays.asList(d.getIPv4Addresses());
-        Collections.sort(actualList);
-        assertEquals(expectedList, actualList);
-    }
-
-    private IDevice getSingleDeviceFromDeviceManager(long mac) {
-        Iterator<? extends IDevice> diter =
-                deviceManager.queryDevices(mac, null, null, null, null);
-        assertTrue("Query didn't return a device", diter.hasNext());
-        IDevice d = diter.next();
-        assertFalse("Query returned more than one device", diter.hasNext());
-        return d;
-    }
-
-    @Test
-    public void testToMaster() throws Exception {
-        int syncStoreWriteIntervalMs = 0;
-        int initialSyncStoreConsolidateIntervalMs = 50;
-        ITopologyService mockTopology = makeMockTopologyAllPortsAp();
-        replay(mockTopology);
-        deviceManager.topology = mockTopology;
-        // We want an EntityClassifier that has switch/port as key fields
-        deviceManager.entityClassifier = new MockEntityClassifier();
-        deviceManager.setSyncStoreWriteInterval(syncStoreWriteIntervalMs);
-        deviceManager.setInitialSyncStoreConsolidateMs(initialSyncStoreConsolidateIntervalMs);
-
-        // Add Device1 with two entities with two different IPs
-        Entity e1a = new Entity(1L, null, 3, 4L, 5, new Date(1000));
-        Entity e1b = new Entity(1L, null, 33,  4L, 5, new Date(2000));
-        Device d1 = deviceManager.allocateDevice(1L, e1a,
-                                                 DefaultEntityClassifier.entityClass);
-        d1 = deviceManager.allocateDevice(d1, e1b, -1);
-        DeviceSyncRepresentation dsr = new DeviceSyncRepresentation(d1);
-        storeClient.put(dsr.getKey(), dsr);
-
-        // Add Device2 with different switch-ports. Only the most recent
-        // one should be the attachment point
-        Entity e2a = new Entity(2L, null, null, 4L, 4, new Date(1000));
-        Entity e2b = new Entity(2L, null, null, 4L, 5, new Date(2000));
-        Device d2 = deviceManager.allocateDevice(2L, e2a,
-                                                 DefaultEntityClassifier.entityClass);
-        d2 = deviceManager.allocateDevice(d2, e2b, -1);
-        d2.updateAttachmentPoint(4L, (short)5,
-                                 e2b.getLastSeenTimestamp().getTime());
-        SwitchPort swp = new SwitchPort(4L, 5);
-        SwitchPort[] aps = d2.getAttachmentPoints();
-        // sanity check
-        assertArrayEquals("Sanity check: should only have AP(4L,5)",
-                          new SwitchPort[] {swp}, aps);
-        dsr = new DeviceSyncRepresentation(d2);
-        storeClient.put(dsr.getKey(), dsr);
-
-        // Add a tombstone entry to the store to make sure we don't trip a
-        // NPE
-        dsr = null;
-        Versioned<DeviceSyncRepresentation> versionedDsr =
-                storeClient.get("FooBar");
-        storeClient.put("FooBar", versionedDsr);
-
-        deviceManager.getHAListener().transitionToMaster();
-
-        // Query for the Device1. Make sure we have the two IPs we stored.
-        IDevice d = getSingleDeviceFromDeviceManager(1L);
-        assertDeviceIps(new Integer[] {3, 33}, d);
-        assertArrayEquals(new Short[] { Ethernet.VLAN_UNTAGGED }, d.getVlanId());
-        swp = new SwitchPort(4L, 5);
-        assertArrayEquals(new SwitchPort[] { swp }, d.getAttachmentPoints());
-
-        // Query for Device2. Make sure we only have the more recent AP
-        // Query for the Device1. Make sure we have the two IPs we stored.
-        d = getSingleDeviceFromDeviceManager(2L);
-        assertArrayEquals(new Integer[0], d.getIPv4Addresses());
-        assertArrayEquals(new Short[] { Ethernet.VLAN_UNTAGGED }, d.getVlanId());
-        swp = new SwitchPort(4L, 5);
-        assertArrayEquals(new SwitchPort[] { swp }, d.getAttachmentPoints());
-
-        //----------------------------
-        // add another entry device to the store. since device manager is
-        // already master we won't read this device and it should be
-        // removed from the store by the consolidate task
-        Entity e3 = new Entity(3L, null, null, 1L, 1, null);
-        dsr = new DeviceSyncRepresentation();
-        dsr.setKey("Device3");
-        dsr.setEntities(Collections.singletonList(new SyncEntity(e3)));
-        storeClient.put(dsr.getKey(), dsr);
-
-        // make sure it's in the store
-        List<DeviceSyncRepresentation> entries = getEntriesFromStore();
-        boolean found = false;
-        for (DeviceSyncRepresentation entry: entries) {
-            if (entry!=null && entry.getKey().equals("Device3"))
-                found = true;
-        }
-        assertTrue("Device3 not in store. Entries in store: " + entries, found);
-        // make sure it's not in DevManager
-        Iterator<? extends IDevice> diter =
-                deviceManager.queryDevices(3L, null, null, null, null);
-        assertFalse("Device3 found in DeviceManager. Should be there",
-                    diter.hasNext());
-
-        // Wait for consolidate
-        Thread.sleep(initialSyncStoreConsolidateIntervalMs + 5);
-        // make sure it's in NOT the store
-        entries = getEntriesFromStore();
-        found = false;
-        for (DeviceSyncRepresentation entry: entries) {
-            if (entry!=null && entry.getKey().equals("Device3"))
-                found = true;
-        }
-        assertFalse("Device3 not is still in the store. Entries in store: "
-                    + entries, found);
-        // make sure it's not in DevManager
-        diter = deviceManager.queryDevices(3L, null, null, null, null);
-        assertFalse("Device3 found in DeviceManager. Should be there",
-                    diter.hasNext());
-    }
-
-
-    @Test
-    public void testConsolitateStore() throws Exception {
-        int syncStoreInternalMs = 0;
-        ITopologyService mockTopology = makeMockTopologyAllPortsAp();
-        replay(mockTopology);
-        deviceManager.topology = mockTopology;
-        // We want an EntityClassifier that has switch/port as key fields
-        deviceManager.entityClassifier = new MockEntityClassifier();
-        deviceManager.setSyncStoreWriteInterval(syncStoreInternalMs);
-
-        // Add Device1 with two entities to store and let device manager
-        // learn
-        Entity e1a = new Entity(1L, null, null, 4L, 5, new Date(1000));
-        Entity e1b = new Entity(1L, null, 3,  4L, 5, new Date(2000));
-        Device d1 = deviceManager.learnDeviceByEntity(e1a);
-        deviceManager.learnDeviceByEntity(e1b);
-        String dev1Key = DeviceSyncRepresentation.computeKey(d1);
-
-
-        // Add a second device to the store but do NOT add to device manager
-        Entity e2 = new Entity(2L, null, null, 5L, 5, new Date());
-        Device d2 = deviceManager.allocateDevice(42L, e2,
-                                                 DefaultEntityClassifier.entityClass);
-        DeviceSyncRepresentation dsr = new DeviceSyncRepresentation(d2);
-        storeClient.put(dsr.getKey(), dsr);
-        String dev2Key = DeviceSyncRepresentation.computeKey(d2);
-
-        // Make sure we have two devices in the store
-        List<DeviceSyncRepresentation> entries = getEntriesFromStore();
-        assertEquals(2, entries.size());
-
-        deviceManager.scheduleConsolidateStoreNow();
-        Thread.sleep(25); // give the scheduler time to run the task
-
-        // We should still have two entries, however one of them will be a
-        // tombstone
-        entries = getEntriesFromStore();
-        assertEquals(2, entries.size());
-
-        // Device 1 should still be in store
-        Versioned<DeviceSyncRepresentation> versioned =
-                storeClient.get(dev1Key);
-        dsr = versioned.getValue();
-        assertNotNull(dsr);
-        assertEquals(2, dsr.getEntities().size());
-        assertEntityEquals(e1a, dsr.getEntities().get(0));
-        assertEntityEquals(e1b, dsr.getEntities().get(1));
-
-        // Device2 should be gone
-        versioned = storeClient.get(dev2Key);
-        assertNull(versioned.getValue());
-
-        // Run consolitate again. This time we check that tombstones in
-        // the store are handled correctly
-        deviceManager.scheduleConsolidateStoreNow();
-        Thread.sleep(25); // give the scheduler time to run the task
-
-        // Now write a device to the store that doesn't have any switch-port
-        // it should be removed
-        Entity e3 = new Entity(3L, null, null, null, null, null);
-        dsr.setKey("Device3");
-        dsr.setEntities(Collections.singletonList(new SyncEntity(e3)));
-        storeClient.put(dsr.getKey(), dsr);
-
-        // Run consolitate again. This time we check that tombstones in
-        // the store are handled correctly
-        deviceManager.scheduleConsolidateStoreNow();
-        Thread.sleep(25); // give the scheduler time to run the task
-        versioned = storeClient.get("Device3");
-        assertNull(versioned.getValue());
-
-    }
+	protected static Logger logger =
+			LoggerFactory.getLogger(DeviceManagerImplTest.class);
+
+	protected OFPacketIn testARPReplyPacketIn_1, testARPReplyPacketIn_2;
+	protected OFPacketIn testUDPPacketIn;
+	protected IPacket testARPReplyPacket_1, testARPReplyPacket_2;
+	protected Ethernet testUDPPacket;
+	protected byte[] testARPReplyPacket_1_Srld, testARPReplyPacket_2_Srld;
+	protected byte[] testUDPPacketSrld;
+	private MockSyncService syncService;
+	private IStoreClient<String, DeviceSyncRepresentation> storeClient;
+
+	DeviceManagerImpl deviceManager;
+	MemoryStorageSource storageSource;
+	FlowReconcileManager flowReconcileMgr;
+
+	private IOFSwitch makeSwitchMock(DatapathId id) {
+		IOFSwitch mockSwitch = createMock(IOFSwitch.class);
+		OFPort port = OFPort.of(1);
+		expect(mockSwitch.getId()).andReturn(id).anyTimes();
+		expect(mockSwitch.getId().toString()).andReturn(id.toString()).anyTimes();
+		expect(mockSwitch.getPort(OFPort.of(anyShort())).getPortNo()).andReturn(port).anyTimes();
+		return mockSwitch;
+	}
+
+	/*
+	 * return an EasyMock ITopologyService that's setup so that it will
+	 * answer all questions a device or device manager will ask
+	 * (isAttachmentPointPort, etc.) in a way so that every port is a
+	 * non-BD, attachment point port.
+	 * The returned mock is still in record mode
+	 */
+	private ITopologyService makeMockTopologyAllPortsAp() {
+		ITopologyService mockTopology = createMock(ITopologyService.class);
+		mockTopology.isAttachmentPointPort(DatapathId.of(anyLong()), OFPort.of(anyShort()));
+		expectLastCall().andReturn(true).anyTimes();
+		mockTopology.getL2DomainId(DatapathId.of(anyLong()));
+		expectLastCall().andReturn(1L).anyTimes();
+		mockTopology.isBroadcastDomainPort(DatapathId.of(anyLong()), OFPort.of(anyShort()));
+		expectLastCall().andReturn(false).anyTimes();
+		mockTopology.isConsistent(DatapathId.of(anyLong()), OFPort.of(anyShort()), DatapathId.of(anyLong()), OFPort.of(anyShort()));
+		expectLastCall().andReturn(false).anyTimes();
+		mockTopology.isInSameBroadcastDomain(DatapathId.of(anyLong()), OFPort.of(anyShort()), DatapathId.of(anyLong()), OFPort.of(anyShort()));
+		expectLastCall().andReturn(false).anyTimes();
+		return mockTopology;
+	}
+
+	@Override
+	@Before
+	public void setUp() throws Exception {
+		doSetUp(HARole.ACTIVE);
+	}
+
+	public void doSetUp(HARole initialRole) throws Exception {
+		super.setUp();
+
+		this.syncService = new MockSyncService();
+
+		FloodlightModuleContext fmc = new FloodlightModuleContext();
+		RestApiServer restApi = new RestApiServer();
+		MockThreadPoolService tp = new MockThreadPoolService();
+		ITopologyService topology = createMock(ITopologyService.class);
+		fmc.addService(IThreadPoolService.class, tp);
+		mockFloodlightProvider = getMockFloodlightProvider();
+		mockFloodlightProvider.setRole(initialRole, "");
+
+
+		deviceManager = new DeviceManagerImpl();
+		flowReconcileMgr = new FlowReconcileManager();
+		DefaultEntityClassifier entityClassifier = new DefaultEntityClassifier();
+		fmc.addService(IDeviceService.class, deviceManager);
+		storageSource = new MemoryStorageSource();
+		fmc.addService(IStorageSourceService.class, storageSource);
+		fmc.addService(IFloodlightProviderService.class, mockFloodlightProvider);
+		fmc.addService(IRestApiService.class, restApi);
+		fmc.addService(IFlowReconcileService.class, flowReconcileMgr);
+		fmc.addService(IEntityClassifierService.class, entityClassifier);
+		fmc.addService(ITopologyService.class, topology);
+		fmc.addService(ISyncService.class, syncService);
+		tp.init(fmc);
+		restApi.init(fmc);
+		storageSource.init(fmc);
+		deviceManager.init(fmc);
+		flowReconcileMgr.init(fmc);
+		entityClassifier.init(fmc);
+		syncService.init(fmc);
+		storageSource.startUp(fmc);
+		deviceManager.startUp(fmc);
+		flowReconcileMgr.startUp(fmc);
+		tp.startUp(fmc);
+		entityClassifier.startUp(fmc);
+		syncService.startUp(fmc);
+
+		this.storeClient =
+				this.syncService.getStoreClient(DeviceManagerImpl.DEVICE_SYNC_STORE_NAME,
+						String.class, DeviceSyncRepresentation.class);
+
+		reset(topology);
+		topology.addListener(deviceManager);
+		expectLastCall().anyTimes();
+		replay(topology);
+
+		IOFSwitch mockSwitch1 = makeSwitchMock(DatapathId.of(1L));
+		IOFSwitch mockSwitch10 = makeSwitchMock(DatapathId.of(10L));
+		IOFSwitch mockSwitch5 = makeSwitchMock(DatapathId.of(5L));
+		IOFSwitch mockSwitch50 = makeSwitchMock(DatapathId.of(50L));
+		Map<DatapathId, IOFSwitch> switches = new HashMap<DatapathId, IOFSwitch>();
+		switches.put(DatapathId.of(1L), mockSwitch1);
+		switches.put(DatapathId.of(10L), mockSwitch10);
+		switches.put(DatapathId.of(5L), mockSwitch5);
+		switches.put(DatapathId.of(50L), mockSwitch50);
+		getMockSwitchService().setSwitches(switches);
+
+		replay(mockSwitch1, mockSwitch5, mockSwitch10, mockSwitch50);
+
+		// Build our test packet
+		this.testARPReplyPacket_1 = new Ethernet()
+		.setSourceMACAddress("00:44:33:22:11:01")
+		.setDestinationMACAddress("00:11:22:33:44:55")
+		.setEtherType(Ethernet.TYPE_ARP)
+		.setVlanID((short)5)
+		.setPayload(
+				new ARP()
+				.setHardwareType(ARP.HW_TYPE_ETHERNET)
+				.setProtocolType(ARP.PROTO_TYPE_IP)
+				.setHardwareAddressLength((byte) 6)
+				.setProtocolAddressLength((byte) 4)
+				.setOpCode(ARP.OP_REPLY)
+				.setSenderHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:01"))
+				.setSenderProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.1"))
+				.setTargetHardwareAddress(Ethernet.toMACAddress("00:11:22:33:44:55"))
+				.setTargetProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.2")));
+		this.testARPReplyPacket_1_Srld = testARPReplyPacket_1.serialize();
+
+		// Another test packet with the same ARP payload as packet 1 but with
+		// a different source MAC. (i.e., sender MAC and source MAC differ)
+		this.testARPReplyPacket_2 = new Ethernet()
+		.setSourceMACAddress("00:99:88:77:66:55")
+		.setDestinationMACAddress("00:11:22:33:44:55")
+		.setEtherType(Ethernet.TYPE_ARP)
+		.setVlanID((short)5)
+		.setPayload(
+				new ARP()
+				.setHardwareType(ARP.HW_TYPE_ETHERNET)
+				.setProtocolType(ARP.PROTO_TYPE_IP)
+				.setHardwareAddressLength((byte) 6)
+				.setProtocolAddressLength((byte) 4)
+				.setOpCode(ARP.OP_REPLY)
+				.setSenderHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:01"))
+				.setSenderProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.1"))
+				.setTargetHardwareAddress(Ethernet.toMACAddress("00:11:22:33:44:55"))
+				.setTargetProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.2")));
+		this.testARPReplyPacket_2_Srld = testARPReplyPacket_2.serialize();
+
+		// This packet reverses the MACs and IP from testARPReplyPacket_1
+		this.testUDPPacket = (Ethernet) new Ethernet()
+		.setSourceMACAddress("00:11:22:33:44:55")
+		.setDestinationMACAddress("00:44:33:22:11:01")
+		.setEtherType(Ethernet.TYPE_IPv4)
+		.setVlanID((short)5)
+		.setPayload(
+				new IPv4()
+				.setTtl((byte) 128)
+				.setSourceAddress("192.168.1.2")
+				.setDestinationAddress("192.168.1.1")
+				.setPayload(new UDP()
+				.setSourcePort((short) 5000)
+				.setDestinationPort((short) 5001)
+				.setPayload(new Data(new byte[] {0x01}))));
+		updateUDPPacketIn();
+
+		// Build the PacketIn
+		this.testARPReplyPacketIn_1 = OFFactories.getFactory(OFVersion.OF_13).buildPacketIn()
+				.setBufferId(OFBufferId.NO_BUFFER)
+				.setInPort(OFPort.of(1))
+				.setData(this.testARPReplyPacket_1_Srld)
+				.setReason(OFPacketInReason.NO_MATCH)
+				.build();
+
+		// Build the PacketIn
+		this.testARPReplyPacketIn_2 = OFFactories.getFactory(OFVersion.OF_13).buildPacketIn()
+				.setBufferId(OFBufferId.NO_BUFFER)
+				.setInPort(OFPort.of(1))
+				.setData(this.testARPReplyPacket_2_Srld)
+				.setReason(OFPacketInReason.NO_MATCH)
+				.build();
+	}
+
+	/**
+	 * Updates testUDPPacketIn and testUDPPacketSrld from testUDPPacket
+	 * To be called after testUDPPacket has been mangled.
+	 */
+	private void updateUDPPacketIn() {
+		this.testUDPPacketSrld = this.testUDPPacket.serialize();
+		// Build the PacketIn
+		this.testUDPPacketIn = OFFactories.getFactory(OFVersion.OF_13).buildPacketIn()
+				.setBufferId(OFBufferId.NO_BUFFER)
+				.setInPort(OFPort.of(3))
+				.setData(this.testUDPPacketSrld)
+				.setReason(OFPacketInReason.NO_MATCH)
+				.build();
+	}
+
+	@Test
+	public void testLastSeen() throws Exception {
+		Calendar c = Calendar.getInstance();
+		Date d1 = c.getTime();
+		Entity entity1 = new Entity(MacAddress.of(1L), null, null, null, null, d1);
+		c.add(Calendar.SECOND, 1);
+		Entity entity2 = new Entity(MacAddress.of(1L), null, IPv4Address.of(1), null, null, c.getTime());
+
+		IDevice d = deviceManager.learnDeviceByEntity(entity2);
+		assertEquals(c.getTime(), d.getLastSeen());
+		d = deviceManager.learnDeviceByEntity(entity1);
+		assertEquals(c.getTime(), d.getLastSeen());
+
+		deviceManager.startUp(null);
+		d = deviceManager.learnDeviceByEntity(entity1);
+		assertEquals(d1, d.getLastSeen());
+		d = deviceManager.learnDeviceByEntity(entity2);
+		assertEquals(c.getTime(), d.getLastSeen());
+	}
+
+
+	@Test
+	public void testEntityLearning() throws Exception {
+		IDeviceListener mockListener =
+				createMock(IDeviceListener.class);
+		expect(mockListener.getName()).andReturn("mockListener").atLeastOnce();
+		expect(mockListener.isCallbackOrderingPostreq((String)anyObject(), (String)anyObject()))
+		.andReturn(false).atLeastOnce();
+		expect(mockListener.isCallbackOrderingPrereq((String)anyObject(), (String)anyObject()))
+		.andReturn(false).atLeastOnce();
+
+		replay(mockListener);
+		deviceManager.addListener(mockListener);
+		verify(mockListener);
+		reset(mockListener);
+		deviceManager.entityClassifier= new MockEntityClassifier();
+		deviceManager.startUp(null);
+
+		ITopologyService mockTopology = createMock(ITopologyService.class);
+		expect(mockTopology.getL2DomainId(DatapathId.of(anyLong()))).
+		andReturn(DatapathId.of(1L)).anyTimes();
+		expect(mockTopology.isBroadcastDomainPort(DatapathId.of(anyLong()), OFPort.of(anyShort()))).
+		andReturn(false).anyTimes();
+
+		expect(mockTopology.isAttachmentPointPort(DatapathId.of(anyLong()),
+				OFPort.of(anyShort()))).andReturn(true).anyTimes();
+		expect(mockTopology.isConsistent(DatapathId.of(10L), OFPort.of(1), DatapathId.of(10L), OFPort.of(1))).
+		andReturn(true).anyTimes();
+		expect(mockTopology.isConsistent(DatapathId.of(1L), OFPort.of(1), DatapathId.of(1L), OFPort.of(1))).
+		andReturn(true).anyTimes();
+		expect(mockTopology.isConsistent(DatapathId.of(50L), OFPort.of(3), DatapathId.of(50L), OFPort.of(3))).
+		andReturn(true).anyTimes();
+
+		Date topologyUpdateTime = new Date();
+		expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
+		anyTimes();
+
+		deviceManager.topology = mockTopology;
+
+		Entity entity1 = new Entity(MacAddress.of(1L), null, null, DatapathId.of(1L), OFPort.of(1), new Date());
+		Entity entity2 = new Entity(MacAddress.of(1L), null, null, DatapathId.of(10L), OFPort.of(1), new Date());
+		Entity entity3 = new Entity(MacAddress.of(1L), null, IPv4Address.of(1), DatapathId.of(10L), OFPort.of(1), new Date());
+		Entity entity4 = new Entity(MacAddress.of(1L), null, IPv4Address.of(1), DatapathId.of(1L), OFPort.of(1), new Date());
+		Entity entity5 = new Entity(MacAddress.of(2L), VlanVid.ofVlan(4), IPv4Address.of(1), DatapathId.of(5L), OFPort.of(2), new Date());
+		Entity entity6 = new Entity(MacAddress.of(2L), VlanVid.ofVlan(4), IPv4Address.of(1), DatapathId.of(50L), OFPort.of(3), new Date());
+		Entity entity7 = new Entity(MacAddress.of(2L), VlanVid.ofVlan(4), IPv4Address.of(2), DatapathId.of(50L), OFPort.of(3), new Date());
+
+		mockListener.deviceAdded(isA(IDevice.class));
+		replay(mockListener, mockTopology);
+
+		Device d1 = deviceManager.learnDeviceByEntity(entity1);
+		assertSame(d1, deviceManager.learnDeviceByEntity(entity1));
+		assertSame(d1, deviceManager.findDeviceByEntity(entity1));
+		assertEquals(DefaultEntityClassifier.entityClass ,
+				d1.getEntityClass());
+		assertArrayEquals(new Short[] { -1 }, d1.getVlanId());
+		assertArrayEquals(new Integer[] { }, d1.getIPv4Addresses());
+
+		assertEquals(1, deviceManager.getAllDevices().size());
+		verify(mockListener);
+
+		reset(mockListener);
+		mockListener.deviceAdded(isA(IDevice.class));
+		replay(mockListener);
+
+		Device d2 = deviceManager.learnDeviceByEntity(entity2);
+		assertFalse(d1.equals(d2));
+		assertNotSame(d1, d2);
+		assertNotSame(d1.getDeviceKey(), d2.getDeviceKey());
+		assertEquals(MockEntityClassifier.testEC, d2.getEntityClass());
+		assertArrayEquals(new Short[] { -1 }, d2.getVlanId());
+		assertArrayEquals(new Integer[] { }, d2.getIPv4Addresses());
+
+		assertEquals(2, deviceManager.getAllDevices().size());
+		verify(mockListener);
+
+		reset(mockListener);
+		mockListener.deviceIPV4AddrChanged(isA(IDevice.class));
+		replay(mockListener);
+
+		Device d3 = deviceManager.learnDeviceByEntity(entity3);
+		assertNotSame(d2, d3);
+		assertEquals(d2.getDeviceKey(), d3.getDeviceKey());
+		assertEquals(MockEntityClassifier.testEC, d3.getEntityClass());
+		assertArrayEquals(new Integer[] { 1 },
+				d3.getIPv4Addresses());
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(10L), OFPort.of(1)) },
+				d3.getAttachmentPoints());
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(10L), OFPort.of(1)) },
+				d3.getAttachmentPoints(true));
+		assertArrayEquals(new Short[] { -1 },
+				d3.getVlanId());
+
+		assertEquals(2, deviceManager.getAllDevices().size());
+		verify(mockListener);
+
+		reset(mockListener);
+		mockListener.deviceIPV4AddrChanged(isA(IDevice.class));
+		replay(mockListener);
+
+		Device d4 = deviceManager.learnDeviceByEntity(entity4);
+		assertNotSame(d1, d4);
+		assertEquals(d1.getDeviceKey(), d4.getDeviceKey());
+		assertEquals(DefaultEntityClassifier.entityClass, d4.getEntityClass());
+		assertArrayEquals(new Integer[] { 1 },
+				d4.getIPv4Addresses());
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(1L), OFPort.of(1)) },
+				d4.getAttachmentPoints());
+		assertArrayEquals(new Short[] { -1 },
+				d4.getVlanId());
+
+		assertEquals(2, deviceManager.getAllDevices().size());
+		verify(mockListener);
+
+		reset(mockListener);
+		mockListener.deviceAdded((isA(IDevice.class)));
+		replay(mockListener);
+
+		Device d5 = deviceManager.learnDeviceByEntity(entity5);
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(5L), OFPort.of(2)) },
+				d5.getAttachmentPoints());
+		assertArrayEquals(new Short[] { (short) 4 },
+				d5.getVlanId());
+		assertEquals(2L, d5.getMACAddress());
+		assertEquals("00:00:00:00:00:02", d5.getMACAddressString());
+		verify(mockListener);
+
+		reset(mockListener);
+		mockListener.deviceAdded(isA(IDevice.class));
+		replay(mockListener);
+
+		Device d6 = deviceManager.learnDeviceByEntity(entity6);
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(50L), OFPort.of(3)) },
+				d6.getAttachmentPoints());
+		assertArrayEquals(new Short[] { (short) 4 },
+				d6.getVlanId());
+
+		assertEquals(4, deviceManager.getAllDevices().size());
+		verify(mockListener);
+
+		reset(mockListener);
+		mockListener.deviceIPV4AddrChanged(isA(IDevice.class));
+		replay(mockListener);
+
+		Device d7 = deviceManager.learnDeviceByEntity(entity7);
+		assertNotSame(d6, d7);
+		assertEquals(d6.getDeviceKey(), d7.getDeviceKey());
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(50L), OFPort.of(3)) },
+				d7.getAttachmentPoints());
+		assertArrayEquals(new Short[] { (short) 4 },
+				d7.getVlanId());
+
+		assertEquals(4, deviceManager.getAllDevices().size());
+		verify(mockListener);
+
+
+		reset(mockListener);
+		replay(mockListener);
+
+		reset(deviceManager.topology);
+		deviceManager.topology.addListener(deviceManager);
+		expectLastCall().times(1);
+		replay(deviceManager.topology);
+
+		deviceManager.entityClassifier = new MockEntityClassifierMac();
+		deviceManager.startUp(null);
+		Entity entityNoClass = new Entity(MacAddress.of(5L), VlanVid.ofVlan(1), IPv4Address.of(5), DatapathId.of(-1L), OFPort.of(1), new Date());
+		assertEquals(null, deviceManager.learnDeviceByEntity(entityNoClass));
+
+		verify(mockListener);
+	}
+
+
+	private void doTestEntityOrdering(boolean computeInsertionPoint) throws Exception {
+		Entity e = new Entity(MacAddress.of(10L), null, null, null, null, null);
+		IEntityClass ec = createNiceMock(IEntityClass.class);
+		Device d = new Device(deviceManager, 1L, e, ec);
+
+		int expectedLength = 1;
+		Long[] macs = new Long[] {  5L,  // new first element
+				15L,  // new last element
+				7L,  // insert in middle
+				12L,  // insert in middle
+				6L,  // insert at idx 1
+				14L,  // insert at idx length-2
+				1L,
+				20L
+		};
+
+		for (Long mac: macs) {
+			e = new Entity(MacAddress.of(mac), null, null, null, null, null);
+			int insertionPoint;
+			if (computeInsertionPoint) {
+				insertionPoint = -(Arrays.binarySearch(d.entities, e)+1);
+			} else {
+				insertionPoint = -1;
+			}
+			d = deviceManager.allocateDevice(d, e, insertionPoint);
+			expectedLength++;
+			assertEquals(expectedLength, d.entities.length);
+			for (int i = 0; i < d.entities.length-1; i++)
+				assertEquals(-1, d.entities[i].compareTo(d.entities[i+1]));
+		}
+	}
+
+	@Test
+	public void testEntityOrderingExternal() throws Exception {
+		doTestEntityOrdering(true);
+	}
+
+	@Test
+	public void testEntityOrderingInternal() throws Exception {
+		doTestEntityOrdering(false);
+	}
+
+	@Test
+	public void testAttachmentPointLearning() throws Exception {
+		IDeviceListener mockListener =
+				createMock(IDeviceListener.class);
+		expect(mockListener.getName()).andReturn("mockListener").atLeastOnce();
+		expect(mockListener.isCallbackOrderingPostreq((String)anyObject(), (String)anyObject()))
+		.andReturn(false).atLeastOnce();
+		expect(mockListener.isCallbackOrderingPrereq((String)anyObject(), (String)anyObject()))
+		.andReturn(false).atLeastOnce();
+
+		replay(mockListener);
+		deviceManager.addListener(mockListener);
+		verify(mockListener);
+		reset(mockListener);
+
+		ITopologyService mockTopology = createMock(ITopologyService.class);
+		expect(mockTopology.getL2DomainId(DatapathId.of(1L))).
+		andReturn(DatapathId.of(1L)).anyTimes();
+		expect(mockTopology.getL2DomainId(DatapathId.of(5L))).
+		andReturn(DatapathId.of(1L)).anyTimes();
+		expect(mockTopology.getL2DomainId(DatapathId.of(10L))).
+		andReturn(DatapathId.of(10L)).anyTimes();
+		expect(mockTopology.getL2DomainId(DatapathId.of(50L))).
+		andReturn(DatapathId.of(10L)).anyTimes();
+		expect(mockTopology.isBroadcastDomainPort(DatapathId.of(anyLong()), OFPort.of(anyShort()))).
+		andReturn(false).anyTimes();
+		expect(mockTopology.isInSameBroadcastDomain(DatapathId.of(anyLong()), OFPort.of(anyShort()),
+				DatapathId.of(anyLong()), OFPort.of(anyShort()))).andReturn(false).anyTimes();
+
+		expect(mockTopology.isAttachmentPointPort(DatapathId.of(anyLong()),
+				OFPort.of(anyShort()))).andReturn(true).anyTimes();
+		expect(mockTopology.isConsistent(DatapathId.of(1L), OFPort.of(1), DatapathId.of(5L), OFPort.of(1))).
+		andReturn(false).anyTimes();
+		expect(mockTopology.isConsistent(DatapathId.of(5L), OFPort.of(1), DatapathId.of(10L), OFPort.of(1))).
+		andReturn(false).anyTimes();
+		expect(mockTopology.isConsistent(DatapathId.of(10L), OFPort.of(1), DatapathId.of(50L), OFPort.of(1))).
+		andReturn(false).anyTimes();
+
+		Date topologyUpdateTime = new Date();
+		expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
+		anyTimes();
+
+		replay(mockTopology);
+
+		deviceManager.topology = mockTopology;
+
+		Calendar c = Calendar.getInstance();
+		Entity entity1 = new Entity(MacAddress.of(1L), null, IPv4Address.of(1), DatapathId.of(1L), OFPort.of(1), c.getTime());
+		Entity entity0 = new Entity(MacAddress.of(1L), null, null, null, null, c.getTime());
+		c.add(Calendar.SECOND, 1);
+		Entity entity2 = new Entity(MacAddress.of(1L), null, null, DatapathId.of(5L), OFPort.of(1), c.getTime());
+		c.add(Calendar.SECOND, 1);
+		Entity entity3 = new Entity(MacAddress.of(1L), null, null, DatapathId.of(10L), OFPort.of(1), c.getTime());
+		c.add(Calendar.SECOND, 1);
+		Entity entity4 = new Entity(MacAddress.of(1L), null, null, DatapathId.of(50L), OFPort.of(1), c.getTime());
+
+		IDevice d;
+		SwitchPort[] aps;
+		IPv4Address[] ips;
+
+		mockListener.deviceAdded(isA(IDevice.class));
+		replay(mockListener);
+
+		deviceManager.learnDeviceByEntity(entity1);
+		d = deviceManager.learnDeviceByEntity(entity0);
+		assertEquals(1, deviceManager.getAllDevices().size());
+		aps = d.getAttachmentPoints();
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(1L), OFPort.of(1)) }, aps);
+		ips = d.getIPv4Addresses();
+		assertArrayEquals(new Integer[] { 1 }, ips);
+		verify(mockListener);
+
+		reset(mockListener);
+		mockListener.deviceMoved((isA(IDevice.class)));
+		replay(mockListener);
+
+		d = deviceManager.learnDeviceByEntity(entity2);
+		assertEquals(1, deviceManager.getAllDevices().size());
+		aps = d.getAttachmentPoints();
+
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(5L), OFPort.of(1)) }, aps);
+		ips = d.getIPv4Addresses();
+		assertArrayEquals(new Integer[] { 1 }, ips);
+		verify(mockListener);
+
+		reset(mockListener);
+		mockListener.deviceMoved((isA(IDevice.class)));
+		replay(mockListener);
+
+		d = deviceManager.learnDeviceByEntity(entity3);
+		assertEquals(1, deviceManager.getAllDevices().size());
+		aps = d.getAttachmentPoints();
+		assertArrayEquals(new SwitchPort[] {new SwitchPort(DatapathId.of(5L), OFPort.of(1)), new SwitchPort(DatapathId.of(10L), OFPort.of(1))}, aps);
+		ips = d.getIPv4Addresses();
+		assertArrayEquals(new Integer[] { 1 }, ips);
+		verify(mockListener);
+
+		reset(mockListener);
+		mockListener.deviceMoved((isA(IDevice.class)));
+		replay(mockListener);
+
+		d = deviceManager.learnDeviceByEntity(entity4);
+		assertEquals(1, deviceManager.getAllDevices().size());
+		aps = d.getAttachmentPoints();
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(5L), OFPort.of(1)),
+				new SwitchPort(DatapathId.of(50L), OFPort.of(1)) }, aps);
+		ips = d.getIPv4Addresses();
+		assertArrayEquals(new Integer[] { 1 }, ips);
+		verify(mockListener);
+	}
+
+	/**
+	 * In this test, a device is moved from attachment point (1,1) to (5,1)
+	 * and then moved back to (1,1) within 30 seconds.  Both the moves should
+	 * generate device moved notification.
+	 * @throws Exception
+	 */
+	@Test
+	public void testAttachmentPointMovingBack() throws Exception {
+		IDeviceListener mockListener =
+				createMock(IDeviceListener.class);
+		expect(mockListener.getName()).andReturn("mockListener").atLeastOnce();
+		expect(mockListener.isCallbackOrderingPostreq((String)anyObject(), (String)anyObject()))
+		.andReturn(false).atLeastOnce();
+		expect(mockListener.isCallbackOrderingPrereq((String)anyObject(), (String)anyObject()))
+		.andReturn(false).atLeastOnce();
+
+		replay(mockListener);
+		deviceManager.addListener(mockListener);
+		verify(mockListener);
+		reset(mockListener);
+
+		ITopologyService mockTopology = createMock(ITopologyService.class);
+		expect(mockTopology.getL2DomainId(DatapathId.of(1L))).
+		andReturn(DatapathId.of(1L)).anyTimes();
+		expect(mockTopology.getL2DomainId(DatapathId.of(5L))).
+		andReturn(DatapathId.of(1L)).anyTimes();
+		expect(mockTopology.isBroadcastDomainPort(DatapathId.of(anyLong()), OFPort.of(anyShort()))).
+		andReturn(false).anyTimes();
+		expect(mockTopology.isInSameBroadcastDomain(DatapathId.of(anyLong()), OFPort.of(anyShort()),
+				DatapathId.of(anyLong()), OFPort.of(anyShort())))
+				.andReturn(false).anyTimes();
+
+		expect(mockTopology.isAttachmentPointPort(DatapathId.of(anyLong()),
+				OFPort.of(anyShort()))).andReturn(true).anyTimes();
+		expect(mockTopology.isConsistent(DatapathId.of(1L), OFPort.of(1), DatapathId.of(5L), OFPort.of(1))).
+		andReturn(false).anyTimes();
+
+		Date topologyUpdateTime = new Date();
+		expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
+		anyTimes();
+
+		replay(mockTopology);
+
+		deviceManager.topology = mockTopology;
+
+		Calendar c = Calendar.getInstance();
+		Entity entity1 = new Entity(MacAddress.of(1L), null, null, DatapathId.of(1L), OFPort.of(1), c.getTime());
+		c.add(Calendar.SECOND, 1);
+		Entity entity2 = new Entity(MacAddress.of(1L), null, null, DatapathId.of(5L), OFPort.of(1), c.getTime());
+		c.add(Calendar.SECOND, 1);
+		Entity entity3 = new Entity(MacAddress.of(1L), null, null, DatapathId.of(1L), OFPort.of(1), c.getTime());
+		c.add(Calendar.SECOND, 1);
+		Entity entity4 = new Entity(MacAddress.of(1L), null, null, DatapathId.of(5L), OFPort.of(1), c.getTime());
+
+		IDevice d;
+		SwitchPort[] aps;
+
+		mockListener.deviceAdded(isA(IDevice.class));
+		replay(mockListener);
+
+		d = deviceManager.learnDeviceByEntity(entity1);
+		assertEquals(1, deviceManager.getAllDevices().size());
+		aps = d.getAttachmentPoints();
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(1L), OFPort.of(1)) }, aps);
+		verify(mockListener);
+
+		reset(mockListener);
+		mockListener.deviceMoved((isA(IDevice.class)));
+		replay(mockListener);
+
+		d = deviceManager.learnDeviceByEntity(entity2);
+		assertEquals(1, deviceManager.getAllDevices().size());
+		aps = d.getAttachmentPoints();
+
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(5L), OFPort.of(1)) }, aps);
+		verify(mockListener);
+
+		reset(mockListener);
+		mockListener.deviceMoved((isA(IDevice.class)));
+		replay(mockListener);
+
+		d = deviceManager.learnDeviceByEntity(entity3);
+		assertEquals(1, deviceManager.getAllDevices().size());
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(1L), OFPort.of(1)),
+				new SwitchPort(DatapathId.of(5L), OFPort.of(1), ErrorStatus.DUPLICATE_DEVICE)},
+				d.getAttachmentPoints(true));
+		verify(mockListener);
+
+		// Generate a packet-in again from 5,1 and ensure that it doesn't
+		// create a device moved event.
+		reset(mockListener);
+		replay(mockListener);
+		d = deviceManager.learnDeviceByEntity(entity4);
+		assertEquals(1, deviceManager.getAllDevices().size());
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(1L), OFPort.of(1)),
+				new SwitchPort(DatapathId.of(5L), OFPort.of(1), ErrorStatus.DUPLICATE_DEVICE)},
+				d.getAttachmentPoints(true));
+		verify(mockListener);
+	}
+
+	private void verifyEntityArray(Entity[] expected, Device d) {
+		Arrays.sort(expected);
+		assertArrayEquals(expected, d.entities);
+	}
+
+	@Test
+	public void testNoLearningOnInternalPorts() throws Exception {
+		IDeviceListener mockListener =
+				createMock(IDeviceListener.class);
+
+		expect(mockListener.getName()).andReturn("mockListener").anyTimes();
+		expect(mockListener.isCallbackOrderingPostreq((String)anyObject(), (String)anyObject()))
+		.andReturn(false).atLeastOnce();
+		expect(mockListener.isCallbackOrderingPrereq((String)anyObject(), (String)anyObject()))
+		.andReturn(false).atLeastOnce();
+
+		replay(mockListener);
+		deviceManager.addListener(mockListener);
+		verify(mockListener);
+		reset(mockListener);
+
+		ITopologyService mockTopology = createMock(ITopologyService.class);
+		expect(mockTopology.getL2DomainId(DatapathId.of(1L))).
+		andReturn(DatapathId.of(1L)).anyTimes();
+		expect(mockTopology.getL2DomainId(DatapathId.of(2L))).
+		andReturn(DatapathId.of(1L)).anyTimes();
+		expect(mockTopology.getL2DomainId(DatapathId.of(3L))).
+		andReturn(DatapathId.of(1L)).anyTimes();
+		expect(mockTopology.getL2DomainId(DatapathId.of(4L))).
+		andReturn(DatapathId.of(1L)).anyTimes();
+		expect(mockTopology.isBroadcastDomainPort(DatapathId.of(anyLong()), OFPort.of(anyShort())))
+		.andReturn(false).anyTimes();
+		expect(mockTopology.isInSameBroadcastDomain(DatapathId.of(anyLong()), OFPort.of(anyShort()),
+				DatapathId.of(anyLong()), OFPort.of(anyShort())))
+				.andReturn(false).anyTimes();
+
+		expect(mockTopology.isAttachmentPointPort(or(eq(DatapathId.of(1L)), eq(DatapathId.of(3L))), OFPort.of(anyShort())))
+		.andReturn(true).anyTimes();
+		// Switches 2 and 4 have only internal ports
+		expect(mockTopology.isAttachmentPointPort(or(eq(DatapathId.of(2L)), eq(DatapathId.of(4L))), OFPort.of(anyShort())))
+		.andReturn(false).anyTimes();
+
+		expect(mockTopology.isConsistent(DatapathId.of(1L), OFPort.of(1), DatapathId.of(3L), OFPort.of(1)))
+		.andReturn(false).once();
+
+		Date topologyUpdateTime = new Date();
+		expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
+		anyTimes();
+
+		replay(mockTopology);
+
+		deviceManager.topology = mockTopology;
+
+		Calendar c = Calendar.getInstance();
+		Entity entity1 = new Entity(MacAddress.of(1L), null, IPv4Address.of(1), DatapathId.of(1L), OFPort.of(1), c.getTime());
+		c.add(Calendar.SECOND, 1);
+		Entity entity2 = new Entity(MacAddress.of(1L), null, IPv4Address.of(2), DatapathId.of(2L), OFPort.of(1), c.getTime());
+		c.add(Calendar.SECOND, 1);
+		Entity entity3 = new Entity(MacAddress.of(1L), null, IPv4Address.of(3), DatapathId.of(3L), OFPort.of(1), c.getTime());
+		c.add(Calendar.SECOND, 1);
+		Entity entity4 = new Entity(MacAddress.of(1L), null, IPv4Address.of(4), DatapathId.of(4L), OFPort.of(1), c.getTime());
+
+		IDevice d;
+		SwitchPort[] aps;
+		IPv4Address[] ips;
+
+		mockListener.deviceAdded(isA(IDevice.class));
+		expectLastCall().once();
+		replay(mockListener);
+
+		// cannot learn device internal ports
+		d = deviceManager.learnDeviceByEntity(entity2);
+		assertNull(d);
+		d = deviceManager.learnDeviceByEntity(entity4);
+		assertNull(d);
+
+		d = deviceManager.learnDeviceByEntity(entity1);
+		assertEquals(1, deviceManager.getAllDevices().size());
+		aps = d.getAttachmentPoints();
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(1L), OFPort.of(1)) }, aps);
+		verifyEntityArray(new Entity[] { entity1 } , (Device)d);
+		ips = d.getIPv4Addresses();
+		assertArrayEquals(new Integer[] { 1 }, ips);
+		verify(mockListener);
+
+		reset(mockListener);
+		replay(mockListener);
+
+		// don't learn
+		d = deviceManager.learnDeviceByEntity(entity2);
+		assertEquals(1, deviceManager.getAllDevices().size());
+		aps = d.getAttachmentPoints();
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(1L), OFPort.of(1)) }, aps);
+		verifyEntityArray(new Entity[] { entity1 } , (Device)d);
+		ips = d.getIPv4Addresses();
+		assertArrayEquals(new Integer[] { 1 }, ips);
+		verify(mockListener);
+
+		reset(mockListener);
+		mockListener.deviceMoved(isA(IDevice.class));
+		mockListener.deviceIPV4AddrChanged(isA(IDevice.class));
+		replay(mockListener);
+
+		// learn
+		d = deviceManager.learnDeviceByEntity(entity3);
+		assertEquals(1, deviceManager.getAllDevices().size());
+		aps = d.getAttachmentPoints();
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(3L), OFPort.of(1)) }, aps);
+		verifyEntityArray(new Entity[] { entity1, entity3 } , (Device)d);
+		ips = d.getIPv4Addresses();
+		Arrays.sort(ips);
+		assertArrayEquals(new Integer[] { 1, 3 }, ips);
+		verify(mockListener);
+
+		reset(mockListener);
+		replay(mockListener);
+
+		// don't learn
+		d = deviceManager.learnDeviceByEntity(entity4);
+		assertEquals(1, deviceManager.getAllDevices().size());
+		aps = d.getAttachmentPoints();
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(3L), OFPort.of(1)) }, aps);
+		verifyEntityArray(new Entity[] { entity1, entity3 } , (Device)d);
+		ips = d.getIPv4Addresses();
+		Arrays.sort(ips);
+		assertArrayEquals(new Integer[] { 1, 3 }, ips);
+		verify(mockListener);
+	}
+
+	@Test
+	public void testAttachmentPointSuppression() throws Exception {
+		IDeviceListener mockListener =
+				createMock(IDeviceListener.class);
+
+		expect(mockListener.getName()).andReturn("mockListener").anyTimes();
+		expect(mockListener.isCallbackOrderingPostreq((String)anyObject(), (String)anyObject()))
+		.andReturn(false).atLeastOnce();
+		expect(mockListener.isCallbackOrderingPrereq((String)anyObject(), (String)anyObject()))
+		.andReturn(false).atLeastOnce();
+
+		replay(mockListener);
+		deviceManager.addListener(mockListener);
+		verify(mockListener);
+		reset(mockListener);
+
+		ITopologyService mockTopology = createMock(ITopologyService.class);
+		expect(mockTopology.getL2DomainId(DatapathId.of(1L))).
+		andReturn(DatapathId.of(1L)).anyTimes();
+		expect(mockTopology.getL2DomainId(DatapathId.of(5L))).
+		andReturn(DatapathId.of(1L)).anyTimes();
+		expect(mockTopology.getL2DomainId(DatapathId.of(10L))).
+		andReturn(DatapathId.of(10L)).anyTimes();
+		expect(mockTopology.getL2DomainId(DatapathId.of(50L))).
+		andReturn(DatapathId.of(10L)).anyTimes();
+		expect(mockTopology.isBroadcastDomainPort(DatapathId.of(anyLong()), OFPort.of(anyShort())))
+		.andReturn(false).anyTimes();
+		expect(mockTopology.isInSameBroadcastDomain(DatapathId.of(anyLong()), OFPort.of(anyShort()),
+				DatapathId.of(anyLong()), OFPort.of(anyShort())))
+				.andReturn(false).anyTimes();
+
+		expect(mockTopology.isAttachmentPointPort(DatapathId.of(anyLong()), OFPort.of(anyShort())))
+		.andReturn(true).anyTimes();
+		expect(mockTopology.isConsistent(DatapathId.of(5L), OFPort.of(1), DatapathId.of(50L), OFPort.of(1)))
+		.andReturn(false).anyTimes();
+
+		Date topologyUpdateTime = new Date();
+		expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
+		anyTimes();
+
+		replay(mockTopology);
+
+		deviceManager.topology = mockTopology;
+		// suppress (1L, 1) and (10L, 1)
+		deviceManager.addSuppressAPs(DatapathId.of(1L), OFPort.of(1));
+		deviceManager.addSuppressAPs(DatapathId.of(10L), OFPort.of(1));
+
+		Calendar c = Calendar.getInstance();
+		Entity entity0 = new Entity(MacAddress.of(1L), null, null, null, null, c.getTime());
+		// No attachment point should be learnt on 1L, 1
+		Entity entity1 = new Entity(MacAddress.of(1L), null, IPv4Address.of(1), DatapathId.of(1L), OFPort.of(1), c.getTime());
+		c.add(Calendar.SECOND, 1);
+		Entity entity2 = new Entity(MacAddress.of(1L), null, IPv4Address.of(1), DatapathId.of(5L), OFPort.of(1), c.getTime());
+		c.add(Calendar.SECOND, 1);
+		Entity entity3 = new Entity(MacAddress.of(1L), null, null, DatapathId.of(10L), OFPort.of(1), c.getTime());
+		c.add(Calendar.SECOND, 1);
+		Entity entity4 = new Entity(MacAddress.of(1L), null, null, DatapathId.of(50L), OFPort.of(1), c.getTime());
+
+		IDevice d;
+		SwitchPort[] aps;
+		IPv4Address[] ips;
+
+		mockListener.deviceAdded(isA(IDevice.class));
+		mockListener.deviceIPV4AddrChanged((isA(IDevice.class)));
+		replay(mockListener);
+
+		// TODO: we currently do learn entities on suppressed APs
+		// // cannot learn device on suppressed AP
+		// d = deviceManager.learnDeviceByEntity(entity1);
+		// assertNull(d);
+
+		deviceManager.learnDeviceByEntity(entity0);
+		d = deviceManager.learnDeviceByEntity(entity1);
+		assertEquals(1, deviceManager.getAllDevices().size());
+		aps = d.getAttachmentPoints();
+		assertEquals(aps.length, 0);
+		verifyEntityArray(new Entity[] { entity0, entity1} , (Device)d);
+		ips = d.getIPv4Addresses();
+		assertArrayEquals(new Integer[] { 1 }, ips);
+		verify(mockListener);
+
+		reset(mockListener);
+		mockListener.deviceMoved((isA(IDevice.class)));
+		//mockListener.deviceIPV4AddrChanged((isA(IDevice.class)));
+		replay(mockListener);
+		d = deviceManager.learnDeviceByEntity(entity2);
+		assertEquals(1, deviceManager.getAllDevices().size());
+		aps = d.getAttachmentPoints();
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(5L), OFPort.of(1)) }, aps);
+		verifyEntityArray(new Entity[] { entity0, entity1, entity2 } , (Device)d);
+		ips = d.getIPv4Addresses();
+		assertArrayEquals(new Integer[] { 1 }, ips);
+		verify(mockListener);
+
+		reset(mockListener);
+		replay(mockListener);
+
+		d = deviceManager.learnDeviceByEntity(entity3);
+		assertEquals(1, deviceManager.getAllDevices().size());
+		aps = d.getAttachmentPoints();
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(5L), OFPort.of(1)) }, aps);
+		verifyEntityArray(new Entity[] { entity0, entity1, entity2, entity3 } , (Device)d);
+		ips = d.getIPv4Addresses();
+		assertArrayEquals(new Integer[] { 1 }, ips);
+		verify(mockListener);
+
+		reset(mockListener);
+		mockListener.deviceMoved((isA(IDevice.class)));
+		replay(mockListener);
+
+		d = deviceManager.learnDeviceByEntity(entity4);
+		assertEquals(1, deviceManager.getAllDevices().size());
+		aps = d.getAttachmentPoints();
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(5L), OFPort.of(1)),
+				new SwitchPort(DatapathId.of(50L), OFPort.of(1)) }, aps);
+		verifyEntityArray(new Entity[] { entity0, entity1, entity2, entity3, entity4} , (Device)d);
+		ips = d.getIPv4Addresses();
+		assertArrayEquals(new Integer[] { 1 }, ips);
+		verify(mockListener);
+	}
+
+	@Test
+	public void testBDAttachmentPointLearning() throws Exception {
+		ITopologyService mockTopology = createMock(ITopologyService.class);
+		expect(mockTopology.getL2DomainId(DatapathId.of(anyLong()))).andReturn(DatapathId.of(1L)).anyTimes();
+		expect(mockTopology.isAttachmentPointPort(DatapathId.of(anyLong()), OFPort.of(anyShort()))).
+		andReturn(true).anyTimes();
+		expect(mockTopology.isBroadcastDomainPort(DatapathId.of(1L), OFPort.of(1))).
+		andReturn(false).anyTimes();
+		expect(mockTopology.isBroadcastDomainPort(DatapathId.of(1L), OFPort.of(2))).
+		andReturn(true).anyTimes();
+		expect(mockTopology.isInSameBroadcastDomain(DatapathId.of(1L), OFPort.of(1),
+				DatapathId.of(1L), OFPort.of(2))).andReturn(true).anyTimes();
+		expect(mockTopology.isInSameBroadcastDomain(DatapathId.of(1L), OFPort.of(2),
+				DatapathId.of(1L), OFPort.of(1))).andReturn(true).anyTimes();
+		expect(mockTopology.isConsistent(DatapathId.of(anyLong()), OFPort.of(anyShort()), DatapathId.of(anyLong()), OFPort.of(anyShort()))).andReturn(false).anyTimes();
+
+		Date topologyUpdateTime = new Date();
+		expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
+		anyTimes();
+
+		replay(mockTopology);
+
+		deviceManager.topology = mockTopology;
+
+		Calendar c = Calendar.getInstance();
+		Entity entity1 = new Entity(MacAddress.of(1L), null, IPv4Address.of(1), DatapathId.of(1L), OFPort.of(1), c.getTime());
+		c.add(Calendar.MILLISECOND,
+				(int)AttachmentPoint.OPENFLOW_TO_EXTERNAL_TIMEOUT/ 2);
+		Entity entity2 = new Entity(MacAddress.of(1L), null, null, DatapathId.of(1L), OFPort.of(2), c.getTime());
+		c.add(Calendar.MILLISECOND,
+				(int)AttachmentPoint.OPENFLOW_TO_EXTERNAL_TIMEOUT / 2 + 1);
+		Entity entity3 = new Entity(MacAddress.of(1L), null, null, DatapathId.of(1L), OFPort.of(2), c.getTime());
+
+		IDevice d;
+		SwitchPort[] aps;
+
+		d = deviceManager.learnDeviceByEntity(entity1);
+		assertEquals(1, deviceManager.getAllDevices().size());
+		aps = d.getAttachmentPoints();
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(1L), OFPort.of(1)) }, aps);
+
+		// this timestamp is too soon; don't switch
+		d = deviceManager.learnDeviceByEntity(entity2);
+		assertEquals(1, deviceManager.getAllDevices().size());
+		aps = d.getAttachmentPoints();
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(1L), OFPort.of(1)) }, aps);
+
+		// it should switch when we learn with a timestamp after the
+		// timeout
+		d = deviceManager.learnDeviceByEntity(entity3);
+		assertEquals(1, deviceManager.getAllDevices().size());
+		aps = d.getAttachmentPoints();
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(1L), OFPort.of(2)) }, aps);
+	}
+
+	/**
+	 * This test verifies that the learning behavior on OFPP_LOCAL ports.
+	 * Once a host is learned on OFPP_LOCAL, it is allowed to move only from
+	 * one OFPP_LOCAL to another OFPP_LOCAL port.
+	 * @throws Exception
+	 */
+	@Test
+	public void testLOCALAttachmentPointLearning() throws Exception {
+		ITopologyService mockTopology = createMock(ITopologyService.class);
+		expect(mockTopology.getL2DomainId(DatapathId.of(anyLong()))).
+		andReturn(DatapathId.of(1L)).anyTimes();
+		expect(mockTopology.isAttachmentPointPort(DatapathId.of(anyLong()), OFPort.of(anyShort()))).
+		andReturn(true).anyTimes();
+		expect(mockTopology.isBroadcastDomainPort(DatapathId.of(1L), OFPort.of(1))).
+		andReturn(false).anyTimes();
+		expect(mockTopology.isBroadcastDomainPort(DatapathId.of(1L), OFPort.LOCAL)).
+		andReturn(false).anyTimes();
+		expect(mockTopology.isBroadcastDomainPort(DatapathId.of(1L), OFPort.of(2))).
+		andReturn(true).anyTimes();
+		expect(mockTopology.isInSameBroadcastDomain(DatapathId.of(1L), OFPort.of(1),
+				DatapathId.of(1L), OFPort.LOCAL)).andReturn(true).anyTimes();
+		expect(mockTopology.isInSameBroadcastDomain(DatapathId.of(1L), OFPort.LOCAL,
+				DatapathId.of(1L), OFPort.of(2))).andReturn(true).anyTimes();
+		expect(mockTopology.isInSameBroadcastDomain(DatapathId.of(1L), OFPort.of(2),
+				DatapathId.of(1L), OFPort.LOCAL)).andReturn(true).anyTimes();
+		expect(mockTopology.isConsistent(DatapathId.of(anyLong()), OFPort.of(anyShort()), DatapathId.of(anyLong()), OFPort.of(anyShort()))).andReturn(false).anyTimes();
+
+		Date topologyUpdateTime = new Date();
+		expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
+		anyTimes();
+
+		replay(mockTopology);
+
+		deviceManager.topology = mockTopology;
+
+		Calendar c = Calendar.getInstance();
+		Entity entity1 = new Entity(MacAddress.of(1L), null, IPv4Address.of(1), DatapathId.of(1L), OFPort.of(1), c.getTime());
+		c.add(Calendar.MILLISECOND,
+				(int)AttachmentPoint.OPENFLOW_TO_EXTERNAL_TIMEOUT/ 2);
+		Entity entity2 = new Entity(MacAddress.of(1L), null, null, DatapathId.of(1L), OFPort.LOCAL, c.getTime());
+		c.add(Calendar.MILLISECOND,
+				(int)AttachmentPoint.OPENFLOW_TO_EXTERNAL_TIMEOUT + 1);
+		Entity entity3 = new Entity(MacAddress.of(1L), null, null, DatapathId.of(1L), OFPort.of(2), c.getTime());
+
+		IDevice d;
+		SwitchPort[] aps;
+
+		d = deviceManager.learnDeviceByEntity(entity1);
+		assertEquals(1, deviceManager.getAllDevices().size());
+		aps = d.getAttachmentPoints();
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(1L), OFPort.of(1)) }, aps);
+
+		// Ensure that the attachment point changes to OFPP_LOCAL
+		d = deviceManager.learnDeviceByEntity(entity2);
+		assertEquals(1, deviceManager.getAllDevices().size());
+		aps = d.getAttachmentPoints();
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(1L), OFPort.LOCAL) }, aps);
+
+		// Even though the new attachment point is consistent with old
+		// and the time has elapsed, OFPP_LOCAL attachment point should
+		// be maintained.
+		d = deviceManager.learnDeviceByEntity(entity3);
+		assertEquals(1, deviceManager.getAllDevices().size());
+		aps = d.getAttachmentPoints();
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(1L), OFPort.LOCAL) }, aps);
+	}
+
+	private static void
+	mockTopologyForPacketInTests(ITopologyService mockTopology) {
+		expect(mockTopology.isAttachmentPointPort(DatapathId.of(anyLong()),
+				OFPort.of(anyShort()))).
+				andReturn(true).
+				anyTimes();
+		expect(mockTopology.isConsistent(DatapathId.of(EasyMock.anyLong()),
+				OFPort.of(EasyMock.anyShort()),
+				DatapathId.of(EasyMock.anyLong()),
+				OFPort.of(EasyMock.anyShort()))).andReturn(false).
+				anyTimes();
+		expect(mockTopology.isBroadcastDomainPort(DatapathId.of(EasyMock.anyLong()),
+				OFPort.of(EasyMock.anyShort())))
+				.andReturn(false)
+				.anyTimes();
+		expect(mockTopology.getL2DomainId(DatapathId.of(anyLong()))).andReturn(DatapathId.of(1L)).anyTimes();
+		expect(mockTopology.isInSameBroadcastDomain(DatapathId.of(anyLong()),
+				OFPort.of(anyShort()),
+				DatapathId.of(anyLong()),
+				OFPort.of(anyShort())))
+				.andReturn(false).anyTimes();
+
+	}
+
+	private Command dispatchPacketIn(long swId, OFPacketIn pi,
+			FloodlightContext cntx) {
+		IOFSwitch sw = getMockSwitchService().getSwitch(DatapathId.of(swId));
+		Ethernet eth = new Ethernet();
+		eth.deserialize(pi.getData(), 0, pi.getData().length);
+		IFloodlightProviderService.bcStore.put(cntx,
+				IFloodlightProviderService.CONTEXT_PI_PAYLOAD,
+				eth);
+		return deviceManager.receive(sw, pi, cntx);
+	}
+
+	/**
+	 * Verify that the given device exactly matches the given fields. E.g.,
+	 * if ip is not null we expect the device to have exactly one IP address.
+	 * swId and port are the attachment point port.
+	 * Vlan and ip are optional all other fields must be specified.
+	 * @return
+	 */
+	private static void verifyDevice(IDevice d, long mac, Short vlan, Integer ip,
+			long swId, int port) {
+		assertNotNull(d);
+		assertEquals(mac, d.getMACAddress());
+		if (vlan == null)
+			assertArrayEquals(new Short[0], d.getVlanId());
+		else
+			assertArrayEquals(new Short[] { vlan }, d.getVlanId());
+
+		if (ip == null)
+			assertArrayEquals(new Integer[0], d.getIPv4Addresses());
+		else
+			assertArrayEquals(new Integer[] { ip }, d.getIPv4Addresses());
+
+		SwitchPort expectedAp = new SwitchPort(DatapathId.of(swId), OFPort.of(port));
+		assertArrayEquals(new SwitchPort[] { expectedAp },
+				d.getAttachmentPoints());
+	}
+
+
+	@Test
+	public void testPacketInBasic() throws Exception {
+		MacAddress deviceMac =
+				((Ethernet)this.testARPReplyPacket_1).getSourceMACAddress();
+		OFPacketIn packetIn = testARPReplyPacketIn_1;
+		Integer ipaddr = IPv4.toIPv4Address("192.168.1.1");
+
+		// Mock up our expected behavior
+		ITopologyService mockTopology = createMock(ITopologyService.class);
+		deviceManager.topology = mockTopology;
+		mockTopologyForPacketInTests(mockTopology);
+		replay(mockTopology);
+
+		FloodlightContext cntx = new FloodlightContext();
+		Command cmd = dispatchPacketIn(1L, packetIn, cntx);
+		verify(mockTopology);
+		assertEquals(Command.CONTINUE, cmd);
+		// Verify the device
+		Device rdevice = (Device)
+				deviceManager.findDevice(deviceMac,
+						VlanVid.ofVlan(5), null, null, null);
+		verifyDevice(rdevice, deviceMac.getLong(),
+				(short) 5, ipaddr, 1L, 1);
+		IDevice cntxSrcDev = IDeviceService.fcStore.get(cntx,
+				IDeviceService.CONTEXT_SRC_DEVICE);
+		assertEquals(rdevice, cntxSrcDev);
+		IDevice cntxDstDev = IDeviceService.fcStore.get(cntx,
+				IDeviceService.CONTEXT_DST_DEVICE);
+		assertNull(cntxDstDev);
+
+		Device result = null;
+		Iterator<? extends IDevice> dstiter =
+				deviceManager.queryDevices(null, null, IPv4Address.of(ipaddr),
+						null, null);
+		if (dstiter.hasNext()) {
+			result = (Device)dstiter.next();
+		}
+		assertFalse("There shouldn't be more than 1 device", dstiter.hasNext());
+		assertEquals(rdevice, result);
+
+
+		//-----------------
+		// Test packetIn again with a different source port. Should be
+		// the same device
+		reset(mockTopology);
+		mockTopologyForPacketInTests(mockTopology);
+		replay(mockTopology);
+
+		// trigger the packet in
+		cntx = new FloodlightContext();
+		packetIn = packetIn.createBuilder().setInPort(OFPort.of(2)).build();
+		cmd = dispatchPacketIn(5L, packetIn, cntx);
+		verify(mockTopology);
+		// Verify the replay matched our expectations
+		assertEquals(Command.CONTINUE, cmd);
+
+		// Verify the device
+		rdevice = (Device)
+				deviceManager.findDevice(deviceMac,
+						VlanVid.ofVlan(5), null, null, null);
+		verifyDevice(rdevice, deviceMac.getLong(),
+				(short)5, ipaddr, 5L, 2);
+		cntxSrcDev = IDeviceService.fcStore.get(cntx,
+				IDeviceService.CONTEXT_SRC_DEVICE);
+		assertEquals(rdevice, cntxSrcDev);
+		cntxDstDev = IDeviceService.fcStore.get(cntx,
+				IDeviceService.CONTEXT_DST_DEVICE);
+		assertNull(cntxDstDev);
+		// There can be only one device
+		assertEquals(1, deviceManager.getAllDevices().size());
+
+		//----------------------------
+		// Test packetIn with a different packet going the reverse direction.
+		// We should now get source and dest device in the context
+		//==> The destination device in this step has been learned just before
+		MacAddress srcMac = testUDPPacket.getSourceMACAddress();
+		MacAddress dstMac = deviceMac;
+		reset(mockTopology);
+		mockTopologyForPacketInTests(mockTopology);
+		replay(mockTopology);
+		// trigger the packet in
+		cntx = new FloodlightContext();
+		cmd = dispatchPacketIn(1L, testUDPPacketIn, cntx);
+		verify(mockTopology);
+
+		assertEquals(Command.CONTINUE, cmd);
+		IDevice srcDev =
+				deviceManager.findDevice(srcMac, VlanVid.ofVlan(5), null, null, null);
+		verifyDevice(srcDev, srcMac.getLong(), (short)5, null,
+				1L, testUDPPacketIn.getInPort().getShortPortNumber());
+
+		IDevice dstDev =
+				deviceManager.findDevice(dstMac, VlanVid.ofVlan(5), null, null, null);
+		verifyDevice(dstDev, dstMac.getLong(), (short)5, ipaddr, 5L, 2);
+
+		cntxSrcDev = IDeviceService.fcStore.get(cntx,
+				IDeviceService.CONTEXT_SRC_DEVICE);
+		assertEquals(srcDev, cntxSrcDev);
+
+		cntxDstDev = IDeviceService.fcStore.get(cntx,
+				IDeviceService.CONTEXT_DST_DEVICE);
+		assertEquals(dstDev, cntxDstDev);
+
+		assertEquals(2, deviceManager.getAllDevices().size());
+	}
+
+	/**
+	 * This test ensures the device manager learns the source device
+	 * corresponding to the senderHardwareAddress and senderProtocolAddress
+	 * in an ARP response whenever the senderHardwareAddress is different
+	 * from the source MAC address of the Ethernet frame.
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	public void testDeviceLearningFromArpResponseData() throws Exception {
+		ARP arp = (ARP)((Ethernet)this.testARPReplyPacket_2).getPayload();
+		MacAddress senderMac = MacAddress.of(arp.getSenderHardwareAddress());
+		MacAddress sourceMac =
+				((Ethernet)this.testARPReplyPacket_2)
+				.getSourceMACAddress();
+		Integer ipaddr = IPv4.toIPv4Address("192.168.1.1");
+		OFPacketIn packetIn = testARPReplyPacketIn_2;
+
+		// Mock up our expected behavior
+		ITopologyService mockTopology = createMock(ITopologyService.class);
+		deviceManager.topology = mockTopology;
+		mockTopologyForPacketInTests(mockTopology);
+		replay(mockTopology);
+
+
+		FloodlightContext cntx = new FloodlightContext();
+		Command cmd = dispatchPacketIn(1L, packetIn, cntx);
+		verify(mockTopology);
+		assertEquals(Command.CONTINUE, cmd);
+		// Verify the device for the sender HW address
+		Device senderDev = (Device)
+				deviceManager.findDevice(senderMac, VlanVid.ofVlan(5), null, null, null);
+		verifyDevice(senderDev, senderMac.getLong(), (short)5, ipaddr, 1L, 1);
+
+		Device result = null;
+		Iterator<? extends IDevice> dstiter =
+				deviceManager.queryDevices(null, null, IPv4Address.of(ipaddr),
+						null, null);
+		if (dstiter.hasNext()) {
+			result = (Device)dstiter.next();
+		}
+		assertFalse("There shouldn't be more than 1 device", dstiter.hasNext());
+		assertEquals(senderDev, result);
+
+
+
+		// Verify the device for the source MAC
+		Device srcDev = (Device)
+				deviceManager.findDevice(sourceMac, VlanVid.ofVlan(5), null, null, null);
+		// must NOT learn IP on this device
+		verifyDevice(srcDev, sourceMac.getLong(), (short)5, null, 1L, 1);
+		assertFalse("Device must differ", srcDev.equals(senderDev));
+		// Context is annotated with this device, not the device associated
+		// with ARP sender address
+		IDevice cntxSrcDev = IDeviceService.fcStore.get(cntx,
+				IDeviceService.CONTEXT_SRC_DEVICE);
+		assertEquals(srcDev, cntxSrcDev);
+
+		assertEquals(2, deviceManager.getAllDevices().size());
+	}
+
+
+	@Test
+	public void testPacketInInvalidSrcMac() throws Exception {
+		// Mock up our expected behavior
+		ITopologyService mockTopology = createMock(ITopologyService.class);
+		deviceManager.topology = mockTopology;
+		mockTopologyForPacketInTests(mockTopology);
+		replay(mockTopology);
+		FloodlightContext cntx = new FloodlightContext();
+
+		testUDPPacket.setSourceMACAddress(Ethernet.toByteArray(0L));
+		updateUDPPacketIn();
+		Command cmd = dispatchPacketIn(1L, testUDPPacketIn, cntx);
+		assertEquals(Command.STOP, cmd);
+		IDevice cntxSrcDev = IDeviceService.fcStore.get(cntx,
+				IDeviceService.CONTEXT_SRC_DEVICE);
+		assertNull(cntxSrcDev);
+		IDevice cntxDstDev = IDeviceService.fcStore.get(cntx,
+				IDeviceService.CONTEXT_DST_DEVICE);
+		assertNull(cntxDstDev);
+
+		testUDPPacket.setSourceMACAddress(Ethernet.toByteArray(-1L));
+		updateUDPPacketIn();
+		cmd = dispatchPacketIn(1L, testUDPPacketIn, cntx);
+		assertEquals(Command.STOP, cmd);
+		cntxSrcDev = IDeviceService.fcStore.get(cntx,
+				IDeviceService.CONTEXT_SRC_DEVICE);
+		assertNull(cntxSrcDev);
+		cntxDstDev = IDeviceService.fcStore.get(cntx,
+				IDeviceService.CONTEXT_DST_DEVICE);
+		assertNull(cntxDstDev);
+
+		// MAC with only the multicast bit set
+		testUDPPacket.setSourceMACAddress(new byte[] { 1, 0, 0, 0, 0, 0 });
+		updateUDPPacketIn();
+		cmd = dispatchPacketIn(1L, testUDPPacketIn, cntx);
+		assertEquals(Command.STOP, cmd);
+		cntxSrcDev = IDeviceService.fcStore.get(cntx,
+				IDeviceService.CONTEXT_SRC_DEVICE);
+		assertNull(cntxSrcDev);
+		cntxDstDev = IDeviceService.fcStore.get(cntx,
+				IDeviceService.CONTEXT_DST_DEVICE);
+		assertNull(cntxDstDev);
+
+		// Now use a real MAC. We should get a src device
+		testUDPPacket.setSourceMACAddress(Ethernet.toByteArray(1L));
+		updateUDPPacketIn();
+		cmd = dispatchPacketIn(1L, testUDPPacketIn, cntx);
+		assertEquals(Command.CONTINUE, cmd);
+		cntxSrcDev = IDeviceService.fcStore.get(cntx,
+				IDeviceService.CONTEXT_SRC_DEVICE);
+		verifyDevice(cntxSrcDev, 1L, (short)5, null,
+				1L, testUDPPacketIn.getInPort().getShortPortNumber());
+
+		cntxDstDev = IDeviceService.fcStore.get(cntx,
+				IDeviceService.CONTEXT_DST_DEVICE);
+		assertNull(cntxDstDev);
+		verify(mockTopology);
+	}
+
+
+	@Test
+	public void testPacketInInvalidDstMac() throws Exception {
+		// Mock up our expected behavior
+		ITopologyService mockTopology = createMock(ITopologyService.class);
+		deviceManager.topology = mockTopology;
+		mockTopologyForPacketInTests(mockTopology);
+		replay(mockTopology);
+		FloodlightContext cntx = new FloodlightContext();
+
+		MacAddress srcMac = testUDPPacket.getSourceMACAddress();
+		MacAddress dstMac = testUDPPacket.getDestinationMACAddress();
+
+		// Prime device manager with the source device
+		Command cmd = dispatchPacketIn(1L, testUDPPacketIn, cntx);
+		assertEquals(Command.CONTINUE, cmd);
+		IDevice cntxSrcDev = IDeviceService.fcStore.get(cntx,
+				IDeviceService.CONTEXT_SRC_DEVICE);
+		verifyDevice(cntxSrcDev, srcMac.getLong(), (short)5, null,
+				1L, testUDPPacketIn.getInPort().getShortPortNumber());
+		IDevice cntxDstDev = IDeviceService.fcStore.get(cntx,
+				IDeviceService.CONTEXT_DST_DEVICE);
+		assertNull(cntxDstDev);
+		IDevice expectedSrcDev = cntxSrcDev;
+
+		// Create a device for the destination. We can use testARPPacketIn_1
+		// for that.
+		cntx = new FloodlightContext();
+		// Prime device manager with the source device
+		cmd = dispatchPacketIn(1L, testARPReplyPacketIn_1, cntx);
+		assertEquals(Command.CONTINUE, cmd);
+		cntxSrcDev = IDeviceService.fcStore.get(cntx,
+				IDeviceService.CONTEXT_SRC_DEVICE);
+		// yes: we check that cntxSrcDev matched dstMAC because we are
+		// just adding the dest device
+		int ip = IPv4.toIPv4Address("192.168.1.1");
+		verifyDevice(cntxSrcDev, dstMac.getLong(), (short)5, ip,
+				1L, testARPReplyPacketIn_1.getInPort().getShortPortNumber());
+		// yes: we set the expected dst device to the current srcDev
+		IDevice expectedDstDev = cntxSrcDev;
+
+		//-------------------------------
+		// Let the real tests begin
+
+		cntx = new FloodlightContext();
+		testUDPPacket.setDestinationMACAddress(Ethernet.toByteArray(0L));
+		updateUDPPacketIn();
+		cmd = dispatchPacketIn(1L, testUDPPacketIn, cntx);
+		assertEquals(Command.STOP, cmd);
+		cntxDstDev = IDeviceService.fcStore.get(cntx,
+				IDeviceService.CONTEXT_DST_DEVICE);
+		assertNull(cntxDstDev);
+
+		// use a real dest mac
+		cntx = new FloodlightContext();
+		testUDPPacket.setDestinationMACAddress(dstMac);
+		updateUDPPacketIn();
+		cmd = dispatchPacketIn(1L, testUDPPacketIn, cntx);
+		assertEquals(Command.CONTINUE, cmd);
+		cntxSrcDev = IDeviceService.fcStore.get(cntx,
+				IDeviceService.CONTEXT_SRC_DEVICE);
+		assertEquals(expectedSrcDev, cntxSrcDev);
+		cntxDstDev = IDeviceService.fcStore.get(cntx,
+				IDeviceService.CONTEXT_DST_DEVICE);
+		assertEquals(expectedDstDev, cntxDstDev);
+
+		verify(mockTopology);
+	}
+
+	/**
+	 * Note: Entity expiration does not result in device moved notification.
+	 * @throws Exception
+	 */
+	public void doTestEntityExpiration() throws Exception {
+		IDeviceListener mockListener =
+				createMock(IDeviceListener.class);
+		expect(mockListener.getName()).andReturn("mockListener").anyTimes();
+		expect(mockListener.isCallbackOrderingPostreq((String)anyObject(), (String)anyObject()))
+		.andReturn(false).atLeastOnce();
+		expect(mockListener.isCallbackOrderingPrereq((String)anyObject(), (String)anyObject()))
+		.andReturn(false).atLeastOnce();
+
+		ITopologyService mockTopology = createMock(ITopologyService.class);
+		expect(mockTopology.isAttachmentPointPort(DatapathId.of(anyLong()),
+				OFPort.of(anyShort()))).andReturn(true).anyTimes();
+
+		expect(mockTopology.isBroadcastDomainPort(DatapathId.of(1L), OFPort.of(1))).andReturn(false).anyTimes();
+		expect(mockTopology.isBroadcastDomainPort(DatapathId.of(5L), OFPort.of(1))).andReturn(false).anyTimes();
+		expect(mockTopology.getL2DomainId(DatapathId.of(1L))).andReturn(DatapathId.of(1L)).anyTimes();
+		expect(mockTopology.getL2DomainId(DatapathId.of(5L))).andReturn(DatapathId.of(5L)).anyTimes();
+		expect(mockTopology.isConsistent(DatapathId.of(1L), OFPort.of(1), DatapathId.of(5L), OFPort.of(1))).
+		andReturn(false).anyTimes();
+
+		Date topologyUpdateTime = new Date();
+		expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
+		anyTimes();
+
+		replay(mockTopology);
+		deviceManager.topology = mockTopology;
+
+		Calendar c = Calendar.getInstance();
+		Entity entity1 = new Entity(MacAddress.of(1L), null, IPv4Address.of(2), DatapathId.of(1L), OFPort.of(1), c.getTime());
+		c.add(Calendar.MILLISECOND, -DeviceManagerImpl.ENTITY_TIMEOUT-1);
+		Entity entity2 = new Entity(MacAddress.of(1L), null, IPv4Address.of(1), DatapathId.of(5L), OFPort.of(1), c.getTime());
+
+		deviceManager.learnDeviceByEntity(entity1);
+		IDevice d = deviceManager.learnDeviceByEntity(entity2);
+		assertArrayEquals(new Integer[] { 1, 2 }, d.getIPv4Addresses());
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(1L), OFPort.of(1)),
+				new SwitchPort(DatapathId.of(5L), OFPort.of(1))},
+				d.getAttachmentPoints());
+		Iterator<? extends IDevice> diter =
+				deviceManager.queryClassDevices(d.getEntityClass(),
+						null, null, IPv4Address.of(1), null, null);
+		assertTrue(diter.hasNext());
+		assertEquals(d.getDeviceKey(), diter.next().getDeviceKey());
+		diter = deviceManager.queryClassDevices(d.getEntityClass(),
+				null, null, IPv4Address.of(2), null, null);
+		assertTrue(diter.hasNext());
+		assertEquals(d.getDeviceKey(), diter.next().getDeviceKey());
+
+		replay(mockListener);
+		deviceManager.addListener(mockListener);
+		verify(mockListener);
+		reset(mockListener);
+
+		mockListener.deviceIPV4AddrChanged(isA(IDevice.class));
+		replay(mockListener);
+		deviceManager.entityCleanupTask.reschedule(0, null);
+
+		d = deviceManager.getDevice(d.getDeviceKey());
+		assertArrayEquals(new Integer[] { 2 }, d.getIPv4Addresses());
+
+		// Attachment points are not removed, previous ones are still valid.
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(1L), OFPort.of(1)),
+				new SwitchPort(DatapathId.of(5L), OFPort.of(1)) },
+				d.getAttachmentPoints());
+		diter = deviceManager.queryClassDevices(d.getEntityClass(),
+				null, null, IPv4Address.of(2), null, null);
+		assertTrue(diter.hasNext());
+		assertEquals(d.getDeviceKey(), diter.next().getDeviceKey());
+		diter = deviceManager.queryClassDevices(d.getEntityClass(),
+				null, null, IPv4Address.of(1), null, null);
+		assertFalse(diter.hasNext());
+
+		d = deviceManager.findDevice(MacAddress.of(1L), null, null, null, null);
+		assertArrayEquals(new Integer[] { 2 }, d.getIPv4Addresses());
+
+		// Attachment points are not removed, previous ones are still valid.
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(1L), OFPort.of(1)),
+				new SwitchPort(DatapathId.of(5L), OFPort.of(1)) },
+				d.getAttachmentPoints());
+
+		verify(mockListener);
+	}
+
+	public void doTestDeviceExpiration() throws Exception {
+		IDeviceListener mockListener =
+				createMock(IDeviceListener.class);
+		expect(mockListener.getName()).andReturn("mockListener").anyTimes();
+		expect(mockListener.isCallbackOrderingPostreq((String)anyObject(), (String)anyObject()))
+		.andReturn(false).atLeastOnce();
+		expect(mockListener.isCallbackOrderingPrereq((String)anyObject(), (String)anyObject()))
+		.andReturn(false).atLeastOnce();
+
+		Calendar c = Calendar.getInstance();
+		c.add(Calendar.MILLISECOND, -DeviceManagerImpl.ENTITY_TIMEOUT-1);
+		Entity entity1 = new Entity(MacAddress.of(1L), null, IPv4Address.of(1), DatapathId.of(1L), OFPort.of(1), c.getTime());
+		Entity entity2 = new Entity(MacAddress.of(1L), null, IPv4Address.of(2), DatapathId.of(5L), OFPort.of(1), c.getTime());
+
+		ITopologyService mockTopology = createMock(ITopologyService.class);
+		deviceManager.topology = mockTopology;
+
+		expect(mockTopology.isAttachmentPointPort(DatapathId.of(EasyMock.anyLong()),
+				OFPort.of(EasyMock.anyShort()))).
+				andReturn(true).
+				anyTimes();
+		expect(mockTopology.getL2DomainId(DatapathId.of(1L))).andReturn(DatapathId.of(1L)).anyTimes();
+		expect(mockTopology.getL2DomainId(DatapathId.of(5L))).andReturn(DatapathId.of(1L)).anyTimes();
+		expect(mockTopology.isConsistent(DatapathId.of(EasyMock.anyLong()),
+				OFPort.of(EasyMock.anyShort()),
+				DatapathId.of(EasyMock.anyLong()),
+				OFPort.of(EasyMock.anyShort()))).andReturn(false).
+				anyTimes();
+		expect(mockTopology.isBroadcastDomainPort(DatapathId.of(EasyMock.anyLong()),
+				OFPort.of(EasyMock.anyShort()))).
+				andReturn(false).anyTimes();
+		replay(mockTopology);
+
+		IDevice d = deviceManager.learnDeviceByEntity(entity2);
+		d = deviceManager.learnDeviceByEntity(entity1);
+		assertArrayEquals(new Integer[] { 1, 2 }, d.getIPv4Addresses());
+
+		replay(mockListener);
+		deviceManager.addListener(mockListener);
+		verify(mockListener);
+		reset(mockListener);
+
+		mockListener.deviceRemoved(isA(IDevice.class));
+		replay(mockListener);
+		deviceManager.entityCleanupTask.reschedule(0, null);
+
+		IDevice r = deviceManager.getDevice(d.getDeviceKey());
+		assertNull(r);
+		Iterator<? extends IDevice> diter =
+				deviceManager.queryClassDevices(d.getEntityClass(),
+						null, null, IPv4Address.of(1), null, null);
+		assertFalse(diter.hasNext());
+
+		r = deviceManager.findDevice(MacAddress.of(1L), null, null, null, null);
+		assertNull(r);
+
+		verify(mockListener);
+	}
+
+	/*
+	 * A ConcurrentHashMap for devices (deviceMap) that can be used to test
+	 * code that specially handles concurrent modification situations. In
+	 * particular, we overwrite values() and will replace / remove all the
+	 * elements returned by values.
+	 *
+	 * The remove flag in the constructor specifies if devices returned by
+	 * values() should be removed or replaced.
+	 */
+	protected static class ConcurrentlyModifiedDeviceMap
+	extends ConcurrentHashMap<Long, Device> {
+		private static final long serialVersionUID = 7784938535441180562L;
+		protected boolean remove;
+		public ConcurrentlyModifiedDeviceMap(boolean remove) {
+			super();
+			this.remove = remove;
+		}
+
+		@Override
+		public Collection<Device> values() {
+			// Get the values from the real map and copy them since
+			// the collection returned by values can reflect changed
+			Collection<Device> devs = new ArrayList<Device>(super.values());
+			for (Device d: devs) {
+				if (remove) {
+					// We remove the device from the underlying map
+					super.remove(d.getDeviceKey());
+				} else {
+					super.remove(d.getDeviceKey());
+					// We add a different Device instance with the same
+					// key to the map. We'll do some hackery so the device
+					// is different enough to compare differently in equals
+					// but otherwise looks the same.
+					// It's ugly but it works.
+					// clone entities
+					Device newDevice = d;
+					for (Entity e: d.getEntities()) {
+						Entity newEntity = new Entity (e.macAddress,
+								e.vlan,
+								e.ipv4Address,
+								e.switchDPID,
+								e.switchPort,
+								e.lastSeenTimestamp);
+						if (e.vlan == null)
+							newEntity.vlan = VlanVid.ofVlan(1);
+						else
+							newEntity.vlan = VlanVid.ofVlan(((e.vlan.getVlan() + 1 % 4095)+1));
+						newDevice = new Device(newDevice, newEntity, -1);
+					}
+					assertEquals(false, newDevice.equals(d));
+					super.put(newDevice.getDeviceKey(), newDevice);
+				}
+			}
+			return devs;
+		}
+	}
+
+	@Test
+	public void testEntityExpiration() throws Exception {
+		doTestEntityExpiration();
+	}
+
+	@Test
+	public void testDeviceExpiration() throws Exception {
+		doTestDeviceExpiration();
+	}
+
+	/* Test correct entity cleanup behavior when a concurrent modification
+	 * occurs.
+	 */
+	@Test
+	public void testEntityExpirationConcurrentModification() throws Exception {
+		deviceManager.deviceMap = new ConcurrentlyModifiedDeviceMap(false);
+		doTestEntityExpiration();
+	}
+
+	/* Test correct entity cleanup behavior when a concurrent remove
+	 * occurs.
+	 */
+	@Test
+	public void testDeviceExpirationConcurrentRemove() throws Exception {
+		deviceManager.deviceMap = new ConcurrentlyModifiedDeviceMap(true);
+		doTestDeviceExpiration();
+	}
+
+	/* Test correct entity cleanup behavior when a concurrent modification
+	 * occurs.
+	 */
+	@Test
+	public void testDeviceExpirationConcurrentModification() throws Exception {
+		deviceManager.deviceMap = new ConcurrentlyModifiedDeviceMap(false);
+		doTestDeviceExpiration();
+	}
+
+
+	@Test
+	public void testAttachmentPointFlapping() throws Exception {
+		Calendar c = Calendar.getInstance();
+
+		ITopologyService mockTopology = createMock(ITopologyService.class);
+		expect(mockTopology.isAttachmentPointPort(DatapathId.of(anyLong()),
+				OFPort.of(anyShort()))).andReturn(true).anyTimes();
+		expect(mockTopology.isBroadcastDomainPort(DatapathId.of(anyLong()),
+				OFPort.of(anyShort()))).
+				andReturn(false).anyTimes();
+		expect(mockTopology.isInSameBroadcastDomain(DatapathId.of(anyLong()), OFPort.of(anyShort()),
+				DatapathId.of(anyLong()), OFPort.of(anyShort()))).andReturn(false).anyTimes();
+		expect(mockTopology.getL2DomainId(DatapathId.of(anyLong()))).
+		andReturn(DatapathId.of(1L)).anyTimes();
+		expect(mockTopology.isConsistent(DatapathId.of(1L), OFPort.of(1), DatapathId.of(1L), OFPort.of(1))).
+		andReturn(true).anyTimes();
+		expect(mockTopology.isConsistent(DatapathId.of(1L), OFPort.of(1), DatapathId.of(5L), OFPort.of(1))).
+		andReturn(false).anyTimes();
+		expect(mockTopology.isConsistent(DatapathId.of(1L), OFPort.of(1), DatapathId.of(10L), OFPort.of(1))).
+		andReturn(false).anyTimes();
+		expect(mockTopology.isConsistent(DatapathId.of(5L), OFPort.of(1), DatapathId.of(10L), OFPort.of(1))).
+		andReturn(false).anyTimes();
+		expect(mockTopology.isConsistent(DatapathId.of(10L), OFPort.of(1), DatapathId.of(1L), OFPort.of(1))).
+		andReturn(false).anyTimes();
+		expect(mockTopology.isConsistent(DatapathId.of(5L), OFPort.of(1), DatapathId.of(1L), OFPort.of(1))).
+		andReturn(false).anyTimes();
+		expect(mockTopology.isConsistent(DatapathId.of(10L), OFPort.of(1), DatapathId.of(5L), OFPort.of(1))).
+		andReturn(false).anyTimes();
+
+		Date topologyUpdateTime = new Date();
+		expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
+		anyTimes();
+
+
+		replay(mockTopology);
+		deviceManager.topology = mockTopology;
+
+		Entity entity1 = new Entity(MacAddress.of(1L), null, null, DatapathId.of(1L), OFPort.of(1), c.getTime());
+		Entity entity1a = new Entity(MacAddress.of(1L), null, IPv4Address.of(1), DatapathId.of(1L), OFPort.of(1), c.getTime());
+		Entity entity2 = new Entity(MacAddress.of(1L), null, null, DatapathId.of(5L), OFPort.of(1), c.getTime());
+		Entity entity3 = new Entity(MacAddress.of(1L), null, null, DatapathId.of(10L), OFPort.of(1), c.getTime());
+		entity1.setLastSeenTimestamp(c.getTime());
+		c.add(Calendar.MILLISECOND, Entity.ACTIVITY_TIMEOUT/2);
+		entity1a.setLastSeenTimestamp(c.getTime());
+		c.add(Calendar.MILLISECOND, 1);
+		entity2.setLastSeenTimestamp(c.getTime());
+		c.add(Calendar.MILLISECOND, 1);
+		entity3.setLastSeenTimestamp(c.getTime());
+
+
+
+		IDevice d;
+		d = deviceManager.learnDeviceByEntity(entity1);
+		d = deviceManager.learnDeviceByEntity(entity1a);
+		d = deviceManager.learnDeviceByEntity(entity2);
+		d = deviceManager.learnDeviceByEntity(entity3);
+
+		// all entities are active, so entity3 should win
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(10L), OFPort.of(1)) },
+				d.getAttachmentPoints());
+
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(10L), OFPort.of(1)),},
+				d.getAttachmentPoints(true));
+
+		c.add(Calendar.MILLISECOND, Entity.ACTIVITY_TIMEOUT/4);
+		entity1.setLastSeenTimestamp(c.getTime());
+		d = deviceManager.learnDeviceByEntity(entity1);
+
+		// all are still active; entity3 should still win
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(1L), OFPort.of(1)) },
+				d.getAttachmentPoints());
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(1L), OFPort.of(1)),
+				new SwitchPort(DatapathId.of(5L), OFPort.of(1),
+						ErrorStatus.DUPLICATE_DEVICE),
+						new SwitchPort(DatapathId.of(10L), OFPort.of(1),
+								ErrorStatus.DUPLICATE_DEVICE) },
+								d.getAttachmentPoints(true));
+
+		c.add(Calendar.MILLISECOND, Entity.ACTIVITY_TIMEOUT+2000);
+		entity1.setLastSeenTimestamp(c.getTime());
+		d = deviceManager.learnDeviceByEntity(entity1);
+
+		assertEquals(entity1.getActiveSince(), entity1.getLastSeenTimestamp());
+		// entity1 should now be the only active entity
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(1L), OFPort.of(1)) },
+				d.getAttachmentPoints());
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(1L), OFPort.of(1)) },
+				d.getAttachmentPoints(true));
+	}
+
+
+	@Test
+	public void testAttachmentPointFlappingTwoCluster() throws Exception {
+		Calendar c = Calendar.getInstance();
+
+		ITopologyService mockTopology = createMock(ITopologyService.class);
+		expect(mockTopology.isAttachmentPointPort(DatapathId.of(anyLong()),
+				OFPort.of(anyShort()))).andReturn(true).anyTimes();
+		expect(mockTopology.isBroadcastDomainPort(DatapathId.of(anyLong()),
+				OFPort.of(anyShort()))).
+				andReturn(false).anyTimes();
+		expect(mockTopology.isInSameBroadcastDomain(DatapathId.of(anyLong()), OFPort.of(anyShort()),
+				DatapathId.of(anyLong()), OFPort.of(anyShort()))).andReturn(false).anyTimes();
+		expect(mockTopology.getL2DomainId(DatapathId.of(1L))).
+		andReturn(DatapathId.of(1L)).anyTimes();
+		expect(mockTopology.getL2DomainId(DatapathId.of(5L))).
+		andReturn(DatapathId.of(5L)).anyTimes();
+		expect(mockTopology.isConsistent(DatapathId.of(1L), OFPort.of(1), DatapathId.of(1L), OFPort.of(2))).
+		andReturn(false).anyTimes();
+		expect(mockTopology.isConsistent(DatapathId.of(1L), OFPort.of(2), DatapathId.of(5L), OFPort.of(1))).
+		andReturn(false).anyTimes();
+		expect(mockTopology.isConsistent(DatapathId.of(5L), OFPort.of(1), DatapathId.of(5L), OFPort.of(2))).
+		andReturn(false).anyTimes();
+		expect(mockTopology.isConsistent(DatapathId.of(1L), OFPort.of(2), DatapathId.of(1L), OFPort.of(1))).
+		andReturn(false).anyTimes();
+		expect(mockTopology.isConsistent(DatapathId.of(1L), OFPort.of(1), DatapathId.of(5L), OFPort.of(1))).
+		andReturn(false).anyTimes();
+		expect(mockTopology.isConsistent(DatapathId.of(1L), OFPort.of(1), DatapathId.of(5L), OFPort.of(2))).
+		andReturn(false).anyTimes();
+		expect(mockTopology.isConsistent(DatapathId.of(5L), OFPort.of(2), DatapathId.of(5L), OFPort.of(1))).
+		andReturn(false).anyTimes();
+
+		Date topologyUpdateTime = new Date();
+		expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
+		anyTimes();
+
+		replay(mockTopology);
+		deviceManager.topology = mockTopology;
+
+		Entity entity1 = new Entity(MacAddress.of(1L), null, null, DatapathId.of(1L), OFPort.of(1), c.getTime());
+		Entity entity2 = new Entity(MacAddress.of(1L), null, null, DatapathId.of(1L), OFPort.of(2), c.getTime());
+		Entity entity3 = new Entity(MacAddress.of(1L), null, null, DatapathId.of(5L), OFPort.of(1), c.getTime());
+		Entity entity4 = new Entity(MacAddress.of(1L), null, null, DatapathId.of(5L), OFPort.of(2), c.getTime());
+		entity1.setLastSeenTimestamp(c.getTime());
+		c.add(Calendar.MILLISECOND, Entity.ACTIVITY_TIMEOUT/2);
+		c.add(Calendar.MILLISECOND, 1);
+		entity2.setLastSeenTimestamp(c.getTime());
+		c.add(Calendar.MILLISECOND, 1);
+		entity3.setLastSeenTimestamp(c.getTime());
+		c.add(Calendar.MILLISECOND, 1);
+		entity4.setLastSeenTimestamp(c.getTime());
+
+		deviceManager.learnDeviceByEntity(entity1);
+		deviceManager.learnDeviceByEntity(entity2);
+		deviceManager.learnDeviceByEntity(entity3);
+		IDevice d = deviceManager.learnDeviceByEntity(entity4);
+
+		// all entities are active, so entities 2,4 should win
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(1L), OFPort.of(2)),
+				new SwitchPort(DatapathId.of(5L), OFPort.of(2)) },
+				d.getAttachmentPoints());
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(1L), OFPort.of(2)),
+				new SwitchPort(DatapathId.of(5L), OFPort.of(2))},
+				d.getAttachmentPoints(true));
+
+		c.add(Calendar.MILLISECOND, 1);
+		entity1.setLastSeenTimestamp(c.getTime());
+		d = deviceManager.learnDeviceByEntity(entity1);
+
+		// all entities are active, so entities 2,4 should win
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(1L), OFPort.of(1)),
+				new SwitchPort(DatapathId.of(5L), OFPort.of(2)) },
+				d.getAttachmentPoints());
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(1L), OFPort.of(1)),
+				new SwitchPort(DatapathId.of(5L), OFPort.of(2)),
+				new SwitchPort(DatapathId.of(1L), OFPort.of(2), ErrorStatus.DUPLICATE_DEVICE)},
+				d.getAttachmentPoints(true));
+
+		c.add(Calendar.MILLISECOND, Entity.ACTIVITY_TIMEOUT+1);
+		entity1.setLastSeenTimestamp(c.getTime());
+		d = deviceManager.learnDeviceByEntity(entity1);
+
+		// entities 3,4 are still in conflict, but 1 should be resolved
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(1L), OFPort.of(1)),
+				new SwitchPort(DatapathId.of(5L), OFPort.of(2)) },
+				d.getAttachmentPoints());
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(1L), OFPort.of(1)),
+				new SwitchPort(DatapathId.of(5L), OFPort.of(2))},
+				d.getAttachmentPoints(true));
+
+		entity3.setLastSeenTimestamp(c.getTime());
+		d = deviceManager.learnDeviceByEntity(entity3);
+
+		// no conflicts, 1 and 3 will win
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(1L), OFPort.of(1)),
+				new SwitchPort(DatapathId.of(5L), OFPort.of(1)) },
+				d.getAttachmentPoints());
+		assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(1L), OFPort.of(1)),
+				new SwitchPort(DatapathId.of(5L), OFPort.of(1)) },
+				d.getAttachmentPoints(true));
+
+	}
+
+	protected void doTestDeviceQuery() throws Exception {
+		Entity entity1 = new Entity(MacAddress.of(1L), VlanVid.ofVlan(1), IPv4Address.of(1), DatapathId.of(1L), OFPort.of(1), new Date());
+		Entity entity2 = new Entity(MacAddress.of(2L), VlanVid.ofVlan(2), IPv4Address.of(2), DatapathId.of(1L), OFPort.of(2), new Date());
+		Entity entity3 = new Entity(MacAddress.of(3L), VlanVid.ofVlan(3), IPv4Address.of(3), DatapathId.of(5L), OFPort.of(1), new Date());
+		Entity entity4 = new Entity(MacAddress.of(4L), VlanVid.ofVlan(4), IPv4Address.of(3), DatapathId.of(5L), OFPort.of(2), new Date());
+		Entity entity5 = new Entity(MacAddress.of(1L), VlanVid.ofVlan(4), IPv4Address.of(3), DatapathId.of(5L), OFPort.of(2), new Date());
+
+		Device d1 = deviceManager.learnDeviceByEntity(entity1);
+		deviceManager.learnDeviceByEntity(entity2);
+		Device d3 = deviceManager.learnDeviceByEntity(entity3);
+		Device d4 = deviceManager.learnDeviceByEntity(entity4);
+
+		IDevice d;
+
+		Iterator<? extends IDevice> iter =
+				deviceManager.queryDevices(null, VlanVid.ofVlan(1), IPv4Address.of(1), null, null);
+		int count = 0;
+		while (iter.hasNext()) {
+			count += 1;
+			d = iter.next();
+			assertEquals(d1.getDeviceKey(), d.getDeviceKey());
+		}
+		assertEquals(1, count);
+
+		iter = deviceManager.queryDevices(null, VlanVid.ofVlan(3), IPv4Address.of(3), null, null);
+		count = 0;
+		while (iter.hasNext()) {
+			count += 1;
+			d = iter.next();
+			assertEquals(d3.getDeviceKey(), d.getDeviceKey());
+		}
+		assertEquals(1, count);
+
+		iter = deviceManager.queryDevices(null, VlanVid.ofVlan(1), IPv4Address.of(3), null, null);
+		count = 0;
+		while (iter.hasNext()) {
+			count += 1;
+			iter.next();
+		}
+		assertEquals(0, count);
+
+		Device d5 = deviceManager.learnDeviceByEntity(entity5);
+		iter = deviceManager.queryDevices(null, VlanVid.ofVlan(4), IPv4Address.of(3), null, null);
+		count = 0;
+		Set<Long> deviceKeysFromIterator = new HashSet<Long>();
+		while (iter.hasNext()) {
+			count += 1;
+			d = iter.next();
+			deviceKeysFromIterator.add(d.getDeviceKey());
+		}
+		Set<Long> expectedDeviceKeys = new HashSet<Long>();
+		expectedDeviceKeys.add(d4.getDeviceKey());
+		expectedDeviceKeys.add(d5.getDeviceKey());
+		assertEquals(expectedDeviceKeys, deviceKeysFromIterator);
+		assertEquals(2, count);
+
+
+		iter = deviceManager.queryDevices(MacAddress.of(1L), null, null, null, null);
+		count = 0;
+		deviceKeysFromIterator = new HashSet<Long>();
+		while (iter.hasNext()) {
+			count += 1;
+			d = iter.next();
+			deviceKeysFromIterator.add(d.getDeviceKey());
+		}
+		expectedDeviceKeys = new HashSet<Long>();
+		expectedDeviceKeys.add(d1.getDeviceKey());
+		expectedDeviceKeys.add(d5.getDeviceKey());
+		assertEquals(expectedDeviceKeys, deviceKeysFromIterator);
+		assertEquals(2, count);
+	}
+
+	@Test
+	public void testDeviceIndex() throws Exception {
+		EnumSet<IDeviceService.DeviceField> indexFields =
+				EnumSet.noneOf(IDeviceService.DeviceField.class);
+		indexFields.add(IDeviceService.DeviceField.IPV4);
+		indexFields.add(IDeviceService.DeviceField.VLAN);
+		deviceManager.addIndex(false, indexFields);
+
+		indexFields = EnumSet.noneOf(IDeviceService.DeviceField.class);
+		deviceManager.addIndex(false, indexFields);
+
+		ITopologyService mockTopology = createMock(ITopologyService.class);
+		deviceManager.topology = mockTopology;
+		expect(mockTopology.isAttachmentPointPort(DatapathId.of(anyLong()),
+				OFPort.of(anyShort()))).
+				andReturn(true).anyTimes();
+		expect(mockTopology.getL2DomainId(DatapathId.of(EasyMock.anyLong()))).andReturn(DatapathId.of(1L)).anyTimes();
+		replay(mockTopology);
+		doTestDeviceQuery();
+	}
+
+	@Test
+	public void testDeviceQuery() throws Exception {
+		ITopologyService mockTopology = createMock(ITopologyService.class);
+		deviceManager.topology = mockTopology;
+		expect(mockTopology.isAttachmentPointPort(DatapathId.of(anyLong()),
+				OFPort.of(anyShort()))).
+				andReturn(true).anyTimes();
+		expect(mockTopology.getL2DomainId(DatapathId.of(EasyMock.anyLong()))).andReturn(DatapathId.of(1L)).anyTimes();
+		replay(mockTopology);
+
+		doTestDeviceQuery();
+	}
+
+	protected void doTestDeviceClassQuery() throws Exception {
+		Entity entity1 = new Entity(MacAddress.of(1L), VlanVid.ofVlan(1), IPv4Address.of(1), DatapathId.of(1L), OFPort.of(1), new Date());
+		Entity entity2 = new Entity(MacAddress.of(2L), VlanVid.ofVlan(2), IPv4Address.of(2), DatapathId.of(1L), OFPort.of(2), new Date());
+		Entity entity3 = new Entity(MacAddress.of(3L), VlanVid.ofVlan(3), IPv4Address.of(3), DatapathId.of(5L), OFPort.of(1), new Date());
+		Entity entity4 = new Entity(MacAddress.of(4L), VlanVid.ofVlan(4), IPv4Address.of(3), DatapathId.of(5L), OFPort.of(2), new Date());
+		Entity entity5 = new Entity(MacAddress.of(1L), VlanVid.ofVlan(4), IPv4Address.of(3), DatapathId.of(5L), OFPort.of(2), new Date());
+
+		IDevice d1 = deviceManager.learnDeviceByEntity(entity1);
+		IDevice d2 = deviceManager.learnDeviceByEntity(entity2);
+		IDevice d3 = deviceManager.learnDeviceByEntity(entity3);
+		IDevice d4 = deviceManager.learnDeviceByEntity(entity4);
+		assertEquals(d1.getEntityClass(), d2.getEntityClass());
+		assertEquals(d1.getEntityClass(), d3.getEntityClass());
+		assertEquals(d1.getEntityClass(), d4.getEntityClass());
+
+		IDevice d;
+
+		Iterator<? extends IDevice> iter =
+				deviceManager.queryClassDevices(d1.getEntityClass(), null,
+						VlanVid.ofVlan(1), IPv4Address.of(1), null, null);
+		int count = 0;
+		while (iter.hasNext()) {
+			count += 1;
+			d = iter.next();
+			assertEquals(d1.getDeviceKey(), d.getDeviceKey());
+		}
+		assertEquals(1, count);
+
+		iter = deviceManager.queryClassDevices(d1.getEntityClass(), null,
+				VlanVid.ofVlan(3), IPv4Address.of(3), null, null);
+		count = 0;
+		while (iter.hasNext()) {
+			count += 1;
+			d = iter.next();
+			assertEquals(d3.getDeviceKey(), d.getDeviceKey());
+
+		}
+		assertEquals(1, count);
+
+		iter = deviceManager.queryClassDevices(d1.getEntityClass(), null,
+				VlanVid.ofVlan(1), IPv4Address.of(3), null, null);
+		count = 0;
+		while (iter.hasNext()) {
+			count += 1;
+			iter.next();
+		}
+		assertEquals(0, count);
+
+		IDevice d5 = deviceManager.learnDeviceByEntity(entity5);
+		assertEquals(d1.getEntityClass(), d5.getEntityClass());
+		iter = deviceManager.queryClassDevices(d1.getEntityClass(), null,
+				VlanVid.ofVlan(4), IPv4Address.of(3), null, null);
+		count = 0;
+		Set<Long> deviceKeysFromIterator = new HashSet<Long>();
+		while (iter.hasNext()) {
+			count += 1;
+			d = iter.next();
+			deviceKeysFromIterator.add(d.getDeviceKey());
+		}
+		Set<Long> expectedDeviceKeys = new HashSet<Long>();
+		expectedDeviceKeys.add(d4.getDeviceKey());
+		expectedDeviceKeys.add(d5.getDeviceKey());
+		assertEquals(expectedDeviceKeys, deviceKeysFromIterator);
+		assertEquals(2, count);
+	}
+
+	@Test
+	public void testDeviceClassIndex() throws Exception {
+		EnumSet<IDeviceService.DeviceField> indexFields =
+				EnumSet.noneOf(IDeviceService.DeviceField.class);
+		indexFields.add(IDeviceService.DeviceField.IPV4);
+		indexFields.add(IDeviceService.DeviceField.VLAN);
+		deviceManager.addIndex(true, indexFields);
+
+		ITopologyService mockTopology = createMock(ITopologyService.class);
+		deviceManager.topology = mockTopology;
+		expect(mockTopology.isAttachmentPointPort(DatapathId.of(anyLong()),
+				OFPort.of(anyShort()))).
+				andReturn(true).anyTimes();
+		expect(mockTopology.getL2DomainId(DatapathId.of(EasyMock.anyLong()))).andReturn(DatapathId.of(1L)).anyTimes();
+		replay(mockTopology);
+
+		doTestDeviceClassQuery();
+	}
+
+	@Test
+	public void testDeviceClassQuery() throws Exception {
+		ITopologyService mockTopology = createMock(ITopologyService.class);
+		deviceManager.topology = mockTopology;
+		expect(mockTopology.isAttachmentPointPort(DatapathId.of(anyLong()),
+				OFPort.of(anyShort()))).andReturn(true).anyTimes();
+		expect(mockTopology.getL2DomainId(DatapathId.of(EasyMock.anyLong()))).andReturn(DatapathId.of(1L)).anyTimes();
+		replay(mockTopology);
+
+		doTestDeviceClassQuery();
+	}
+
+	@Test
+	public void testFindDevice() throws FloodlightModuleException {
+		boolean exceptionCaught;
+		deviceManager.entityClassifier= new MockEntityClassifierMac();
+		deviceManager.startUp(null);
+
+		ITopologyService mockTopology = createMock(ITopologyService.class);
+		deviceManager.topology = mockTopology;
+		expect(mockTopology.isAttachmentPointPort(DatapathId.of(anyLong()),
+				OFPort.of(anyShort()))).
+				andReturn(true).anyTimes();
+		expect(mockTopology.getL2DomainId(DatapathId.of(EasyMock.anyLong()))).andReturn(DatapathId.of(1L)).anyTimes();
+		replay(mockTopology);
+
+		Entity entity1 = new Entity(MacAddress.of(1L), VlanVid.ofVlan(1), IPv4Address.of(1), DatapathId.of(1L), OFPort.of(1), new Date());
+		Entity entity2 = new Entity(MacAddress.of(2L), VlanVid.ofVlan(2), IPv4Address.of(2), DatapathId.of(1L), OFPort.of(2), new Date());
+		Entity entity2b = new Entity(MacAddress.of(22L), VlanVid.ofVlan(2), IPv4Address.of(2), DatapathId.of(1L), OFPort.of(2), new Date());
+
+		Entity entity3 = new Entity(MacAddress.of(3L), VlanVid.ofVlan(1), IPv4Address.of(3), DatapathId.of(2L), OFPort.of(1), new Date());
+		Entity entity4 = new Entity(MacAddress.of(4L), VlanVid.ofVlan(2), IPv4Address.of(4), DatapathId.of(2L), OFPort.of(2), new Date());
+
+		Entity entity5 = new Entity(MacAddress.of(5L), VlanVid.ofVlan(1), IPv4Address.of(5), DatapathId.of(3L), OFPort.of(1), new Date());
+
+
+		IDevice d1 = deviceManager.learnDeviceByEntity(entity1);
+		IDevice d2 = deviceManager.learnDeviceByEntity(entity2);
+		IDevice d3 = deviceManager.learnDeviceByEntity(entity3);
+		IDevice d4 = deviceManager.learnDeviceByEntity(entity4);
+		IDevice d5 = deviceManager.learnDeviceByEntity(entity5);
+
+		// Make sure the entity classifier worked as expected
+		assertEquals(MockEntityClassifierMac.testECMac1, d1.getEntityClass());
+		assertEquals(MockEntityClassifierMac.testECMac1, d2.getEntityClass());
+		assertEquals(MockEntityClassifierMac.testECMac2, d3.getEntityClass());
+		assertEquals(MockEntityClassifierMac.testECMac2, d4.getEntityClass());
+		assertEquals(DefaultEntityClassifier.entityClass,
+				d5.getEntityClass());
+
+		// Look up the device using findDevice() which uses only the primary
+		// index
+		assertEquals(d1, deviceManager.findDevice(entity1.getMacAddress(),
+				entity1.getVlan(),
+				entity1.getIpv4Address(),
+				entity1.getSwitchDPID(),
+				entity1.getSwitchPort()));
+		// port changed. Device will be found through class index
+		assertEquals(d1, deviceManager.findDevice(entity1.getMacAddress(),
+				entity1.getVlan(),
+				entity1.getIpv4Address(),
+				entity1.getSwitchDPID(),
+				OFPort.of(entity1.getSwitchPort().getPortNumber()+1)));
+		// VLAN changed. No device matches
+		assertEquals(null, deviceManager.findDevice(entity1.getMacAddress(),
+				VlanVid.ofVlan(42),
+				entity1.getIpv4Address(),
+				entity1.getSwitchDPID(),
+				entity1.getSwitchPort()));
+		assertEquals(null, deviceManager.findDevice(entity1.getMacAddress(),
+				null,
+				entity1.getIpv4Address(),
+				entity1.getSwitchDPID(),
+				entity1.getSwitchPort()));
+		assertEquals(d2, deviceManager.findDeviceByEntity(entity2));
+		assertEquals(null, deviceManager.findDeviceByEntity(entity2b));
+		assertEquals(d3, deviceManager.findDevice(entity3.getMacAddress(),
+				entity3.getVlan(),
+				entity3.getIpv4Address(),
+				entity3.getSwitchDPID(),
+				entity3.getSwitchPort()));
+		// switch and port not set. throws exception
+		exceptionCaught = false;
+		try {
+			assertEquals(null, deviceManager.findDevice(entity3.getMacAddress(),
+					entity3.getVlan(),
+					entity3.getIpv4Address(),
+					null,
+					null));
+		}
+		catch (IllegalArgumentException e) {
+			exceptionCaught = true;
+		}
+		if (!exceptionCaught)
+			fail("findDevice() did not throw IllegalArgumentException");
+		assertEquals(d4, deviceManager.findDeviceByEntity(entity4));
+		assertEquals(d5, deviceManager.findDevice(entity5.getMacAddress(),
+				entity5.getVlan(),
+				entity5.getIpv4Address(),
+				entity5.getSwitchDPID(),
+				entity5.getSwitchPort()));
+		// switch and port not set. throws exception (swith/port are key
+		// fields of IEntityClassifier but not d5.entityClass
+		exceptionCaught = false;
+		try {
+			assertEquals(d5, deviceManager.findDevice(entity5.getMacAddress(),
+					entity5.getVlan(),
+					entity5.getIpv4Address(),
+					null,
+					null));
+		}
+		catch (IllegalArgumentException e) {
+			exceptionCaught = true;
+		}
+		if (!exceptionCaught)
+			fail("findDevice() did not throw IllegalArgumentException");
+
+
+		Entity entityNoClass = new Entity(MacAddress.of(5L), VlanVid.ofVlan(1), IPv4Address.of(5), DatapathId.of(-1L), OFPort.of(1), new Date());
+		assertEquals(null, deviceManager.findDeviceByEntity(entityNoClass));
+
+
+		// Now look up destination devices
+		assertEquals(d1, deviceManager.findClassDevice(d2.getEntityClass(),
+				entity1.getMacAddress(),
+				entity1.getVlan(),
+				entity1.getIpv4Address()));
+		assertEquals(d1, deviceManager.findClassDevice(d2.getEntityClass(),
+				entity1.getMacAddress(),
+				entity1.getVlan(),
+				null));
+		assertEquals(null, deviceManager.findClassDevice(d2.getEntityClass(),
+				entity1.getMacAddress(),
+				VlanVid.ofVlan(-1),
+				IPv4Address.of(0)));
+	}
+
+
+
+	@Test
+	public void testGetIPv4Addresses() {
+		// Looks like Date is only 1s granularity
+
+		ITopologyService mockTopology = createMock(ITopologyService.class);
+		deviceManager.topology = mockTopology;
+		expect(mockTopology.isAttachmentPointPort(DatapathId.of(anyLong()),
+				OFPort.of(anyShort()))).
+				andReturn(true).anyTimes();
+		expect(mockTopology.getL2DomainId(DatapathId.of(anyLong()))).andReturn(DatapathId.of(1L)).anyTimes();
+		expect(mockTopology.isConsistent(DatapathId.of(EasyMock.anyLong()),
+				OFPort.of(EasyMock.anyShort()),
+				DatapathId.of(EasyMock.anyLong()),
+				OFPort.of(EasyMock.anyShort())))
+				.andReturn(false)
+				.anyTimes();
+		expect(mockTopology.isBroadcastDomainPort(DatapathId.of(EasyMock.anyLong()),
+				OFPort.of(EasyMock.anyShort())))
+				.andReturn(false)
+				.anyTimes();
+		expect(mockTopology.isInSameBroadcastDomain(DatapathId.of(EasyMock.anyLong()),
+				OFPort.of(EasyMock.anyShort()),
+				DatapathId.of(EasyMock.anyLong()),
+				OFPort.of(EasyMock.anyShort()))).
+				andReturn(false).anyTimes();
+		replay(mockTopology);
+
+		Entity e1 = new Entity(MacAddress.of(1L), VlanVid.ofVlan(1), null, null, null, new Date(2000));
+		Device d1 = deviceManager.learnDeviceByEntity(e1);
+		assertArrayEquals(new Integer[0], d1.getIPv4Addresses());
+
+
+		Entity e2 = new Entity(MacAddress.of(2L), VlanVid.ofVlan(2), IPv4Address.of(2), null, null, new Date(2000));
+		Device d2 = deviceManager.learnDeviceByEntity(e2);
+		d2 = deviceManager.learnDeviceByEntity(e2);
+		assertArrayEquals(new Integer[] { 2 }, d2.getIPv4Addresses());
+		// More than one entity
+		Entity e2b = new Entity(MacAddress.of(2L), VlanVid.ofVlan(2), null, DatapathId.of(2L), OFPort.of(2), new Date(3000));
+		d2 = deviceManager.learnDeviceByEntity(e2b);
+		assertEquals(2, d2.entities.length);
+		assertArrayEquals(new Integer[] { 2 }, d2.getIPv4Addresses());
+		// and now add an entity with an IP
+		Entity e2c = new Entity(MacAddress.of(2L), VlanVid.ofVlan(2), IPv4Address.of(2), DatapathId.of(2L), OFPort.of(3), new Date(3000));
+		d2 = deviceManager.learnDeviceByEntity(e2c);
+		assertArrayEquals(new Integer[] { 2 }, d2.getIPv4Addresses());
+		assertEquals(3, d2.entities.length);
+
+		// Other devices with different IPs shouldn't interfere
+		Entity e3 = new Entity(MacAddress.of(3L), VlanVid.ofVlan(3), IPv4Address.of(3), null, null, new Date(4000));
+		Entity e3b = new Entity(MacAddress.of(3L), VlanVid.ofVlan(3), IPv4Address.of(3), DatapathId.of(3L), OFPort.of(3), new Date(4400));
+		Device d3 = deviceManager.learnDeviceByEntity(e3);
+		d3 = deviceManager.learnDeviceByEntity(e3b);
+		assertArrayEquals(new Integer[] { 2 }, d2.getIPv4Addresses());
+		assertArrayEquals(new Integer[] { 3 }, d3.getIPv4Addresses());
+
+		// Add another IP to d3
+		Entity e3c = new Entity(MacAddress.of(3L), VlanVid.ofVlan(3), IPv4Address.of(33), DatapathId.of(3L), OFPort.of(3), new Date(4400));
+		d3 = deviceManager.learnDeviceByEntity(e3c);
+		IPv4Address[] ips = d3.getIPv4Addresses();
+		Arrays.sort(ips);
+		assertArrayEquals(new Integer[] { 3, 33 }, ips);
+
+		// Add another device that also claims IP2 but is older than e2
+		Entity e4 = new Entity(MacAddress.of(4L), VlanVid.ofVlan(4), IPv4Address.of(2), null, null, new Date(1000));
+		Entity e4b = new Entity(MacAddress.of(4L), VlanVid.ofVlan(4), null, DatapathId.of(4L), OFPort.of(4), new Date(1000));
+		Device d4 = deviceManager.learnDeviceByEntity(e4);
+		assertArrayEquals(new Integer[] { 2 }, d2.getIPv4Addresses());
+		assertArrayEquals(new Integer[0],  d4.getIPv4Addresses());
+		// add another entity to d4
+		d4 = deviceManager.learnDeviceByEntity(e4b);
+		assertArrayEquals(new Integer[0], d4.getIPv4Addresses());
+
+		// Make e4 and e4a newer
+		Entity e4c = new Entity(MacAddress.of(4L), VlanVid.ofVlan(4), IPv4Address.of(2), null, null, new Date(5000));
+		Entity e4d = new Entity(MacAddress.of(4L), VlanVid.ofVlan(4), null, DatapathId.of(4L), OFPort.of(5), new Date(5000));
+		d4 = deviceManager.learnDeviceByEntity(e4c);
+		d4 = deviceManager.learnDeviceByEntity(e4d);
+		assertArrayEquals(new Integer[0], d2.getIPv4Addresses());
+		// FIXME: d4 should not return IP4
+		assertArrayEquals(new Integer[] { 2 }, d4.getIPv4Addresses());
+
+		// Add another newer entity to d2 but with different IP
+		Entity e2d = new Entity(MacAddress.of(2L), VlanVid.ofVlan(2), IPv4Address.of(22), DatapathId.of(4L), OFPort.of(6), new Date(6000));
+		d2 = deviceManager.learnDeviceByEntity(e2d);
+		assertArrayEquals(new Integer[] { 22 }, d2.getIPv4Addresses());
+		assertArrayEquals(new Integer[] { 2 }, d4.getIPv4Addresses());
+
+		// new IP for d2,d4 but with same timestamp. Both devices get the IP
+		Entity e2e = new Entity(MacAddress.of(2L), VlanVid.ofVlan(2), IPv4Address.of(42), DatapathId.of(2L), OFPort.of(4), new Date(7000));
+		d2 = deviceManager.learnDeviceByEntity(e2e);
+		ips= d2.getIPv4Addresses();
+		Arrays.sort(ips);
+		assertArrayEquals(new Integer[] { 22, 42 }, ips);
+		Entity e4e = new Entity(MacAddress.of(4L), VlanVid.ofVlan(4), IPv4Address.of(42), DatapathId.of(4L), OFPort.of(7), new Date(7000));
+		d4 = deviceManager.learnDeviceByEntity(e4e);
+		ips= d4.getIPv4Addresses();
+		Arrays.sort(ips);
+		assertArrayEquals(new Integer[] { 2, 42 }, ips);
+
+		// add a couple more IPs
+		Entity e2f = new Entity(MacAddress.of(2L), VlanVid.ofVlan(2), IPv4Address.of(4242), DatapathId.of(2L), OFPort.of(5), new Date(8000));
+		d2 = deviceManager.learnDeviceByEntity(e2f);
+		ips= d2.getIPv4Addresses();
+		Arrays.sort(ips);
+		assertArrayEquals(new Integer[] { 22, 42, 4242 }, ips);
+		Entity e4f = new Entity(MacAddress.of(4L), VlanVid.ofVlan(4), IPv4Address.of(4242), DatapathId.of(4L), OFPort.of(8), new Date(9000));
+		d4 = deviceManager.learnDeviceByEntity(e4f);
+		ips= d4.getIPv4Addresses();
+		Arrays.sort(ips);
+		assertArrayEquals(new Integer[] { 2, 42, 4242 }, ips);
+	}
+
+	// TODO: this test should really go into a separate class that collects
+	// unit tests for Device
+	@Test
+	public void testGetSwitchPortVlanId() {
+		Entity entity1 = new Entity(MacAddress.of(1L), VlanVid.ofVlan(1), null, DatapathId.of(10L), OFPort.of(1), new Date());
+		Entity entity2 = new Entity(MacAddress.of(1L), null, null, DatapathId.of(10L), OFPort.of(1), new Date());
+		Entity entity3 = new Entity(MacAddress.of(1L), VlanVid.ofVlan(3), null,  DatapathId.of(1L), OFPort.of(1), new Date());
+		Entity entity4 = new Entity(MacAddress.of(1L), VlanVid.ofVlan(42), null,  DatapathId.of(1L), OFPort.of(1), new Date());
+		Entity[] entities = new Entity[] { entity1, entity2,
+				entity3, entity4
+		};
+		Device d = new Device(null,1L, null, null, null,
+				Arrays.asList(entities), null);
+		SwitchPort swp1x1 = new SwitchPort(DatapathId.of(1L), OFPort.of(1));
+		SwitchPort swp1x2 = new SwitchPort(DatapathId.of(1L), OFPort.of(2));
+		SwitchPort swp2x1 = new SwitchPort(DatapathId.of(2L), OFPort.of(1));
+		SwitchPort swp10x1 = new SwitchPort(DatapathId.of(10L), OFPort.of(1));
+		assertArrayEquals(new Short[] { -1, 1},
+				d.getSwitchPortVlanIds(swp10x1));
+		assertArrayEquals(new Short[] { 3, 42},
+				d.getSwitchPortVlanIds(swp1x1));
+		assertArrayEquals(new Short[0],
+				d.getSwitchPortVlanIds(swp1x2));
+		assertArrayEquals(new Short[0],
+				d.getSwitchPortVlanIds(swp2x1));
+	}
+
+	@Test
+	public void testReclassifyDevice() throws FloodlightModuleException {
+		MockFlexEntityClassifier flexClassifier =
+				new MockFlexEntityClassifier();
+		deviceManager.entityClassifier= flexClassifier;
+		deviceManager.startUp(null);
+
+		ITopologyService mockTopology = createMock(ITopologyService.class);
+		deviceManager.topology = mockTopology;
+		expect(mockTopology.isAttachmentPointPort(DatapathId.of(anyLong()),
+				OFPort.of(anyShort()))).
+				andReturn(true).anyTimes();
+		expect(mockTopology.getL2DomainId(DatapathId.of(anyLong()))).andReturn(DatapathId.of(1L)).anyTimes();
+		expect(mockTopology.isConsistent(DatapathId.of(EasyMock.anyLong()),
+				OFPort.of(EasyMock.anyShort()),
+				DatapathId.of(EasyMock.anyLong()),
+				OFPort.of(EasyMock.anyShort())))
+				.andReturn(false)
+				.anyTimes();
+		expect(mockTopology.isBroadcastDomainPort(DatapathId.of(EasyMock.anyLong()),
+				OFPort.of(EasyMock.anyShort())))
+				.andReturn(false)
+				.anyTimes();
+		replay(mockTopology);
+
+		//flexClassifier.createTestEntityClass("Class1");
+
+		Entity entity1 = new Entity(MacAddress.of(1L), VlanVid.ofVlan(1), IPv4Address.of(1), DatapathId.of(1L), OFPort.of(1), new Date());
+		Entity entity1b = new Entity(MacAddress.of(1L), VlanVid.ofVlan(2), IPv4Address.of(1), DatapathId.of(1L), OFPort.of(1), new Date());
+		Entity entity2 = new Entity(MacAddress.of(2L), VlanVid.ofVlan(1), IPv4Address.of(2), DatapathId.of(2L), OFPort.of(2), new Date());
+		Entity entity2b = new Entity(MacAddress.of(2L), VlanVid.ofVlan(2), IPv4Address.of(2), DatapathId.of(2L), OFPort.of(2), new Date());
+
+
+		Device d1 = deviceManager.learnDeviceByEntity(entity1);
+		Device d2 = deviceManager.learnDeviceByEntity(entity2);
+		Device d1b = deviceManager.learnDeviceByEntity(entity1b);
+		Device d2b = deviceManager.learnDeviceByEntity(entity2b);
+
+		d1 = deviceManager.getDeviceIteratorForQuery(entity1.getMacAddress(),
+				entity1.getVlan(), entity1.getIpv4Address(),
+				entity1.getSwitchDPID(), entity1.getSwitchPort())
+				.next();
+		d1b = deviceManager.getDeviceIteratorForQuery(entity1b.getMacAddress(),
+				entity1b.getVlan(), entity1b.getIpv4Address(),
+				entity1b.getSwitchDPID(), entity1b.getSwitchPort()).next();
+
+		assertEquals(d1, d1b);
+
+		d2 = deviceManager.getDeviceIteratorForQuery(entity2.getMacAddress(),
+				entity2.getVlan(), entity2.getIpv4Address(),
+				entity2.getSwitchDPID(), entity2.getSwitchPort()).next();
+		d2b = deviceManager.getDeviceIteratorForQuery(entity2b.getMacAddress(),
+				entity2b.getVlan(), entity2b.getIpv4Address(),
+				entity2b.getSwitchDPID(), entity2b.getSwitchPort()).next();
+		assertEquals(d2, d2b);
+
+		IEntityClass eC1 = flexClassifier.createTestEntityClass("C1");
+		IEntityClass eC2 = flexClassifier.createTestEntityClass("C2");
+
+		flexClassifier.addVlanEntities((short)1, eC1);
+		flexClassifier.addVlanEntities((short)2, eC1);
+
+		deviceManager.reclassifyDevice(d1);
+		deviceManager.reclassifyDevice(d2);
+
+		d1 = deviceManager.deviceMap.get(
+				deviceManager.primaryIndex.findByEntity(entity1));
+		d1b = deviceManager.deviceMap.get(
+				deviceManager.primaryIndex.findByEntity(entity1b));
+
+		assertEquals(d1, d1b);
+
+		d2 = deviceManager.deviceMap.get(
+				deviceManager.primaryIndex.findByEntity(entity2));
+		d2b = deviceManager.deviceMap.get(
+				deviceManager.primaryIndex.findByEntity(entity2b));
+
+		assertEquals(d2, d2b);
+
+		flexClassifier.addVlanEntities((short)1, eC2);
+
+		deviceManager.reclassifyDevice(d1);
+		deviceManager.reclassifyDevice(d2);
+		d1 = deviceManager.deviceMap.get(
+				deviceManager.primaryIndex.findByEntity(entity1));
+		d1b = deviceManager.deviceMap.get(
+				deviceManager.primaryIndex.findByEntity(entity1b));
+		d2 = deviceManager.deviceMap.get(
+				deviceManager.primaryIndex.findByEntity(entity2));
+		d2b = deviceManager.deviceMap.get(
+				deviceManager.primaryIndex.findByEntity(entity2b));
+
+		assertNotSame(d1, d1b);
+
+		assertNotSame(d2, d2b);
+
+		flexClassifier.addVlanEntities((short)1, eC1);
+		deviceManager.reclassifyDevice(d1);
+		deviceManager.reclassifyDevice(d2);
+		ClassState classState = deviceManager.classStateMap.get(eC1.getName());
+
+		Long deviceKey1 = null;
+		Long deviceKey1b = null;
+		Long deviceKey2 = null;
+		Long deviceKey2b = null;
+
+		deviceKey1 =
+				classState.classIndex.findByEntity(entity1);
+		deviceKey1b =
+				classState.classIndex.findByEntity(entity1b);
+		deviceKey2 =
+				classState.classIndex.findByEntity(entity2);
+		deviceKey2b =
+				classState.classIndex.findByEntity(entity2b);
+
+		assertEquals(deviceKey1, deviceKey1b);
+
+		assertEquals(deviceKey2, deviceKey2b);
+	}
+
+	@Test
+	public void testSyncEntity() {
+		Date d1 = new Date();
+		Date d2 = new Date(0);
+		Entity e1 = new Entity(MacAddress.of(1L), VlanVid.ofVlan(2), IPv4Address.of(3), DatapathId.of(4L), OFPort.of(5), d1);
+		e1.setActiveSince(d2);
+		SyncEntity se1 = new SyncEntity(e1);
+		assertEntityEquals(e1, se1);
+		assertEquals(1L, se1.macAddress);
+		assertEquals(Short.valueOf((short)2), se1.vlan);
+		assertEquals(Integer.valueOf(3), se1.ipv4Address);
+		assertEquals(Long.valueOf(4L), se1.switchDPID);
+		assertEquals(Integer.valueOf(5), se1.switchPort);
+		assertEquals(d1, se1.lastSeenTimestamp);
+		assertEquals(d2, se1.activeSince);
+		assertNotSame(d1, se1.lastSeenTimestamp);
+		assertNotSame(d2, se1.activeSince);
+
+		Entity e2 = new Entity(MacAddress.of(42L), null, null, null, null, null);
+		SyncEntity se2 = new SyncEntity(e2);
+		assertEntityEquals(e2, se2);
+
+		SyncEntity se3 = new SyncEntity();
+		SyncEntity se4 = new SyncEntity();
+		se3.lastSeenTimestamp = new Date(1000);
+		se4.lastSeenTimestamp = new Date(2000);
+		assertTrue("", se3.compareTo(se4) < 0);
+		assertTrue("", se4.compareTo(se3) > 0);
+		se4.lastSeenTimestamp = new Date(1000);
+		assertTrue("", se3.compareTo(se4) == 0);
+		assertTrue("", se4.compareTo(se3) == 0);
+		se4.lastSeenTimestamp = new Date(500);
+		assertTrue("", se3.compareTo(se4) > 0);
+		assertTrue("", se4.compareTo(se3) < 0);
+	}
+
+	/* Test basic DeviceSyncRepresentation behavior */
+	@Test
+	public void testDeviceSyncRepresentationBasics() {
+		DeviceSyncRepresentation dsr = new DeviceSyncRepresentation();
+		assertNull(dsr.getKey());
+		assertNull(dsr.getEntities());
+		dsr.setKey("MyKey");
+		assertEquals("MyKey", dsr.getKey());
+		assertEquals("MyKey", dsr.toString());
+
+		List<SyncEntity> entities = new ArrayList<SyncEntity>();
+		Entity e1a = new Entity(MacAddress.of(1L), VlanVid.ofVlan(2), IPv4Address.of(3), DatapathId.of(4L), OFPort.of(5), new Date(1000));
+		Entity e1b = new Entity(MacAddress.of(1L), VlanVid.ofVlan(2), null, DatapathId.of(4L), OFPort.of(5), new Date(0));
+		entities.add(new SyncEntity(e1a));
+		entities.add(new SyncEntity(e1b));
+		// e1b comes before e1 (lastSeen) but we add it after it to test
+		// sorting
+		dsr.setEntities(entities);
+
+		assertEquals(2, dsr.getEntities().size());
+		// e1b has earlier time
+		assertEquals(e1b, dsr.getEntities().get(0).asEntity());
+		assertEquals(e1a, dsr.getEntities().get(1).asEntity());
+
+		dsr.setKey(null);
+		dsr.setEntities(null);
+		assertNull(dsr.getKey());
+		assertNull(dsr.getEntities());
+	}
+
+	@Test
+	public void testDeviceSyncRepresentationFromDevice() {
+		ITopologyService mockTopology = makeMockTopologyAllPortsAp();
+		replay(mockTopology);
+		deviceManager.topology = mockTopology;
+
+		deviceManager.entityClassifier = new MockEntityClassifier();
+
+		//**************************************
+		// Test 1: a single entity
+		Entity e1 = new Entity(MacAddress.of(1L), VlanVid.ofVlan(2), IPv4Address.of(3), DatapathId.of(4L), OFPort.of(5), new Date(1000));
+		Device d1 = deviceManager.learnDeviceByEntity(e1);
+		assertEquals("Sanity check failed. Device doesn't have the expected " +
+				"entity class. Something with the test setup is strange",
+				"DefaultEntityClass", d1.getEntityClass().getName());
+		assertEquals("Sanity check failed. Device doesn't have the expected " +
+				"entity class. Something with the test setup is strange",
+				EnumSet.of(DeviceField.MAC, DeviceField.VLAN),
+				d1.getEntityClass().getKeyFields());
+
+		Long deviceKey = d1.getDeviceKey();
+		DeviceSyncRepresentation dsr1 = new DeviceSyncRepresentation(d1);
+		assertEquals("DefaultEntityClass::00:00:00:00:00:01::[2]::",
+				dsr1.getKey());
+		assertEquals(1, dsr1.getEntities().size());
+		assertEquals(e1, dsr1.getEntities().get(0).asEntity());
+
+		//**************************************
+		// Test 1b: same device, now with a second entity (no IP).
+		// this second entity has a lastSeen time that is earlier than the
+		// first entity
+		Entity e1b = new Entity(MacAddress.of(1L), VlanVid.ofVlan(2), null, DatapathId.of(4L), OFPort.of(5), new Date(0));
+		d1 = deviceManager.learnDeviceByEntity(e1b);
+		assertEquals("Sanity check failed. Should still be same device but " +
+				"deviceKeys differs", deviceKey, d1.getDeviceKey());
+		dsr1 = new DeviceSyncRepresentation(d1);
+		assertEquals("DefaultEntityClass::00:00:00:00:00:01::[2]::",
+				dsr1.getKey());
+		assertEquals(2, dsr1.getEntities().size());
+		// Entities are ordered by their lastSeen time. e1b should come
+		// before e1.
+		assertEquals(e1, dsr1.getEntities().get(1).asEntity());
+		assertEquals(e1b, dsr1.getEntities().get(0).asEntity());
+
+		//**************************************
+		// Test 1c: same device with a third entity that does not have a
+		// switch port. It should be added to the DeviceSyncRepresentation
+		Entity e1c = new Entity(MacAddress.of(1L), VlanVid.ofVlan(2), IPv4Address.of(33), null, null, new Date(2000));
+		d1 = deviceManager.learnDeviceByEntity(e1c);
+		assertEquals("Sanity check failed. Should still be same device but " +
+				"deviceKeys differs", deviceKey, d1.getDeviceKey());
+		dsr1 = new DeviceSyncRepresentation(d1);
+		assertEquals("DefaultEntityClass::00:00:00:00:00:01::[2]::",
+				dsr1.getKey());
+		assertEquals(3, dsr1.getEntities().size());
+		// Entities are ordered by their lastSeen time
+		assertEquals(e1c, dsr1.getEntities().get(2).asEntity());
+		assertEquals(e1, dsr1.getEntities().get(1).asEntity());
+		assertEquals(e1b, dsr1.getEntities().get(0).asEntity());
+
+		//**************************************
+		// Test 1d: same device with a fourth entity that has a different
+		// attachment point and that is newer. Device should move and
+		// non-attachment point entities should be removed (e1b). Although
+		// e1 is non-attachment point it will remain because it has an IP
+		Entity e1d = new Entity(MacAddress.of(1L), VlanVid.ofVlan(2), IPv4Address.of(33), DatapathId.of(4L), OFPort.of(6), new Date(3000));
+		d1 = deviceManager.learnDeviceByEntity(e1d);
+		assertEquals("Sanity check failed. Should still be same device but " +
+				"deviceKeys differs", deviceKey, d1.getDeviceKey());
+		dsr1 = new DeviceSyncRepresentation(d1);
+		assertEquals("DefaultEntityClass::00:00:00:00:00:01::[2]::",
+				dsr1.getKey());
+		assertEquals(3, dsr1.getEntities().size());
+		assertEquals(e1, dsr1.getEntities().get(0).asEntity());
+		assertEquals(e1c, dsr1.getEntities().get(1).asEntity());
+		assertEquals(e1d, dsr1.getEntities().get(2).asEntity());
+
+		d1 = null;
+
+
+		//**************************************
+		// Test 2: a second device with a different entity class. The
+		// mock entity classifier will return an entity class where all
+		// fields are keys if the DPID is > 10L
+		Entity e2 = new Entity(MacAddress.of(2L), VlanVid.ofVlan(23), IPv4Address.of(24), DatapathId.of(11L), OFPort.of(1), new Date(0));
+		Device d2 = deviceManager.learnDeviceByEntity(e2);
+		DeviceSyncRepresentation dsr2 = new DeviceSyncRepresentation(d2);
+		assertEquals("Sanity check failed. Device doesn't have the expected " +
+				"entity class. Something with the test setup is strange",
+				"TestEntityClass", d2.getEntityClass().getName());
+		assertEquals("Sanity check failed. Device doesn't have the expected " +
+				"entity class. Something with the test setup is strange",
+				EnumSet.of(DeviceField.MAC, DeviceField.VLAN,
+						DeviceField.SWITCH, DeviceField.PORT),
+						d2.getEntityClass().getKeyFields());
+		SwitchPort swp = new SwitchPort(DatapathId.of(11L), OFPort.of(1), null);
+		assertEquals("TestEntityClass::00:00:00:00:00:02::[23]::[" +
+				swp.toString() + "]::",
+				dsr2.getKey());
+	}
+
+	/* interate through all entries in the sync store and return them as
+	 * list. We don't return the key from the store however, we assert
+	 * that the key from the store matches the key in the representation.
+	 * If we have a null value (tombstone) we simply add the null value to
+	 * the list to return.
+	 */
+	private List<DeviceSyncRepresentation> getEntriesFromStore()
+			throws Exception {
+		List<DeviceSyncRepresentation> entries =
+				new ArrayList<DeviceSyncRepresentation>();
+		IClosableIterator<Entry<String, Versioned<DeviceSyncRepresentation>>> iter =
+				storeClient.entries();
+		try {
+			while(iter.hasNext()) {
+				Entry<String, Versioned<DeviceSyncRepresentation>> entry =
+						iter.next();
+				DeviceSyncRepresentation dsr = entry.getValue().getValue();
+				if (dsr != null)
+					assertEquals(entry.getKey(), dsr.getKey());
+				entries.add(dsr);
+			}
+		} finally {
+			if (iter != null)
+				iter.close();
+		}
+		return entries;
+	}
+
+	/*
+	 * assert whether the given Entity expected is equals to the given
+	 * SyncEntity actual. This method also compares the times (lastSeen,
+	 * activeSince). Entity.equals will not do that!
+	 */
+	private static void assertEntityEquals(Entity expected, SyncEntity actual) {
+		assertNotNull(actual);
+		assertNotNull(expected);
+		Entity actualEntity = actual.asEntity();
+		assertEquals("entityFields", expected, actualEntity);
+		assertEquals("lastSeenTimestamp",
+				expected.getLastSeenTimestamp(),
+				actualEntity.getLastSeenTimestamp());
+		assertEquals("activeSince",
+				expected.getActiveSince(), actualEntity.getActiveSince());
+	}
+
+	/* This test tests the normal operation as master when we write to the sync
+	 * store or delete from the store.
+	 */
+	@Test
+	public void testWriteToSyncStore() throws Exception {
+		int syncStoreIntervalMs = 50;
+		ITopologyService mockTopology = makeMockTopologyAllPortsAp();
+		replay(mockTopology);
+		deviceManager.topology = mockTopology;
+		deviceManager.setSyncStoreWriteInterval(syncStoreIntervalMs);
+
+		Entity e1a = new Entity(MacAddress.of(1L), VlanVid.ofVlan(2), IPv4Address.of(3), DatapathId.of(4L), OFPort.of(5), new Date(1000));
+		e1a.setActiveSince(new Date(0));
+		deviceManager.learnDeviceByEntity(e1a);
+
+		//storeClient.put("FooBar", new DeviceSyncRepresentation());
+
+		List<DeviceSyncRepresentation> entries = getEntriesFromStore();
+		assertEquals(1, entries.size());
+		DeviceSyncRepresentation dsr1 = entries.get(0);
+		assertEquals(1, dsr1.getEntities().size());
+		assertEntityEquals(e1a, dsr1.getEntities().get(0));
+
+		// Same entity but newer timestamp. Since the device hasn't changed,
+		// only the timestamp is updated and the write should be throttled.
+		Entity e1b = new Entity(MacAddress.of(1L), VlanVid.ofVlan(2), IPv4Address.of(3), DatapathId.of(4L), OFPort.of(5), new Date(2000));
+		e1b.setActiveSince(new Date(0));
+		deviceManager.learnDeviceByEntity(e1a);
+		entries = getEntriesFromStore();
+		assertEquals(1, entries.size());
+		dsr1 = entries.get(0);
+		assertEquals(1, dsr1.getEntities().size());
+		assertEntityEquals(e1a, dsr1.getEntities().get(0)); //e1a not e1b !!!
+
+		// Wait for the write interval to expire then write again.
+		Thread.sleep(syncStoreIntervalMs+5);
+		Entity e1c = new Entity(MacAddress.of(1L), VlanVid.ofVlan(2), IPv4Address.of(3), DatapathId.of(4L), OFPort.of(5), new Date(3000));
+		e1c.setActiveSince(new Date(0));
+		deviceManager.learnDeviceByEntity(e1c);
+		entries = getEntriesFromStore();
+		assertEquals(1, entries.size());
+		dsr1 = entries.get(0);
+		assertEquals(1, dsr1.getEntities().size());
+		assertEntityEquals(e1c, dsr1.getEntities().get(0)); // e1c !!
+
+		// Entity for same device but with different IP. should be added
+		// immediately
+		Entity e1d = new Entity(MacAddress.of(1L), VlanVid.ofVlan(2), IPv4Address.of(33), DatapathId.of(4L), OFPort.of(5), new Date(4000));
+		e1d.setActiveSince(new Date(0));
+		deviceManager.learnDeviceByEntity(e1d);
+		entries = getEntriesFromStore();
+		assertEquals(1, entries.size());
+		dsr1 = entries.get(0);
+		assertEquals(2, dsr1.getEntities().size());
+		assertEntityEquals(e1c, dsr1.getEntities().get(0)); // e1c !!
+		assertEntityEquals(e1d, dsr1.getEntities().get(1)); // e1d !!
+
+		// Entity for same device with new switch port ==> moved ==> write
+		// update immediately without throttle.
+		// Note: the previous entities will still be there because they have
+		// IPs (even though they aren't for the current attachment point)
+		Entity e1e = new Entity(MacAddress.of(1L), VlanVid.ofVlan(2), IPv4Address.of(33), DatapathId.of(4L), OFPort.of(6), new Date(5000));
+		e1e.setActiveSince(new Date(0));
+		deviceManager.learnDeviceByEntity(e1e);
+		entries = getEntriesFromStore();
+		assertEquals(1, entries.size());
+		dsr1 = entries.get(0);
+		assertEquals(3, dsr1.getEntities().size());
+		assertEntityEquals(e1c, dsr1.getEntities().get(0));
+		assertEntityEquals(e1d, dsr1.getEntities().get(1));
+		assertEntityEquals(e1e, dsr1.getEntities().get(2));
+
+		// Add a second device
+		Entity e2 = new Entity(MacAddress.of(2L), null, null, DatapathId.of(5L), OFPort.of(5), new Date());
+		deviceManager.learnDeviceByEntity(e2);
+		entries = getEntriesFromStore();
+		assertEquals(2, entries.size());
+		for (DeviceSyncRepresentation dsr: entries) {
+			// This is a kinda ugly way to ensure we have the two
+			// devices we need..... but it will work for now
+			if (dsr.getKey().contains("::00:00:00:00:00:01::")) {
+				assertEquals(3, dsr.getEntities().size());
+				assertEntityEquals(e1c, dsr.getEntities().get(0));
+				assertEntityEquals(e1d, dsr.getEntities().get(1));
+				assertEntityEquals(e1e, dsr.getEntities().get(2));
+			} else if (dsr.getKey().contains("::00:00:00:00:00:02::")) {
+				assertEquals(1, dsr.getEntities().size());
+				assertEntityEquals(e2, dsr.getEntities().get(0));
+			} else {
+				fail("Unknown entry in store: " + dsr);
+			}
+		}
+
+
+		// Run entity cleanup. Since we've used phony time stamps for
+		// device 1 its entities should be cleared and the device should be
+		// removed from the store. Device 2 should remain in the store.
+		deviceManager.cleanupEntities();
+		entries = getEntriesFromStore();
+		assertEquals(2, entries.size());
+		for (DeviceSyncRepresentation dsr: entries) {
+			if (dsr == null) {
+				// pass
+			} else if (dsr.getKey().contains("::00:00:00:00:00:02::")) {
+				assertEquals(1, dsr.getEntities().size());
+				assertEntityEquals(e2, dsr.getEntities().get(0));
+			} else {
+				fail("Unknown entry in store: " + dsr);
+			}
+		}
+	}
+
+
+	private void assertDeviceIps(Integer[] expected, IDevice d) {
+		List<Integer> expectedList = Arrays.asList(expected);
+		Collections.sort(expectedList);
+		List<IPv4Address> actualList = Arrays.asList(d.getIPv4Addresses());
+		Collections.sort(actualList);
+		assertEquals(expectedList, actualList);
+	}
+
+	private IDevice getSingleDeviceFromDeviceManager(long mac) {
+		Iterator<? extends IDevice> diter =
+				deviceManager.queryDevices(MacAddress.of(mac), null, null, null, null);
+		assertTrue("Query didn't return a device", diter.hasNext());
+		IDevice d = diter.next();
+		assertFalse("Query returned more than one device", diter.hasNext());
+		return d;
+	}
+
+	@Test
+	public void testToMaster() throws Exception {
+		int syncStoreWriteIntervalMs = 0;
+		int initialSyncStoreConsolidateIntervalMs = 50;
+		ITopologyService mockTopology = makeMockTopologyAllPortsAp();
+		replay(mockTopology);
+		deviceManager.topology = mockTopology;
+		// We want an EntityClassifier that has switch/port as key fields
+		deviceManager.entityClassifier = new MockEntityClassifier();
+		deviceManager.setSyncStoreWriteInterval(syncStoreWriteIntervalMs);
+		deviceManager.setInitialSyncStoreConsolidateMs(initialSyncStoreConsolidateIntervalMs);
+
+		// Add Device1 with two entities with two different IPs
+		Entity e1a = new Entity(MacAddress.of(1L), null, IPv4Address.of(3), DatapathId.of(4L), OFPort.of(5), new Date(1000));
+		Entity e1b = new Entity(MacAddress.of(1L), null, IPv4Address.of(33),  DatapathId.of(4L), OFPort.of(5), new Date(2000));
+		Device d1 = deviceManager.allocateDevice(1L, e1a,
+				DefaultEntityClassifier.entityClass);
+		d1 = deviceManager.allocateDevice(d1, e1b, -1);
+		DeviceSyncRepresentation dsr = new DeviceSyncRepresentation(d1);
+		storeClient.put(dsr.getKey(), dsr);
+
+		// Add Device2 with different switch-ports. Only the most recent
+		// one should be the attachment point
+		Entity e2a = new Entity(MacAddress.of(2L), null, null, DatapathId.of(4L), OFPort.of(4), new Date(1000));
+		Entity e2b = new Entity(MacAddress.of(2L), null, null, DatapathId.of(4L), OFPort.of(5), new Date(2000));
+		Device d2 = deviceManager.allocateDevice(2L, e2a,
+				DefaultEntityClassifier.entityClass);
+		d2 = deviceManager.allocateDevice(d2, e2b, -1);
+		d2.updateAttachmentPoint(DatapathId.of(4L), OFPort.of(5),
+				e2b.getLastSeenTimestamp());
+		SwitchPort swp = new SwitchPort(DatapathId.of(4L), OFPort.of(5));
+		SwitchPort[] aps = d2.getAttachmentPoints();
+		// sanity check
+		assertArrayEquals("Sanity check: should only have AP(4L,5)",
+				new SwitchPort[] {swp}, aps);
+		dsr = new DeviceSyncRepresentation(d2);
+		storeClient.put(dsr.getKey(), dsr);
+
+		// Add a tombstone entry to the store to make sure we don't trip a
+		// NPE
+		dsr = null;
+		Versioned<DeviceSyncRepresentation> versionedDsr =
+				storeClient.get("FooBar");
+		storeClient.put("FooBar", versionedDsr);
+
+		deviceManager.getHAListener().transitionToActive();
+
+		// Query for the Device1. Make sure we have the two IPs we stored.
+		IDevice d = getSingleDeviceFromDeviceManager(1L);
+		assertDeviceIps(new Integer[] {3, 33}, d);
+		assertArrayEquals(new Short[] { Ethernet.VLAN_UNTAGGED }, d.getVlanId());
+		swp = new SwitchPort(DatapathId.of(4L), OFPort.of(5));
+		assertArrayEquals(new SwitchPort[] { swp }, d.getAttachmentPoints());
+
+		// Query for Device2. Make sure we only have the more recent AP
+		// Query for the Device1. Make sure we have the two IPs we stored.
+		d = getSingleDeviceFromDeviceManager(2L);
+		assertArrayEquals(new Integer[0], d.getIPv4Addresses());
+		assertArrayEquals(new Short[] { Ethernet.VLAN_UNTAGGED }, d.getVlanId());
+		swp = new SwitchPort(DatapathId.of(4L), OFPort.of(5));
+		assertArrayEquals(new SwitchPort[] { swp }, d.getAttachmentPoints());
+
+		//----------------------------
+		// add another entry device to the store. since device manager is
+		// already master we won't read this device and it should be
+		// removed from the store by the consolidate task
+		Entity e3 = new Entity(MacAddress.of(3L), null, null, DatapathId.of(1L), OFPort.of(1), null);
+		dsr = new DeviceSyncRepresentation();
+		dsr.setKey("Device3");
+		dsr.setEntities(Collections.singletonList(new SyncEntity(e3)));
+		storeClient.put(dsr.getKey(), dsr);
+
+		// make sure it's in the store
+		List<DeviceSyncRepresentation> entries = getEntriesFromStore();
+		boolean found = false;
+		for (DeviceSyncRepresentation entry: entries) {
+			if (entry!=null && entry.getKey().equals("Device3"))
+				found = true;
+		}
+		assertTrue("Device3 not in store. Entries in store: " + entries, found);
+		// make sure it's not in DevManager
+		Iterator<? extends IDevice> diter =
+				deviceManager.queryDevices(MacAddress.of(3L), null, null, null, null);
+		assertFalse("Device3 found in DeviceManager. Should be there",
+				diter.hasNext());
+
+		// Wait for consolidate
+		Thread.sleep(initialSyncStoreConsolidateIntervalMs + 5);
+		// make sure it's in NOT the store
+		entries = getEntriesFromStore();
+		found = false;
+		for (DeviceSyncRepresentation entry: entries) {
+			if (entry!=null && entry.getKey().equals("Device3"))
+				found = true;
+		}
+		assertFalse("Device3 not is still in the store. Entries in store: "
+				+ entries, found);
+		// make sure it's not in DevManager
+		diter = deviceManager.queryDevices(MacAddress.of(3L), null, null, null, null);
+		assertFalse("Device3 found in DeviceManager. Should be there",
+				diter.hasNext());
+	}
+
+
+	@Test
+	public void testConsolitateStore() throws Exception {
+		int syncStoreInternalMs = 0;
+		ITopologyService mockTopology = makeMockTopologyAllPortsAp();
+		replay(mockTopology);
+		deviceManager.topology = mockTopology;
+		// We want an EntityClassifier that has switch/port as key fields
+		deviceManager.entityClassifier = new MockEntityClassifier();
+		deviceManager.setSyncStoreWriteInterval(syncStoreInternalMs);
+
+		// Add Device1 with two entities to store and let device manager
+		// learn
+		Entity e1a = new Entity(MacAddress.of(1L), null, null, DatapathId.of(4L), OFPort.of(5), new Date(1000));
+		Entity e1b = new Entity(MacAddress.of(1L), null, IPv4Address.of(3),  DatapathId.of(4L), OFPort.of(5), new Date(2000));
+		Device d1 = deviceManager.learnDeviceByEntity(e1a);
+		deviceManager.learnDeviceByEntity(e1b);
+		String dev1Key = DeviceSyncRepresentation.computeKey(d1);
+
+
+		// Add a second device to the store but do NOT add to device manager
+		Entity e2 = new Entity(MacAddress.of(2L), null, null, DatapathId.of(5L), OFPort.of(5), new Date());
+		Device d2 = deviceManager.allocateDevice(42L, e2,
+				DefaultEntityClassifier.entityClass);
+		DeviceSyncRepresentation dsr = new DeviceSyncRepresentation(d2);
+		storeClient.put(dsr.getKey(), dsr);
+		String dev2Key = DeviceSyncRepresentation.computeKey(d2);
+
+		// Make sure we have two devices in the store
+		List<DeviceSyncRepresentation> entries = getEntriesFromStore();
+		assertEquals(2, entries.size());
+
+		deviceManager.scheduleConsolidateStoreNow();
+		Thread.sleep(25); // give the scheduler time to run the task
+
+		// We should still have two entries, however one of them will be a
+		// tombstone
+		entries = getEntriesFromStore();
+		assertEquals(2, entries.size());
+
+		// Device 1 should still be in store
+		Versioned<DeviceSyncRepresentation> versioned =
+				storeClient.get(dev1Key);
+		dsr = versioned.getValue();
+		assertNotNull(dsr);
+		assertEquals(2, dsr.getEntities().size());
+		assertEntityEquals(e1a, dsr.getEntities().get(0));
+		assertEntityEquals(e1b, dsr.getEntities().get(1));
+
+		// Device2 should be gone
+		versioned = storeClient.get(dev2Key);
+		assertNull(versioned.getValue());
+
+		// Run consolitate again. This time we check that tombstones in
+		// the store are handled correctly
+		deviceManager.scheduleConsolidateStoreNow();
+		Thread.sleep(25); // give the scheduler time to run the task
+
+		// Now write a device to the store that doesn't have any switch-port
+		// it should be removed
+		Entity e3 = new Entity(MacAddress.of(3L), null, null, null, null, null);
+		dsr.setKey("Device3");
+		dsr.setEntities(Collections.singletonList(new SyncEntity(e3)));
+		storeClient.put(dsr.getKey(), dsr);
+
+		// Run consolitate again. This time we check that tombstones in
+		// the store are handled correctly
+		deviceManager.scheduleConsolidateStoreNow();
+		Thread.sleep(25); // give the scheduler time to run the task
+		versioned = storeClient.get("Device3");
+		assertNull(versioned.getValue());
+
+	}
 
 }
diff --git a/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceUniqueIndexTest.java b/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceUniqueIndexTest.java
index 1ac1f1c35d5a13601df137c7e4669bf605c76d8b..e820f9e082e1ce9aa4c0686f7b87f05c34d88897 100644
--- a/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceUniqueIndexTest.java
+++ b/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceUniqueIndexTest.java
@@ -26,6 +26,12 @@ import java.util.Set;
 import java.util.Iterator;
 
 import org.junit.Test;
+import org.projectfloodlight.openflow.types.DatapathId;
+import org.projectfloodlight.openflow.types.IPv4Address;
+import org.projectfloodlight.openflow.types.MacAddress;
+import org.projectfloodlight.openflow.types.OFPort;
+import org.projectfloodlight.openflow.types.VlanVid;
+
 import net.floodlightcontroller.devicemanager.IDeviceService.DeviceField;
 import junit.framework.TestCase;
 
@@ -46,8 +52,8 @@ public class DeviceUniqueIndexTest extends TestCase {
     @Override
     protected void setUp() throws Exception {
         super.setUp();
-        e1a = new Entity(1L, (short)1, 1, 1L, 1, new Date());
-        e1b = new Entity(1L, (short)2, 1, 1L, 1, new Date());
+        e1a = new Entity(MacAddress.of(1L), VlanVid.ofVlan(1), IPv4Address.of(1), DatapathId.of(1L), OFPort.of(1), new Date());
+        e1b = new Entity(MacAddress.of(1L), VlanVid.ofVlan(2), IPv4Address.of(1), DatapathId.of(1L), OFPort.of(1), new Date());
         List<Entity> d1Entities = new ArrayList<Entity>(2);
         d1Entities.add(e1a);
         d1Entities.add(e1b);
@@ -55,14 +61,14 @@ public class DeviceUniqueIndexTest extends TestCase {
                         d1Entities, null);
         
         // e2 and e2 alt match in MAC and VLAN
-        e2 = new Entity(2L, (short)2, 2, 2L, 2, new Date());
-        e2alt = new Entity(2, (short)2, null, null, null, null);
+        e2 = new Entity(MacAddress.of(2L), VlanVid.ofVlan(2), IPv4Address.of(2), DatapathId.of(2L), OFPort.of(2), new Date());
+        e2alt = new Entity(MacAddress.of(2L), VlanVid.ofVlan(2), null, null, null, null);
         
         // IP is null
-        e3 = new Entity(3L, (short)3, null, 3L, 3, new Date());
+        e3 = new Entity(MacAddress.of(3L), VlanVid.ofVlan(3), null, DatapathId.of(3L), OFPort.of(3), new Date());
         
         // IP and switch and port are null
-        e4 = new Entity(4L, (short)4, null, null, null, new Date());
+        e4 = new Entity(MacAddress.of(4L), VlanVid.ofVlan(4), null, null, null, new Date());
     }
     
     /*
@@ -141,7 +147,7 @@ public class DeviceUniqueIndexTest extends TestCase {
         // only one key field is null
         idx2.updateIndex(e3, 3L);
         assertEquals(Long.valueOf(3L), idx2.findByEntity(e3));
-        e3.ipv4Address = 3;
+        e3.ipv4Address = IPv4Address.of(3);
         assertEquals(null, idx2.findByEntity(e3));
         // all key fields are null
         idx2.updateIndex(e4, 4L);
diff --git a/src/test/java/net/floodlightcontroller/devicemanager/test/MockDevice.java b/src/test/java/net/floodlightcontroller/devicemanager/test/MockDevice.java
index 5657cc515792d534179e5d66116f362a232c2098..f8c0bc3f082159a81fd6cdbfb0761ebf57182a00 100644
--- a/src/test/java/net/floodlightcontroller/devicemanager/test/MockDevice.java
+++ b/src/test/java/net/floodlightcontroller/devicemanager/test/MockDevice.java
@@ -23,6 +23,8 @@ import java.util.Collection;
 import java.util.List;
 import java.util.TreeSet;
 
+import org.projectfloodlight.openflow.types.IPv4Address;
+
 import net.floodlightcontroller.devicemanager.IEntityClass;
 import net.floodlightcontroller.devicemanager.SwitchPort;
 import net.floodlightcontroller.devicemanager.internal.AttachmentPoint;
@@ -57,14 +59,14 @@ public class MockDevice extends Device {
     }
 
     @Override
-    public Integer[] getIPv4Addresses() {
-        TreeSet<Integer> vals = new TreeSet<Integer>();
+    public IPv4Address[] getIPv4Addresses() {
+        TreeSet<IPv4Address> vals = new TreeSet<IPv4Address>();
         for (Entity e : entities) {
             if (e.getIpv4Address() == null) continue;
             vals.add(e.getIpv4Address());
         }
         
-        return vals.toArray(new Integer[vals.size()]);
+        return vals.toArray(new IPv4Address[vals.size()]);
     }
 
     @Override
diff --git a/src/test/java/net/floodlightcontroller/devicemanager/test/MockDeviceManager.java b/src/test/java/net/floodlightcontroller/devicemanager/test/MockDeviceManager.java
index f15061ad0a1397cf7564124e26dd071a148fe997..29059e340ea2a4ad13aaff7cd8d785ba4429dec9 100644
--- a/src/test/java/net/floodlightcontroller/devicemanager/test/MockDeviceManager.java
+++ b/src/test/java/net/floodlightcontroller/devicemanager/test/MockDeviceManager.java
@@ -20,6 +20,11 @@ import java.util.Collection;
 import java.util.Date;
 import java.util.List;
 
+import org.projectfloodlight.openflow.types.DatapathId;
+import org.projectfloodlight.openflow.types.IPv4Address;
+import org.projectfloodlight.openflow.types.MacAddress;
+import org.projectfloodlight.openflow.types.OFPort;
+import org.projectfloodlight.openflow.types.VlanVid;
 import org.sdnplatform.sync.test.MockSyncService;
 
 import net.floodlightcontroller.core.module.FloodlightModuleContext;
@@ -38,106 +43,106 @@ import net.floodlightcontroller.devicemanager.internal.Entity;
  * @author readams
  */
 public class MockDeviceManager extends DeviceManagerImpl {
-    /**
-     * Set a new IEntityClassifier
-     * Use this as a quick way to use a particular entity classifier in a
-     * single test without having to setup the full FloodlightModuleContext
-     * again.
-     * @param ecs
-     */
-    public void setEntityClassifier(IEntityClassifierService ecs) {
-        this.entityClassifier = ecs;
-        try {
-            this.startUp(null);
-        } catch (FloodlightModuleException e) {
-            throw new RuntimeException(e);
-        }
-    }
+	/**
+	 * Set a new IEntityClassifier
+	 * Use this as a quick way to use a particular entity classifier in a
+	 * single test without having to setup the full FloodlightModuleContext
+	 * again.
+	 * @param ecs
+	 */
+	public void setEntityClassifier(IEntityClassifierService ecs) {
+		this.entityClassifier = ecs;
+		try {
+			this.startUp(null);
+		} catch (FloodlightModuleException e) {
+			throw new RuntimeException(e);
+		}
+	}
 
-    /**
-     * Learn a device using the given characteristics.
-     * @param macAddress the MAC
-     * @param vlan the VLAN (can be null)
-     * @param ipv4Address the IP (can be null)
-     * @param switchDPID the attachment point switch DPID (can be null)
-     * @param switchPort the attachment point switch port (can be null)
-     * @param processUpdates if false, will not send updates.  Note that this
-     * method is not thread safe if this is false
-     * @return the device, either new or not
-     */
-    public IDevice learnEntity(long macAddress, Short vlan,
-                               Integer ipv4Address, Long switchDPID,
-                               Integer switchPort,
-                               boolean processUpdates) {
-        List<IDeviceListener> listeners = deviceListeners.getOrderedListeners();
-        if (!processUpdates) {
-            deviceListeners.clearListeners();
-        }
+	/**
+	 * Learn a device using the given characteristics.
+	 * @param macAddress the MAC
+	 * @param vlan the VLAN (can be null)
+	 * @param ipv4Address the IP (can be null)
+	 * @param switchDPID the attachment point switch DPID (can be null)
+	 * @param switchPort the attachment point switch port (can be null)
+	 * @param processUpdates if false, will not send updates.  Note that this
+	 * method is not thread safe if this is false
+	 * @return the device, either new or not
+	 */
+	public IDevice learnEntity(long macAddress, Short vlan,
+			Integer ipv4Address, Long switchDPID,
+			Integer switchPort,
+			boolean processUpdates) {
+		List<IDeviceListener> listeners = deviceListeners.getOrderedListeners();
+		if (!processUpdates) {
+			deviceListeners.clearListeners();
+		}
 
-        if (vlan != null && vlan.shortValue() <= 0)
-            vlan = null;
-        if (ipv4Address != null && ipv4Address == 0)
-            ipv4Address = null;
-        IDevice res =  learnDeviceByEntity(new Entity(macAddress, vlan,
-                                                      ipv4Address, switchDPID,
-                                                      switchPort, new Date()));
-        // Restore listeners
-        if (listeners != null) {
-            for (IDeviceListener listener : listeners) {
-                deviceListeners.addListener("device", listener);
-            }
-        }
-        return res;
-    }
+		if (vlan != null && vlan.shortValue() <= 0)
+			vlan = null;
+		if (ipv4Address != null && ipv4Address == 0)
+			ipv4Address = null;
+		IDevice res =  learnDeviceByEntity(new Entity(MacAddress.of(macAddress), VlanVid.ofVlan(vlan),
+				IPv4Address.of(ipv4Address), DatapathId.of(switchDPID),
+				OFPort.of(switchPort), new Date()));
+		// Restore listeners
+		if (listeners != null) {
+			for (IDeviceListener listener : listeners) {
+				deviceListeners.addListener("device", listener);
+			}
+		}
+		return res;
+	}
 
-    @Override
-    public void deleteDevice(Device device) {
-        super.deleteDevice(device);
-    }
+	@Override 
+	public void deleteDevice(Device device) {
+		super.deleteDevice(device);
+	}
 
-    /**
-     * Learn a device using the given characteristics.
-     * @param macAddress the MAC
-     * @param vlan the VLAN (can be null)
-     * @param ipv4Address the IP (can be null)
-     * @param switchDPID the attachment point switch DPID (can be null)
-     * @param switchPort the attachment point switch port (can be null)
-     * @return the device, either new or not
-     */
-    public IDevice learnEntity(long macAddress, Short vlan,
-                               Integer ipv4Address, Long switchDPID,
-                               Integer switchPort) {
-        return learnEntity(macAddress, vlan, ipv4Address,
-                           switchDPID, switchPort, true);
-    }
+	/**
+	 * Learn a device using the given characteristics.
+	 * @param macAddress the MAC
+	 * @param vlan the VLAN (can be null)
+	 * @param ipv4Address the IP (can be null)
+	 * @param switchDPID the attachment point switch DPID (can be null)
+	 * @param switchPort the attachment point switch port (can be null)
+	 * @return the device, either new or not
+	 */
+	public IDevice learnEntity(long macAddress, Short vlan,
+			Integer ipv4Address, Long switchDPID,
+			Integer switchPort) {
+		return learnEntity(macAddress, vlan, ipv4Address,
+				switchDPID, switchPort, true);
+	}
 
-    @Override
-    protected Device allocateDevice(Long deviceKey,
-                                    Entity entity,
-                                    IEntityClass entityClass) {
-        return new MockDevice(this, deviceKey, entity, entityClass);
-    }
+	@Override
+	protected Device allocateDevice(Long deviceKey,
+			Entity entity,
+			IEntityClass entityClass) {
+		return new MockDevice(this, deviceKey, entity, entityClass);
+	}
 
-    @Override
-    protected Device allocateDevice(Long deviceKey,
-                                    String dhcpClientName,
-                                    List<AttachmentPoint> aps,
-                                    List<AttachmentPoint> trueAPs,
-                                    Collection<Entity> entities,
-                                    IEntityClass entityClass) {
-        return new MockDevice(this, deviceKey, aps, trueAPs, entities, entityClass);
-    }
+	@Override
+	protected Device allocateDevice(Long deviceKey,
+			String dhcpClientName,
+			List<AttachmentPoint> aps,
+			List<AttachmentPoint> trueAPs,
+			Collection<Entity> entities,
+			IEntityClass entityClass) {
+		return new MockDevice(this, deviceKey, aps, trueAPs, entities, entityClass);
+	}
 
-    @Override
-    protected Device allocateDevice(Device device,
-                                    Entity entity,
-                                    int insertionpoint) {
-        return new MockDevice(device, entity, insertionpoint);
-    }
+	@Override
+	protected Device allocateDevice(Device device,
+			Entity entity,
+			int insertionpoint) {
+		return new MockDevice(device, entity, insertionpoint);
+	}
 
-    @Override
-    public void init(FloodlightModuleContext fmc) throws FloodlightModuleException {
-        super.init(fmc);
-        setSyncServiceIfNotSet(new MockSyncService());
-    }
+	@Override
+	public void init(FloodlightModuleContext fmc) throws FloodlightModuleException {
+		super.init(fmc);
+		setSyncServiceIfNotSet(new MockSyncService());
+	}
 }
diff --git a/src/test/java/net/floodlightcontroller/devicemanager/test/MockEntityClassifier.java b/src/test/java/net/floodlightcontroller/devicemanager/test/MockEntityClassifier.java
index 7a35049a94f79d4a5b0701b28cd682fc95bc7299..2d92357f453f21c2bf8cc5a8543168a65dd695e0 100644
--- a/src/test/java/net/floodlightcontroller/devicemanager/test/MockEntityClassifier.java
+++ b/src/test/java/net/floodlightcontroller/devicemanager/test/MockEntityClassifier.java
@@ -49,7 +49,7 @@ public class MockEntityClassifier extends DefaultEntityClassifier {
     
     @Override
     public IEntityClass classifyEntity(Entity entity) {
-        if (entity.getSwitchDPID() >= 10L) {
+        if (entity.getSwitchDPID().getLong() >= 10L) {
             return testEC;
         }
         return DefaultEntityClassifier.entityClass;
diff --git a/src/test/java/net/floodlightcontroller/devicemanager/test/MockEntityClassifierMac.java b/src/test/java/net/floodlightcontroller/devicemanager/test/MockEntityClassifierMac.java
index 521b9b7929833dcca5114a6062e7f0475be4738a..a953d5c14dfc0b69c9a899810e37c453d087d636 100644
--- a/src/test/java/net/floodlightcontroller/devicemanager/test/MockEntityClassifierMac.java
+++ b/src/test/java/net/floodlightcontroller/devicemanager/test/MockEntityClassifierMac.java
@@ -59,11 +59,11 @@ public class MockEntityClassifierMac extends DefaultEntityClassifier {
         if (entity.getSwitchDPID() == null) {
             throw new IllegalArgumentException("Not all key fields specified."
                     + " Required fields: " + getKeyFields());
-        } else if (entity.getSwitchDPID() == 1L) {
+        } else if (entity.getSwitchDPID().getLong() == 1L) {
             return testECMac1;
-        } else if (entity.getSwitchDPID() == 2L) {
+        } else if (entity.getSwitchDPID().getLong() == 2L) {
             return testECMac2;
-        } else if (entity.getSwitchDPID() == -1L) {
+        } else if (entity.getSwitchDPID().getLong() == -1L) {
             return null;
         }
         return DefaultEntityClassifier.entityClass;
diff --git a/src/test/java/net/floodlightcontroller/firewall/FirewallTest.java b/src/test/java/net/floodlightcontroller/firewall/FirewallTest.java
index ea9aafb93968fc9af5dc248fe38461fb410cdb32..6e5f4a57bb819012687c80a6ea19fcb8b6d7345d 100644
--- a/src/test/java/net/floodlightcontroller/firewall/FirewallTest.java
+++ b/src/test/java/net/floodlightcontroller/firewall/FirewallTest.java
@@ -47,18 +47,18 @@ import net.floodlightcontroller.test.FloodlightTestCase;
 import org.easymock.EasyMock;
 import org.junit.Before;
 import org.junit.Test;
+import org.projectfloodlight.openflow.protocol.OFFactories;
 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.DatapathId;
 import org.projectfloodlight.openflow.types.EthType;
-import org.projectfloodlight.openflow.types.IPv4Address;
 import org.projectfloodlight.openflow.types.IPv4AddressWithMask;
 import org.projectfloodlight.openflow.types.IpProtocol;
 import org.projectfloodlight.openflow.types.MacAddress;
+import org.projectfloodlight.openflow.types.OFBufferId;
 import org.projectfloodlight.openflow.types.OFPort;
 import org.projectfloodlight.openflow.types.TransportPort;
-import org.projectfloodlight.openflow.util.HexString;
 
 /**
  * Unit test for stateless firewall implemented as a Google Summer of Code project.
@@ -84,6 +84,7 @@ public class FirewallTest extends FloodlightTestCase {
         super.setUp();
         cntx = new FloodlightContext();
         mockFloodlightProvider = getMockFloodlightProvider();
+        mockSwitchManager = getMockSwitchService();
         firewall = new Firewall();
         IStorageSourceService storageService = new MemoryStorageSource();
         RestApiServer restApi = new RestApiServer();
@@ -95,9 +96,9 @@ public class FirewallTest extends FloodlightTestCase {
         expect(sw.getId().toString()).andReturn(TestSwitch1DPID).anyTimes();
         replay(sw);
         // Load the switch map
-        Map<Long, IOFSwitch> switches = new HashMap<Long, IOFSwitch>();
+        Map<DatapathId, IOFSwitch> switches = new HashMap<DatapathId, IOFSwitch>();
         switches.put(dpid, sw);
-        mockFloodlightProvider.setSwitches(switches);
+        mockSwitchManager.setSwitches(switches);
 
         FloodlightModuleContext fmc = new FloodlightModuleContext();
         fmc.addService(IFloodlightProviderService.class,
@@ -216,13 +217,12 @@ public class FirewallTest extends FloodlightTestCase {
     protected void setPacketIn(IPacket packet) {
         byte[] serializedPacket = packet.serialize();
         // Build the PacketIn
-        /*this.packetIn = ((OFPacketIn) mockFloodlightProvider.getOFMessageFactory().getMessage(OFType.PACKET_IN))
-                .setBufferId(-1)
-                .setInPort((short) 1)
-                .setPacketData(serializedPacket)
+        this.packetIn = OFFactories.getFactory(OFVersion.OF_13).buildPacketIn()
+                .setBufferId(OFBufferId.NO_BUFFER)
+                .setInPort(OFPort.of(1))
+                .setData(serializedPacket)
                 .setReason(OFPacketInReason.NO_MATCH)
-                .setTotalLength((short) serializedPacket.length);
-		*/
+                .build();
         // Add the packet to the context store
         IFloodlightProviderService.bcStore.
         put(cntx,
diff --git a/src/test/java/net/floodlightcontroller/flowcache/FlowReconcileMgrTest.java b/src/test/java/net/floodlightcontroller/flowcache/FlowReconcileMgrTest.java
index 62ccecdf69fefab4db37686abb7c273d4420075f..cda16ee4dd8d6c6c54cfc574d93a3b8676014567 100644
--- a/src/test/java/net/floodlightcontroller/flowcache/FlowReconcileMgrTest.java
+++ b/src/test/java/net/floodlightcontroller/flowcache/FlowReconcileMgrTest.java
@@ -17,6 +17,7 @@
 package net.floodlightcontroller.flowcache;
 
 import static org.easymock.EasyMock.*;
+import static org.junit.Assert.*;
 
 import java.util.ArrayList;
 import java.util.Date;
@@ -25,29 +26,26 @@ import java.util.ListIterator;
 import net.floodlightcontroller.core.IListener.Command;
 import net.floodlightcontroller.core.module.FloodlightModuleContext;
 import net.floodlightcontroller.core.test.MockThreadPoolService;
-import net.floodlightcontroller.counter.ICounterStoreService;
-import net.floodlightcontroller.counter.SimpleCounter;
-import net.floodlightcontroller.counter.CounterValue.CounterType;
 import net.floodlightcontroller.flowcache.IFlowReconcileListener;
 import net.floodlightcontroller.flowcache.OFMatchReconcile;
 import net.floodlightcontroller.flowcache.PriorityPendingQueue.EventPriority;
 import net.floodlightcontroller.test.FloodlightTestCase;
 import net.floodlightcontroller.threadpool.IThreadPoolService;
+
 import org.easymock.EasyMock;
 import org.easymock.IAnswer;
 import org.junit.Before;
 import org.junit.Test;
-import org.openflow.protocol.OFStatisticsRequest;
-import org.openflow.protocol.OFType;
+import org.projectfloodlight.openflow.protocol.OFStatsRequest;
+import org.projectfloodlight.openflow.protocol.OFType;
 
 public class FlowReconcileMgrTest extends FloodlightTestCase {
 
     protected FlowReconcileManager flowReconcileMgr;
     protected MockThreadPoolService threadPool;
-    protected ICounterStoreService counterStore;
     protected FloodlightModuleContext fmc;
     
-    OFStatisticsRequest ofStatsRequest;
+    OFStatsRequest ofStatsRequest;
 
     protected int NUM_FLOWS_PER_THREAD = 100;
     protected int NUM_THREADS = 20;
@@ -59,9 +57,7 @@ public class FlowReconcileMgrTest extends FloodlightTestCase {
         fmc = new FloodlightModuleContext();
         flowReconcileMgr = new FlowReconcileManager();
         threadPool = new MockThreadPoolService();
-        counterStore = createMock(ICounterStoreService.class);
         
-        fmc.addService(ICounterStoreService.class, counterStore);
         fmc.addService(IThreadPoolService.class, threadPool);
         
         threadPool.init(fmc);
@@ -115,16 +111,6 @@ public class FlowReconcileMgrTest extends FloodlightTestCase {
                   andThrow(new RuntimeException("This is NOT an error! " +
                             "We are testing exception catching."));
         
-        SimpleCounter cnt = (SimpleCounter)SimpleCounter.createCounter(
-                            new Date(),
-                            CounterType.LONG);
-        cnt.increment();
-        expect(counterStore.getCounter(
-                flowReconcileMgr.controllerPktInCounterName))
-                .andReturn(cnt)
-                .anyTimes();
-        
-        replay(r1, r2, r3, counterStore);
         flowReconcileMgr.clearFlowReconcileListeners();
         flowReconcileMgr.addFlowReconcileListener(r1);
         flowReconcileMgr.addFlowReconcileListener(r2);
@@ -256,8 +242,7 @@ public class FlowReconcileMgrTest extends FloodlightTestCase {
     
     @Test
     public void testGetPktInRate() {
-        internalTestGetPktInRate(CounterType.LONG);
-        internalTestGetPktInRate(CounterType.DOUBLE);
+
     }
     
     protected void internalTestGetPktInRate(CounterType type) {
diff --git a/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java b/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java
index 1209cb1842c2d2373d20dcc510543e6149df7be4..9dec8e67163830432e2da62cc3980b22a8699a2c 100644
--- a/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java
+++ b/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java
@@ -18,6 +18,7 @@
 package net.floodlightcontroller.forwarding;
 
 import static org.easymock.EasyMock.*;
+import static org.junit.Assert.*;
 
 import java.util.ArrayList;
 import java.util.Date;
@@ -32,8 +33,6 @@ import net.floodlightcontroller.core.module.FloodlightModuleContext;
 import net.floodlightcontroller.core.test.MockThreadPoolService;
 import net.floodlightcontroller.devicemanager.internal.DefaultEntityClassifier;
 import net.floodlightcontroller.devicemanager.test.MockDeviceManager;
-import net.floodlightcontroller.counter.CounterStore;
-import net.floodlightcontroller.counter.ICounterStoreService;
 import net.floodlightcontroller.devicemanager.IDevice;
 import net.floodlightcontroller.devicemanager.IDeviceService;
 import net.floodlightcontroller.devicemanager.IEntityClassifierService;
@@ -57,18 +56,24 @@ import org.easymock.Capture;
 import org.easymock.CaptureType;
 import org.easymock.EasyMock;
 import org.junit.Test;
-import org.openflow.protocol.OFFeaturesReply;
-import org.openflow.protocol.OFFlowMod;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFPacketOut;
-import org.openflow.protocol.OFPort;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.OFPacketIn.OFPacketInReason;
-import org.openflow.protocol.action.OFAction;
-import org.openflow.protocol.action.OFActionOutput;
-import org.openflow.util.HexString;
+import org.projectfloodlight.openflow.protocol.OFFeaturesReply;
+import org.projectfloodlight.openflow.protocol.OFFlowMod;
+import org.projectfloodlight.openflow.protocol.match.Match;
+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.OFVersion;
+import org.projectfloodlight.openflow.types.DatapathId;
+import org.projectfloodlight.openflow.types.IPv4Address;
+import org.projectfloodlight.openflow.types.MacAddress;
+import org.projectfloodlight.openflow.types.OFBufferId;
+import org.projectfloodlight.openflow.types.OFPort;
+import org.projectfloodlight.openflow.types.U64;
+import org.projectfloodlight.openflow.protocol.OFPacketInReason;
+import org.projectfloodlight.openflow.protocol.action.OFAction;
+import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
 import org.sdnplatform.sync.ISyncService;
 import org.sdnplatform.sync.test.MockSyncService;
 
@@ -91,6 +96,8 @@ public class ForwardingTest extends FloodlightTestCase {
     protected int expected_wildcards;
     protected Date currentDate;
     private MockSyncService mockSyncService;
+    private OFFactory factory = OFFactories.getFactory(OFVersion.OF_13);
+    
 
     @Override
     public void setUp() throws Exception {
@@ -135,7 +142,6 @@ public class ForwardingTest extends FloodlightTestCase {
         fmc.addService(IThreadPoolService.class, threadPool);
         fmc.addService(ITopologyService.class, topology);
         fmc.addService(IRoutingService.class, routingEngine);
-        fmc.addService(ICounterStoreService.class, new CounterStore());
         fmc.addService(IDeviceService.class, deviceManager);
         fmc.addService(IFlowReconcileService.class, flowReconcileMgr);
         fmc.addService(IEntityClassifierService.class, entityClassifier);
@@ -159,42 +165,29 @@ public class ForwardingTest extends FloodlightTestCase {
         entityClassifier.startUp(fmc);
         verify(topology);
 
-        swFeatures = new OFFeaturesReply();
-        swFeatures.setBuffers(1000);
+        swFeatures = factory.buildFeaturesReply().setNBuffers(1000).build();
         // Mock switches
         sw1 = EasyMock.createMock(IOFSwitch.class);
-        expect(sw1.getId()).andReturn(1L).anyTimes();
-        expect(sw1.getBuffers()).andReturn(swFeatures.getBuffers()).anyTimes();
-        expect(sw1.getStringId())
-                .andReturn(HexString.toHexString(1L)).anyTimes();
+        expect(sw1.getId()).andReturn(DatapathId.of(1L)).anyTimes();
+        expect(sw1.getBuffers()).andReturn(swFeatures.getNBuffers()).anyTimes();
+        expect(sw1.getId().toString())
+                .andReturn(DatapathId.of(1L).toString()).anyTimes();
 
         sw2 = EasyMock.createMock(IOFSwitch.class);
-        expect(sw2.getId()).andReturn(2L).anyTimes();
-        expect(sw2.getBuffers()).andReturn(swFeatures.getBuffers()).anyTimes();
-        expect(sw2.getStringId())
-                .andReturn(HexString.toHexString(2L)).anyTimes();
-
-        //fastWilcards mocked as this constant
-        int fastWildcards =
-                OFMatch.OFPFW_IN_PORT |
-                OFMatch.OFPFW_NW_PROTO |
-                OFMatch.OFPFW_TP_SRC |
-                OFMatch.OFPFW_TP_DST |
-                OFMatch.OFPFW_NW_SRC_ALL |
-                OFMatch.OFPFW_NW_DST_ALL |
-                OFMatch.OFPFW_NW_TOS;
-
-        expect(sw1.getAttribute(IOFSwitch.PROP_FASTWILDCARDS)).andReturn(fastWildcards).anyTimes();
+        expect(sw2.getId()).andReturn(DatapathId.of(2L)).anyTimes();
+        expect(sw2.getBuffers()).andReturn(swFeatures.getNBuffers()).anyTimes();
+        expect(sw2.getId().toString())
+                .andReturn(DatapathId.of(2L).toString()).anyTimes();
+
         expect(sw1.hasAttribute(IOFSwitch.PROP_SUPPORTS_OFPP_TABLE)).andReturn(true).anyTimes();
 
-        expect(sw2.getAttribute(IOFSwitch.PROP_FASTWILDCARDS)).andReturn(fastWildcards).anyTimes();
         expect(sw2.hasAttribute(IOFSwitch.PROP_SUPPORTS_OFPP_TABLE)).andReturn(true).anyTimes();
 
         // Load the switch map
-        Map<Long, IOFSwitch> switches = new HashMap<Long, IOFSwitch>();
-        switches.put(1L, sw1);
-        switches.put(2L, sw2);
-        mockFloodlightProvider.setSwitches(switches);
+        Map<DatapathId, IOFSwitch> switches = new HashMap<DatapathId, IOFSwitch>();
+        switches.put(DatapathId.of(1L), sw1);
+        switches.put(DatapathId.of(2L), sw2);
+        getMockSwitchService().setSwitches(switches);
 
         // Build test packet
         testPacket = new Ethernet()
@@ -217,54 +210,33 @@ public class ForwardingTest extends FloodlightTestCase {
 
         // Mock Packet-in
         testPacketSerialized = testPacket.serialize();
-        packetIn =
-                ((OFPacketIn) mockFloodlightProvider.getOFMessageFactory().
-                        getMessage(OFType.PACKET_IN))
-                        .setBufferId(-1)
-                        .setInPort((short) 1)
-                        .setPacketData(testPacketSerialized)
+        packetIn = factory.buildPacketIn()
+                        .setBufferId(OFBufferId.NO_BUFFER)
+                        .setInPort(OFPort.of(1))
+                        .setData(testPacketSerialized)
                         .setReason(OFPacketInReason.NO_MATCH)
-                        .setTotalLength((short) testPacketSerialized.length);
+                        .build();
 
         // Mock Packet-out
-        packetOut =
-                (OFPacketOut) mockFloodlightProvider.getOFMessageFactory().
-                    getMessage(OFType.PACKET_OUT);
-        packetOut.setBufferId(this.packetIn.getBufferId())
-            .setInPort(this.packetIn.getInPort());
         List<OFAction> poactions = new ArrayList<OFAction>();
-        poactions.add(new OFActionOutput((short) 3, (short) 0xffff));
-        packetOut.setActions(poactions)
-            .setActionsLength((short) OFActionOutput.MINIMUM_LENGTH)
-            .setPacketData(testPacketSerialized)
-            .setLengthU(OFPacketOut.MINIMUM_LENGTH+
-                        packetOut.getActionsLength()+
-                        testPacketSerialized.length);
+        poactions.add(factory.actions().output(OFPort.of(3), Integer.MAX_VALUE));
+        packetOut = factory.buildPacketOut()
+        		.setBufferId(this.packetIn.getBufferId())
+        		.setInPort(this.packetIn.getInPort())
+        		.setActions(poactions)
+        		.setData(testPacketSerialized)
+        		.build();
 
         // Mock Packet-out with OFPP_FLOOD action
-        packetOutFlooded =
-                (OFPacketOut) mockFloodlightProvider.getOFMessageFactory().
-                    getMessage(OFType.PACKET_OUT);
-        packetOutFlooded.setBufferId(this.packetIn.getBufferId())
-            .setInPort(this.packetIn.getInPort());
         poactions = new ArrayList<OFAction>();
-        poactions.add(new OFActionOutput(OFPort.OFPP_FLOOD.getValue(),
-                                         (short) 0xffff));
-        packetOutFlooded.setActions(poactions)
-            .setActionsLength((short) OFActionOutput.MINIMUM_LENGTH)
-            .setPacketData(testPacketSerialized)
-            .setLengthU(OFPacketOut.MINIMUM_LENGTH+
-                        packetOutFlooded.getActionsLength()+
-                        testPacketSerialized.length);
-
-        expected_wildcards = fastWildcards;
-        expected_wildcards &= ~OFMatch.OFPFW_IN_PORT &
-                              ~OFMatch.OFPFW_DL_VLAN &
-                              ~OFMatch.OFPFW_DL_SRC &
-                              ~OFMatch.OFPFW_DL_DST;
-        expected_wildcards &= ~OFMatch.OFPFW_NW_SRC_MASK &
-                              ~OFMatch.OFPFW_NW_DST_MASK;
-
+        poactions.add(factory.actions().output(OFPort.FLOOD, Integer.MAX_VALUE));
+        packetOutFlooded = factory.buildPacketOut()
+        		.setBufferId(this.packetIn.getBufferId())
+        		.setInPort(this.packetIn.getInPort())
+        		.setActions(poactions)
+        		.setData(testPacketSerialized)
+        		.build();
+            
         IFloodlightProviderService.bcStore.
             put(cntx,
                 IFloodlightProviderService.CONTEXT_PI_PAYLOAD,
@@ -274,39 +246,39 @@ public class ForwardingTest extends FloodlightTestCase {
     enum DestDeviceToLearn { NONE, DEVICE1 ,DEVICE2 };
     public void learnDevices(DestDeviceToLearn destDeviceToLearn) {
         // Build src and dest devices
-        byte[] dataLayerSource = ((Ethernet)testPacket).getSourceMACAddress();
-        byte[] dataLayerDest =
+        MacAddress dataLayerSource = ((Ethernet)testPacket).getSourceMACAddress();
+        MacAddress dataLayerDest =
                 ((Ethernet)testPacket).getDestinationMACAddress();
-        int networkSource =
+        IPv4Address networkSource =
                 ((IPv4)((Ethernet)testPacket).getPayload()).
                     getSourceAddress();
-        int networkDest =
+        IPv4Address networkDest =
                 ((IPv4)((Ethernet)testPacket).getPayload()).
                     getDestinationAddress();
 
         reset(topology);
-        expect(topology.isAttachmentPointPort(1L, (short)1))
+        expect(topology.isAttachmentPointPort(DatapathId.of(1L), OFPort.of(1)))
                                               .andReturn(true)
                                               .anyTimes();
-        expect(topology.isAttachmentPointPort(2L, (short)3))
+        expect(topology.isAttachmentPointPort(DatapathId.of(2L), OFPort.of(3)))
                                               .andReturn(true)
                                               .anyTimes();
-        expect(topology.isAttachmentPointPort(1L, (short)3))
+        expect(topology.isAttachmentPointPort(DatapathId.of(1L), OFPort.of(3)))
                                               .andReturn(true)
                                               .anyTimes();
         replay(topology);
 
         srcDevice =
-                deviceManager.learnEntity(Ethernet.toLong(dataLayerSource),
-                                          null, networkSource,
+                deviceManager.learnEntity(dataLayerSource.getLong(),
+                                          null, networkSource.getInt(),
                                           1L, 1);
         IDeviceService.fcStore. put(cntx,
                                     IDeviceService.CONTEXT_SRC_DEVICE,
                                     srcDevice);
         if (destDeviceToLearn == DestDeviceToLearn.DEVICE1) {
             dstDevice1 =
-                    deviceManager.learnEntity(Ethernet.toLong(dataLayerDest),
-                                              null, networkDest,
+                    deviceManager.learnEntity(dataLayerDest.getLong(),
+                                              null, networkDest.getInt(),
                                               2L, 3);
             IDeviceService.fcStore.put(cntx,
                                        IDeviceService.CONTEXT_DST_DEVICE,
@@ -314,8 +286,8 @@ public class ForwardingTest extends FloodlightTestCase {
         }
         if (destDeviceToLearn == DestDeviceToLearn.DEVICE2) {
             dstDevice2 =
-                    deviceManager.learnEntity(Ethernet.toLong(dataLayerDest),
-                                              null, networkDest,
+                    deviceManager.learnEntity(dataLayerDest.getLong(),
+                                              null, networkDest.getInt(),
                                               1L, 3);
             IDeviceService.fcStore.put(cntx,
                                        IDeviceService.CONTEXT_DST_DEVICE,
@@ -330,52 +302,42 @@ public class ForwardingTest extends FloodlightTestCase {
 
         Capture<OFMessage> wc1 = new Capture<OFMessage>(CaptureType.ALL);
         Capture<OFMessage> wc2 = new Capture<OFMessage>(CaptureType.ALL);
-        Capture<FloodlightContext> bc1 =
-                new Capture<FloodlightContext>(CaptureType.ALL);
-        Capture<FloodlightContext> bc2 =
-                new Capture<FloodlightContext>(CaptureType.ALL);
-
 
-        Route route = new Route(1L, 2L);
+        Route route = new Route(DatapathId.of(1L), DatapathId.of(2L));
         List<NodePortTuple> nptList = new ArrayList<NodePortTuple>();
-        nptList.add(new NodePortTuple(1L, (short)1));
-        nptList.add(new NodePortTuple(1L, (short)3));
-        nptList.add(new NodePortTuple(2L, (short)1));
-        nptList.add(new NodePortTuple(2L, (short)3));
+        nptList.add(new NodePortTuple(DatapathId.of(1L), OFPort.of(1)));
+        nptList.add(new NodePortTuple(DatapathId.of(1L), OFPort.of(3)));
+        nptList.add(new NodePortTuple(DatapathId.of(2L), OFPort.of(1)));
+        nptList.add(new NodePortTuple(DatapathId.of(2L), OFPort.of(3)));
         route.setPath(nptList);
-        expect(routingEngine.getRoute(1L, (short)1, 2L, (short)3, 0)).andReturn(route).atLeastOnce();
+        expect(routingEngine.getRoute(DatapathId.of(1L), OFPort.of(1), DatapathId.of(2L), OFPort.of(3), U64.ZERO)).andReturn(route).atLeastOnce();
 
         // Expected Flow-mods
-        OFMatch match = new OFMatch();
-        match.loadFromPacket(testPacketSerialized, (short) 1);
-        OFActionOutput action = new OFActionOutput((short)3, (short)0xffff);
+        Match match = ((OFPacketIn)testPacket).getMatch();
+        OFActionOutput action = factory.actions().output(OFPort.of(3), Integer.MAX_VALUE);
         List<OFAction> actions = new ArrayList<OFAction>();
         actions.add(action);
 
-        OFFlowMod fm1 =
-                (OFFlowMod) mockFloodlightProvider.getOFMessageFactory().
-                    getMessage(OFType.FLOW_MOD);
-        fm1.setIdleTimeout((short)5)
-            .setMatch(match.clone()
-                    .setWildcards(expected_wildcards))
-            .setActions(actions)
-            .setBufferId(OFPacketOut.BUFFER_ID_NONE)
-            .setCookie(2L << 52)
-            .setLengthU(OFFlowMod.MINIMUM_LENGTH+OFActionOutput.MINIMUM_LENGTH);
-        OFFlowMod fm2 = fm1.clone();
-        ((OFActionOutput)fm2.getActions().get(0)).setPort((short) 3);
+        OFFlowMod fm1 = factory.buildFlowAdd()
+        		.setIdleTimeout((short)5)
+        		.setMatch(match)
+        		.setActions(actions)
+        		.setBufferId(OFBufferId.NO_BUFFER)
+        		.setCookie(U64.of(2L << 52))
+        		.build();
+        OFFlowMod fm2 = fm1.createBuilder().build();
 
-        sw1.writeThrottled(capture(wc1), capture(bc1));
+        sw1.write(capture(wc1));
         expectLastCall().anyTimes();
-        sw2.writeThrottled(capture(wc2), capture(bc2));
+        sw2.write(capture(wc2));
         expectLastCall().anyTimes();
 
         reset(topology);
-        expect(topology.getL2DomainId(1L)).andReturn(1L).anyTimes();
-        expect(topology.getL2DomainId(2L)).andReturn(1L).anyTimes();
-        expect(topology.isAttachmentPointPort(1L,  (short)1)).andReturn(true).anyTimes();
-        expect(topology.isAttachmentPointPort(2L,  (short)3)).andReturn(true).anyTimes();
-        expect(topology.isIncomingBroadcastAllowed(anyLong(), anyShort())).andReturn(true).anyTimes();
+        expect(topology.getL2DomainId(DatapathId.of(1L))).andReturn(DatapathId.of(1L)).anyTimes();
+        expect(topology.getL2DomainId(DatapathId.of(2L))).andReturn(DatapathId.of(1L)).anyTimes();
+        expect(topology.isAttachmentPointPort(DatapathId.of(1L),  OFPort.of(1))).andReturn(true).anyTimes();
+        expect(topology.isAttachmentPointPort(DatapathId.of(2L),  OFPort.of(3))).andReturn(true).anyTimes();
+        expect(topology.isIncomingBroadcastAllowed(DatapathId.of(anyLong()), OFPort.of(anyShort()))).andReturn(true).anyTimes();
 
         // Reset mocks, trigger the packet in, and validate results
         replay(sw1, sw2, routingEngine, topology);
@@ -403,39 +365,34 @@ public class ForwardingTest extends FloodlightTestCase {
     public void testForwardSingleSwitchPath() throws Exception {
         learnDevices(DestDeviceToLearn.DEVICE2);
 
-        Route route = new  Route(1L, 1L);
-        route.getPath().add(new NodePortTuple(1L, (short)1));
-        route.getPath().add(new NodePortTuple(1L, (short)3));
-        expect(routingEngine.getRoute(1L, (short)1, 1L, (short)3, 0)).andReturn(route).atLeastOnce();
+        Route route = new  Route(DatapathId.of(1L), DatapathId.of(1L));
+        route.getPath().add(new NodePortTuple(DatapathId.of(1L), OFPort.of(1)));
+        route.getPath().add(new NodePortTuple(DatapathId.of(1L), OFPort.of(3)));
+        expect(routingEngine.getRoute(DatapathId.of(1L), OFPort.of(1), DatapathId.of(1L), OFPort.of(3), U64.ZERO)).andReturn(route).atLeastOnce();
 
         // Expected Flow-mods
-        OFMatch match = new OFMatch();
-        match.loadFromPacket(testPacketSerialized, (short) 1);
-        OFActionOutput action = new OFActionOutput((short)3, (short)0xffff);
+        Match match = ((OFPacketIn) testPacket).getMatch();
+        OFActionOutput action = factory.actions().output(OFPort.of(3), Integer.MAX_VALUE);
         List<OFAction> actions = new ArrayList<OFAction>();
         actions.add(action);
 
-        OFFlowMod fm1 =
-                (OFFlowMod) mockFloodlightProvider.getOFMessageFactory().
-                    getMessage(OFType.FLOW_MOD);
-        fm1.setIdleTimeout((short)5)
-            .setMatch(match.clone()
-                    .setWildcards(expected_wildcards))
+        OFFlowMod fm1 = factory.buildFlowAdd()
+        	.setIdleTimeout((short)5)
+            .setMatch(match)
             .setActions(actions)
-            .setBufferId(OFPacketOut.BUFFER_ID_NONE)
-            .setCookie(2L << 52)
-            .setLengthU(OFFlowMod.MINIMUM_LENGTH +
-                        OFActionOutput.MINIMUM_LENGTH);
+            .setBufferId(OFBufferId.NO_BUFFER)
+            .setCookie(U64.of(2L<< 52))
+            .build();
 
         // Record expected packet-outs/flow-mods
-        sw1.writeThrottled(fm1, cntx);
-        sw1.writeThrottled(packetOut, cntx);
+        sw1.write(fm1);
+        sw1.write(packetOut);
 
         reset(topology);
-        expect(topology.isIncomingBroadcastAllowed(anyLong(), anyShort())).andReturn(true).anyTimes();
-        expect(topology.getL2DomainId(1L)).andReturn(1L).anyTimes();
-        expect(topology.isAttachmentPointPort(1L,  (short)1)).andReturn(true).anyTimes();
-        expect(topology.isAttachmentPointPort(1L,  (short)3)).andReturn(true).anyTimes();
+        expect(topology.isIncomingBroadcastAllowed(DatapathId.of(anyLong()), OFPort.of(anyShort()))).andReturn(true).anyTimes();
+        expect(topology.getL2DomainId(DatapathId.of(1L))).andReturn(DatapathId.of(1L)).anyTimes();
+        expect(topology.isAttachmentPointPort(DatapathId.of(1L),  OFPort.of(1))).andReturn(true).anyTimes();
+        expect(topology.isAttachmentPointPort(DatapathId.of(1L),  OFPort.of(3))).andReturn(true).anyTimes();
 
         // Reset mocks, trigger the packet in, and validate results
         replay(sw1, sw2, routingEngine, topology);
@@ -448,49 +405,44 @@ public class ForwardingTest extends FloodlightTestCase {
         learnDevices(DestDeviceToLearn.DEVICE2);
 
         reset(topology);
-        expect(topology.isAttachmentPointPort(EasyMock.anyLong(), EasyMock.anyShort()))
+        expect(topology.isAttachmentPointPort(DatapathId.of(anyLong()), OFPort.of(anyShort())))
         .andReturn(true).anyTimes();
-        expect(topology.getL2DomainId(1L)).andReturn(1L).anyTimes();
+        expect(topology.getL2DomainId(DatapathId.of(1L))).andReturn(DatapathId.of(1L)).anyTimes();
         replay(topology);
 
 
-        Route route = new  Route(1L, 1L);
-        route.getPath().add(new NodePortTuple(1L, (short)1));
-        route.getPath().add(new NodePortTuple(1L, (short)3));
-        expect(routingEngine.getRoute(1L, (short)1, 1L, (short)3, 0)).andReturn(route).atLeastOnce();
+        Route route = new  Route(DatapathId.of(1L), DatapathId.of(1L));
+        route.getPath().add(new NodePortTuple(DatapathId.of(1L), OFPort.of(1)));
+        route.getPath().add(new NodePortTuple(DatapathId.of(1L), OFPort.of(3)));
+        expect(routingEngine.getRoute(DatapathId.of(1L), OFPort.of(1), DatapathId.of(1L), OFPort.of(3), U64.ZERO)).andReturn(route).atLeastOnce();
 
         // Expected Flow-mods
-        OFMatch match = new OFMatch();
-        match.loadFromPacket(testPacketSerialized, (short) 1);
-        OFActionOutput action = new OFActionOutput((short)3, (short)0xffff);
+        Match match = ((OFPacketIn) testPacket).getMatch();
+        OFActionOutput action = factory.actions().output(OFPort.of(3), Integer.MAX_VALUE);
         List<OFAction> actions = new ArrayList<OFAction>();
         actions.add(action);
 
-        OFFlowMod fm1 =
-                (OFFlowMod) mockFloodlightProvider.getOFMessageFactory().
-                    getMessage(OFType.FLOW_MOD);
-        fm1.setIdleTimeout((short)5)
-            .setMatch(match.clone()
-                    .setWildcards(expected_wildcards))
-            .setActions(actions)
-            .setBufferId(OFPacketOut.BUFFER_ID_NONE)
-            .setCookie(2L << 52)
-            .setLengthU(OFFlowMod.MINIMUM_LENGTH +
-                        OFActionOutput.MINIMUM_LENGTH);
+        OFFlowMod fm1 = factory.buildFlowAdd()
+        		.setIdleTimeout((short)5)
+        		.setMatch(match)
+        		.setActions(actions)
+        		.setBufferId(OFBufferId.NO_BUFFER)
+        		.setCookie(U64.of(2L << 52))
+        		.build();
 
         // Record expected packet-outs/flow-mods
         // We will inject the packet_in 3 times and expect 1 flow mod and
         // 3 packet outs due to flow mod dampening
-        sw1.writeThrottled(fm1, cntx);
+        sw1.write(fm1);
         expectLastCall().once();
-        sw1.writeThrottled(packetOut, cntx);
+        sw1.write(packetOut);
         expectLastCall().times(3);
 
         reset(topology);
-        expect(topology.isIncomingBroadcastAllowed(anyLong(), anyShort())).andReturn(true).anyTimes();
-        expect(topology.getL2DomainId(1L)).andReturn(1L).anyTimes();
-        expect(topology.isAttachmentPointPort(1L,  (short)1)).andReturn(true).anyTimes();
-        expect(topology.isAttachmentPointPort(1L,  (short)3)).andReturn(true).anyTimes();
+        expect(topology.isIncomingBroadcastAllowed(DatapathId.of(anyLong()), OFPort.of(anyShort()))).andReturn(true).anyTimes();
+        expect(topology.getL2DomainId(DatapathId.of(1L))).andReturn(DatapathId.of(1L)).anyTimes();
+        expect(topology.isAttachmentPointPort(DatapathId.of(1L),  OFPort.of(1))).andReturn(true).anyTimes();
+        expect(topology.isAttachmentPointPort(DatapathId.of(1L),  OFPort.of(3))).andReturn(true).anyTimes();
 
         // Reset mocks, trigger the packet in, and validate results
         replay(sw1, routingEngine, topology);
@@ -509,14 +461,14 @@ public class ForwardingTest extends FloodlightTestCase {
 
         // Reset mocks, trigger the packet in, and validate results
         reset(topology);
-        expect(topology.isIncomingBroadcastAllowed(1L, (short)1)).andReturn(true).anyTimes();
-        expect(topology.isAttachmentPointPort(EasyMock.anyLong(),
-                                              EasyMock.anyShort()))
+        expect(topology.isIncomingBroadcastAllowed(DatapathId.of(1L), OFPort.of(1))).andReturn(true).anyTimes();
+        expect(topology.isAttachmentPointPort(DatapathId.of(anyLong()),
+                                              OFPort.of(anyShort())))
                                               .andReturn(true)
                                               .anyTimes();
         expect(sw1.hasAttribute(IOFSwitch.PROP_SUPPORTS_OFPP_FLOOD))
                 .andReturn(true).anyTimes();
-        sw1.writeThrottled(packetOutFlooded, cntx);
+        sw1.write(packetOutFlooded);
         expectLastCall().once();
         replay(sw1, sw2, routingEngine, topology);
         forwarding.receive(sw1, this.packetIn, cntx);
diff --git a/src/test/java/net/floodlightcontroller/learningswitch/LearningSwitchTest.java b/src/test/java/net/floodlightcontroller/learningswitch/LearningSwitchTest.java
index d8da84ff89bea099c40af6792b7c0ad632a99514..f0bf807fd0da056edeb369f2f6fd211b6388fd84 100644
--- a/src/test/java/net/floodlightcontroller/learningswitch/LearningSwitchTest.java
+++ b/src/test/java/net/floodlightcontroller/learningswitch/LearningSwitchTest.java
@@ -21,15 +21,12 @@ import static org.easymock.EasyMock.createMock;
 import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.replay;
 import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.*;
 
-import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collection;
+
 import net.floodlightcontroller.core.IOFMessageListener;
 import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.module.FloodlightTestModuleLoader;
-import net.floodlightcontroller.core.module.IFloodlightModule;
-import net.floodlightcontroller.core.test.MockFloodlightProvider;
 import net.floodlightcontroller.packet.Data;
 import net.floodlightcontroller.packet.Ethernet;
 import net.floodlightcontroller.packet.IPacket;
@@ -39,17 +36,22 @@ import net.floodlightcontroller.test.FloodlightTestCase;
 
 import org.junit.Before;
 import org.junit.Test;
-import org.openflow.protocol.OFFlowMod;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFPacketIn.OFPacketInReason;
-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.OFActionOutput;
-import org.openflow.protocol.action.OFActionType;
+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.OFPacketInReason;
+import org.projectfloodlight.openflow.protocol.OFPacketOut;
+import org.projectfloodlight.openflow.protocol.OFVersion;
+import org.projectfloodlight.openflow.types.DatapathId;
+import org.projectfloodlight.openflow.types.MacAddress;
+import org.projectfloodlight.openflow.types.OFBufferId;
+import org.projectfloodlight.openflow.types.OFPort;
+import org.projectfloodlight.openflow.types.U64;
+import org.projectfloodlight.openflow.types.VlanVid;
+import org.projectfloodlight.openflow.protocol.OFType;
+import org.projectfloodlight.openflow.protocol.action.OFAction;
+import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
 
 /**
  *
@@ -64,21 +66,12 @@ public class LearningSwitchTest extends FloodlightTestCase {
     protected IPacket testPacketReply;
     protected byte[] testPacketReplySerialized;
     private LearningSwitch learningSwitch;
+    private OFFactory factory = OFFactories.getFactory(OFVersion.OF_13);
 
     @Override
     @Before
     public void setUp() throws Exception {
         super.setUp();
-        FloodlightTestModuleLoader fml = new FloodlightTestModuleLoader();
-        Collection<Class<? extends IFloodlightModule>> mods
-        	= new ArrayList<Class<? extends IFloodlightModule>>();
-        mods.add(LearningSwitch.class);
-
-        fml.setupModules(mods, null);
-        learningSwitch = (LearningSwitch) fml.getModuleByName(LearningSwitch.class);
-        mockFloodlightProvider =
-                (MockFloodlightProvider) fml.getModuleByName(MockFloodlightProvider.class);
-
         // Build our test packet
         this.testPacket = new Ethernet()
             .setDestinationMACAddress("00:11:22:33:44:55")
@@ -129,29 +122,27 @@ public class LearningSwitchTest extends FloodlightTestCase {
         this.testPacketReplySerialized = testPacketReply.serialize();
 
         // Build the PacketIn
-        this.packetIn = ((OFPacketIn) mockFloodlightProvider.getOFMessageFactory().getMessage(OFType.PACKET_IN))
-            .setBufferId(OFPacketOut.BUFFER_ID_NONE)
-            .setInPort((short) 1)
-            .setPacketData(this.testPacketSerialized)
+        this.packetIn = factory.buildPacketIn()
+            .setBufferId(OFBufferId.NO_BUFFER)
+            .setInPort(OFPort.of(1))
+            .setData(this.testPacketSerialized)
             .setReason(OFPacketInReason.NO_MATCH)
-            .setTotalLength((short) this.testPacketSerialized.length);
+            .build();
     }
 
     @Test
     public void testFlood() throws Exception {
         // build our expected flooded packetOut
-        OFPacketOut po = new OFPacketOut()
-            .setActions(Arrays.asList(new OFAction[] {new OFActionOutput().setPort(OFPort.OFPP_FLOOD.getValue())}))
-            .setActionsLength((short) OFActionOutput.MINIMUM_LENGTH)
-            .setBufferId(-1)
-            .setInPort((short)1)
-            .setPacketData(this.testPacketSerialized);
-        po.setLengthU(OFPacketOut.MINIMUM_LENGTH + po.getActionsLengthU()
-                + this.testPacketSerialized.length);
+        OFPacketOut po = factory.buildPacketOut()
+            .setActions(Arrays.asList((OFAction)factory.actions().output(OFPort.FLOOD, Integer.MAX_VALUE)))
+            .setBufferId(OFBufferId.NO_BUFFER)
+            .setInPort(OFPort.of(1))
+            .setData(this.testPacketSerialized)
+	        .build();
 
         // Mock up our expected behavior
         IOFSwitch mockSwitch = createMock(IOFSwitch.class);
-        expect(mockSwitch.getStringId()).andReturn("00:11:22:33:44:55:66:77").anyTimes();
+        expect(mockSwitch.getId().toString()).andReturn("00:11:22:33:44:55:66:77").anyTimes();
         mockSwitch.write(po, null);
 
         // Start recording the replay on the mocks
@@ -163,7 +154,7 @@ public class LearningSwitchTest extends FloodlightTestCase {
         listener.receive(mockSwitch, this.packetIn, parseAndAnnotate(this.packetIn));
 
         // Verify the replay matched our expectations
-        short result = learningSwitch.getFromPortMap(mockSwitch, Ethernet.toLong(Ethernet.toMACAddress("00:44:33:22:11:00")), (short) 42).shortValue();
+        OFPort result = learningSwitch.getFromPortMap(mockSwitch, MacAddress.of("00:44:33:22:11:00"), VlanVid.ofVlan(42));
         verify(mockSwitch);
 
         // Verify the MAC table inside the switch
@@ -173,62 +164,40 @@ public class LearningSwitchTest extends FloodlightTestCase {
     @Test
     public void testFlowMod() throws Exception {
         // tweak the test packet in since we need a bufferId
-        this.packetIn.setBufferId(50);
+        this.packetIn = packetIn.createBuilder().setBufferId(OFBufferId.of(50)).build();
 
         // build expected flow mods
-        OFMessage fm1 = ((OFFlowMod) mockFloodlightProvider.getOFMessageFactory().getMessage(OFType.FLOW_MOD))
-            .setActions(Arrays.asList(new OFAction[] {
-                    new OFActionOutput().setPort((short) 2).setMaxLength((short) -1)}))
-            .setBufferId(OFPacketOut.BUFFER_ID_NONE)
-            .setCommand(OFFlowMod.OFPFC_ADD)
+        OFMessage fm1 = factory.buildFlowAdd()
+            .setActions(Arrays.asList((OFAction)factory.actions().output(OFPort.FLOOD, -1)))
+            .setBufferId(OFBufferId.NO_BUFFER)
             .setIdleTimeout((short) 5)
-            .setMatch(new OFMatch()
-                .loadFromPacket(testPacketSerialized, (short) 1)
-                .setWildcards(OFMatch.OFPFW_NW_PROTO | OFMatch.OFPFW_TP_SRC | OFMatch.OFPFW_TP_DST
-                        | OFMatch.OFPFW_NW_TOS))
-            .setOutPort(OFPort.OFPP_NONE.getValue())
-            .setCookie(1L << 52)
+            .setMatch(((OFPacketIn) testPacket).getMatch())
+            .setOutPort(OFPort.ANY)
+            .setCookie(U64.of(1L << 52))
             .setPriority((short) 100)
-            .setFlags((short)(1 << 0))
-            .setLengthU(OFFlowMod.MINIMUM_LENGTH+OFActionOutput.MINIMUM_LENGTH);
-        OFMessage fm2 = ((OFFlowMod) mockFloodlightProvider.getOFMessageFactory().getMessage(OFType.FLOW_MOD))
-            .setActions(Arrays.asList(new OFAction[] {
-                    new OFActionOutput().setPort((short) 1).setMaxLength((short) -1)}))
-            .setBufferId(-1)
-            .setCommand(OFFlowMod.OFPFC_ADD)
+            .build();
+        OFMessage fm2 = factory.buildFlowAdd()
+            .setActions(Arrays.asList((OFAction)factory.actions().output(OFPort.of(1), -1)))
+            .setBufferId(OFBufferId.NO_BUFFER)
             .setIdleTimeout((short) 5)
-            .setMatch(new OFMatch()
-                .loadFromPacket(testPacketReplySerialized, (short) 2)
-                .setWildcards(OFMatch.OFPFW_NW_PROTO | OFMatch.OFPFW_TP_SRC | OFMatch.OFPFW_TP_DST
-                        | OFMatch.OFPFW_NW_TOS))
-            .setOutPort(OFPort.OFPP_NONE.getValue())
-            .setCookie(1L << 52)
+            .setMatch(((OFPacketIn) testPacketReply).getMatch())
+            .setOutPort(OFPort.ANY)
+            .setCookie(U64.of(1L << 52))
             .setPriority((short) 100)
-            .setFlags((short)(1 << 0))
-            .setLengthU(OFFlowMod.MINIMUM_LENGTH+OFActionOutput.MINIMUM_LENGTH);
-
-        OFActionOutput ofAcOut = new OFActionOutput();
-        ofAcOut.setMaxLength((short) -1);
-        ofAcOut.setPort((short)2);
-        ofAcOut.setLength((short) 8);
-        ofAcOut.setType(OFActionType.OUTPUT);
-
-        OFPacketOut packetOut = new OFPacketOut();
-        packetOut.setActions(Arrays.asList(new OFAction[] {ofAcOut}))
-        .setActionsLength((short) OFActionOutput.MINIMUM_LENGTH)
-        .setBufferId(50)
-        .setInPort((short)1)
-        .setPacketData(null)
-        .setLength((short) (OFPacketOut.MINIMUM_LENGTH + OFActionOutput.MINIMUM_LENGTH));
-        packetOut.setActionFactory(mockFloodlightProvider.getOFMessageFactory());
+            .build();
+
+        OFActionOutput ofAcOut = factory.actions().output(OFPort.of(2), -1);
+
+        OFPacketOut packetOut = factory.buildPacketOut()
+        .setActions(Arrays.asList((OFAction)ofAcOut))
+        .setBufferId(OFBufferId.of(50))
+        .setInPort(OFPort.of(1))
+        .build();
 
         // Mock up our expected behavior
         IOFSwitch mockSwitch = createMock(IOFSwitch.class);
-        expect(mockSwitch.getId()).andReturn(1L).anyTimes();
-        expect(mockSwitch.getAttribute(IOFSwitch.PROP_FASTWILDCARDS)).andReturn((OFMatch.OFPFW_IN_PORT | OFMatch.OFPFW_NW_PROTO
-                | OFMatch.OFPFW_TP_SRC | OFMatch.OFPFW_TP_DST | OFMatch.OFPFW_NW_SRC_ALL
-                | OFMatch.OFPFW_NW_DST_ALL | OFMatch.OFPFW_NW_TOS));
-        expect(mockSwitch.getBuffers()).andReturn(100).anyTimes();
+        expect(mockSwitch.getId()).andReturn(DatapathId.of(1L)).anyTimes();
+        expect(mockSwitch.getBuffers()).andReturn((long)100).anyTimes();
         mockSwitch.write(packetOut, null);
         mockSwitch.write(fm1, null);
         mockSwitch.write(fm2, null);
@@ -238,7 +207,7 @@ public class LearningSwitchTest extends FloodlightTestCase {
 
         // Populate the MAC table
         learningSwitch.addToPortMap(mockSwitch,
-                Ethernet.toLong(Ethernet.toMACAddress("00:11:22:33:44:55")), (short) 42, (short) 2);
+                MacAddress.of("00:11:22:33:44:55"), VlanVid.ofVlan(42), OFPort.of(2));
 
         // Get the listener and trigger the packet in
         IOFMessageListener listener = mockFloodlightProvider.getListeners().get(
@@ -246,7 +215,7 @@ public class LearningSwitchTest extends FloodlightTestCase {
         listener.receive(mockSwitch, this.packetIn, parseAndAnnotate(this.packetIn));
 
         // Verify the replay matched our expectations
-        short result = learningSwitch.getFromPortMap(mockSwitch, Ethernet.toLong(Ethernet.toMACAddress("00:44:33:22:11:00")), (short) 42).shortValue();
+        OFPort result = learningSwitch.getFromPortMap(mockSwitch, MacAddress.of("00:44:33:22:11:00"), VlanVid.ofVlan(42));
         verify(mockSwitch);
 
         // Verify the MAC table inside the switch
diff --git a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java
index 940bd076ed4e4cecf46dd502c8466bbe4647596e..b2ba0f446582e7a69d6c22cd012a194539d2cf96 100644
--- a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java
+++ b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java
@@ -24,9 +24,11 @@ import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.expectLastCall;
 import static org.easymock.EasyMock.replay;
 import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.*;
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -36,7 +38,6 @@ import net.floodlightcontroller.core.FloodlightContext;
 import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IListener.Command;
 import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.ImmutablePort;
 import net.floodlightcontroller.core.module.FloodlightModuleContext;
 import net.floodlightcontroller.core.test.MockThreadPoolService;
 import net.floodlightcontroller.linkdiscovery.ILinkDiscoveryListener;
@@ -64,13 +65,16 @@ import org.easymock.CaptureType;
 import org.easymock.EasyMock;
 import org.junit.Before;
 import org.junit.Test;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFPacketIn.OFPacketInReason;
-import org.openflow.protocol.OFPhysicalPort;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.factory.BasicFactory;
-import org.openflow.util.HexString;
+import org.projectfloodlight.openflow.protocol.OFFactories;
+import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFPacketIn;
+import org.projectfloodlight.openflow.protocol.OFPacketInReason;
+import org.projectfloodlight.openflow.protocol.OFPortDesc;
+import org.projectfloodlight.openflow.protocol.OFVersion;
+import org.projectfloodlight.openflow.types.DatapathId;
+import org.projectfloodlight.openflow.types.MacAddress;
+import org.projectfloodlight.openflow.types.OFBufferId;
+import org.projectfloodlight.openflow.types.OFPort;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -111,7 +115,7 @@ public class LinkDiscoveryManagerTest extends FloodlightTestCase {
 
     private IOFSwitch createMockSwitch(Long id) {
         IOFSwitch mockSwitch = createNiceMock(IOFSwitch.class);
-        expect(mockSwitch.getId()).andReturn(id).anyTimes();
+        expect(mockSwitch.getId()).andReturn(DatapathId.of(id)).anyTimes();
         return mockSwitch;
     }
 
@@ -143,10 +147,10 @@ public class LinkDiscoveryManagerTest extends FloodlightTestCase {
 
         IOFSwitch sw1 = createMockSwitch(1L);
         IOFSwitch sw2 = createMockSwitch(2L);
-        Map<Long, IOFSwitch> switches = new HashMap<Long, IOFSwitch>();
-        switches.put(1L, sw1);
-        switches.put(2L, sw2);
-        getMockFloodlightProvider().setSwitches(switches);
+        Map<DatapathId, IOFSwitch> switches = new HashMap<DatapathId, IOFSwitch>();
+        switches.put(DatapathId.of(1L), sw1);
+        switches.put(DatapathId.of(2L), sw2);
+        getMockSwitchService().setSwitches(switches);
         replay(sw1, sw2);
     }
 
@@ -154,14 +158,14 @@ public class LinkDiscoveryManagerTest extends FloodlightTestCase {
     public void testAddOrUpdateLink() throws Exception {
         LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
 
-        Link lt = new Link(1L, 2, 2L, 1);
-        LinkInfo info = new LinkInfo(System.currentTimeMillis(),
-                                     System.currentTimeMillis(), null);
+        Link lt = new Link(DatapathId.of(1L), OFPort.of(2), DatapathId.of(2L), OFPort.of(1));
+        LinkInfo info = new LinkInfo(new Date(),
+                                     new Date(), null);
         linkDiscovery.addOrUpdateLink(lt, info);
 
 
-        NodePortTuple srcNpt = new NodePortTuple(1L, 2);
-        NodePortTuple dstNpt = new NodePortTuple(2L, 1);
+        NodePortTuple srcNpt = new NodePortTuple(DatapathId.of(1L), OFPort.of(2));
+        NodePortTuple dstNpt = new NodePortTuple(DatapathId.of(2L), OFPort.of(1));
 
         // check invariants hold
         assertNotNull(linkDiscovery.switchLinks.get(lt.getSrc()));
@@ -177,9 +181,9 @@ public class LinkDiscoveryManagerTest extends FloodlightTestCase {
     public void testDeleteLink() throws Exception {
         LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
 
-        Link lt = new Link(1L, 2, 2L, 1);
-        LinkInfo info = new LinkInfo(System.currentTimeMillis(),
-                                     System.currentTimeMillis(), null);
+        Link lt = new Link(DatapathId.of(1L), OFPort.of(2), DatapathId.of(2L), OFPort.of(1));
+        LinkInfo info = new LinkInfo(new Date(),
+        		new Date(), null);
         linkDiscovery.addOrUpdateLink(lt, info);
         linkDiscovery.deleteLinks(Collections.singletonList(lt), "Test");
 
@@ -195,12 +199,12 @@ public class LinkDiscoveryManagerTest extends FloodlightTestCase {
     public void testAddOrUpdateLinkToSelf() throws Exception {
         LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
 
-        Link lt = new Link(1L, 2, 2L, 3);
-        NodePortTuple srcNpt = new NodePortTuple(1L, 2);
-        NodePortTuple dstNpt = new NodePortTuple(2L, 3);
+        Link lt = new Link(DatapathId.of(1L), OFPort.of(2), DatapathId.of(2L), OFPort.of(3));
+        NodePortTuple srcNpt = new NodePortTuple(DatapathId.of(1L), OFPort.of(2));
+        NodePortTuple dstNpt = new NodePortTuple(DatapathId.of(2L), OFPort.of(3));
 
-        LinkInfo info = new LinkInfo(System.currentTimeMillis(),
-                                     System.currentTimeMillis(), null);
+        LinkInfo info = new LinkInfo(new Date(),
+        		new Date(), null);
         linkDiscovery.addOrUpdateLink(lt, info);
 
         // check invariants hold
@@ -217,12 +221,12 @@ public class LinkDiscoveryManagerTest extends FloodlightTestCase {
     public void testDeleteLinkToSelf() throws Exception {
         LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
 
-        Link lt = new Link(1L, 2, 1L, 3);
-        NodePortTuple srcNpt = new NodePortTuple(1L, 2);
-        NodePortTuple dstNpt = new NodePortTuple(2L, 3);
+        Link lt = new Link(DatapathId.of(1L), OFPort.of(2), DatapathId.of(1L), OFPort.of(3));
+        NodePortTuple srcNpt = new NodePortTuple(DatapathId.of(1L), OFPort.of(2));
+        NodePortTuple dstNpt = new NodePortTuple(DatapathId.of(2L), OFPort.of(3));
 
-        LinkInfo info = new LinkInfo(System.currentTimeMillis(),
-                                     System.currentTimeMillis(), null);
+        LinkInfo info = new LinkInfo(new Date(),
+        		new Date(), null);
         linkDiscovery.addOrUpdateLink(lt, info);
         linkDiscovery.deleteLinks(Collections.singletonList(lt), "Test to self");
 
@@ -238,15 +242,15 @@ public class LinkDiscoveryManagerTest extends FloodlightTestCase {
     public void testRemovedSwitch() {
         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(), null);
+        Link lt = new Link(DatapathId.of(1L), OFPort.of(2), DatapathId.of(2L), OFPort.of(1));
+        NodePortTuple srcNpt = new NodePortTuple(DatapathId.of(1L), OFPort.of(2));
+        NodePortTuple dstNpt = new NodePortTuple(DatapathId.of(2L), OFPort.of(1));
+        LinkInfo info = new LinkInfo(new Date(),
+        		new Date(), null);
         linkDiscovery.addOrUpdateLink(lt, info);
 
-        IOFSwitch sw1 = getMockFloodlightProvider().getSwitch(1L);
-        IOFSwitch sw2 = getMockFloodlightProvider().getSwitch(2L);
+        IOFSwitch sw1 = getMockSwitchService().getSwitch(DatapathId.of(1L));
+        IOFSwitch sw2 = getMockSwitchService().getSwitch(DatapathId.of(2L));
         // Mock up our expected behavior
         linkDiscovery.switchRemoved(sw1.getId());
         verify(sw1, sw2);
@@ -264,9 +268,9 @@ public class LinkDiscoveryManagerTest extends FloodlightTestCase {
         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(), null);
+        Link lt = new Link(DatapathId.of(1L), OFPort.of(2), DatapathId.of(1L), OFPort.of(3));
+        LinkInfo info = new LinkInfo(new Date(),
+                                     new Date(), null);
         linkDiscovery.addOrUpdateLink(lt, info);
 
         // Mock up our expected behavior
@@ -284,14 +288,14 @@ public class LinkDiscoveryManagerTest extends FloodlightTestCase {
     public void testAddUpdateLinks() throws Exception {
         LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
 
-        Link lt = new Link(1L, 1, 2L, 1);
-        NodePortTuple srcNpt = new NodePortTuple(1L, 1);
-        NodePortTuple dstNpt = new NodePortTuple(2L, 1);
+        Link lt = new Link(DatapathId.of(1L), OFPort.of(1), DatapathId.of(2L), OFPort.of(1));
+        NodePortTuple srcNpt = new NodePortTuple(DatapathId.of(1L), OFPort.of(1));
+        NodePortTuple dstNpt = new NodePortTuple(DatapathId.of(2L), OFPort.of(2));
 
         LinkInfo info;
 
-        info = new LinkInfo(System.currentTimeMillis() - 40000,
-                            System.currentTimeMillis() - 40000, null);
+        info = new LinkInfo(new Date(System.currentTimeMillis() - 40000),
+                            new Date(System.currentTimeMillis() - 40000), null);
         linkDiscovery.addOrUpdateLink(lt, info);
 
         // check invariants hold
@@ -306,9 +310,9 @@ public class LinkDiscoveryManagerTest extends FloodlightTestCase {
         linkDiscovery.timeoutLinks();
 
 
-        info = new LinkInfo(System.currentTimeMillis(),/* firstseen */
+        info = new LinkInfo(new Date(),/* firstseen */
                             null,/* unicast */
-                            System.currentTimeMillis());
+                            new Date());
         linkDiscovery.addOrUpdateLink(lt, info);
         assertTrue(linkDiscovery.links.get(lt).getUnicastValidTime() == null);
         assertTrue(linkDiscovery.links.get(lt).getMulticastValidTime() != null);
@@ -319,8 +323,8 @@ public class LinkDiscoveryManagerTest extends FloodlightTestCase {
         // this to test timeout after this test.  Although the info is initialized
         // with LT_OPENFLOW_LINK, the link property should be changed to LT_NON_OPENFLOW
         // by the addOrUpdateLink method.
-        info = new LinkInfo(System.currentTimeMillis() - 40000,
-                            System.currentTimeMillis() - 40000, null);
+        info = new LinkInfo(new Date(System.currentTimeMillis() - 40000),
+                            new Date(System.currentTimeMillis() - 40000), null);
         linkDiscovery.addOrUpdateLink(lt, info);
 
         // Expect to timeout the unicast Valid Time, but not the multicast Valid time
@@ -330,15 +334,15 @@ public class LinkDiscoveryManagerTest extends FloodlightTestCase {
         assertTrue(linkDiscovery.links.get(lt).getMulticastValidTime() != null);
 
         // Set the multicastValidTime to be old and see if that also times out.
-        info = new LinkInfo(System.currentTimeMillis() - 40000,
-                            null, System.currentTimeMillis() - 40000);
+        info = new LinkInfo(new Date(System.currentTimeMillis() - 40000),
+                            null, new Date(System.currentTimeMillis() - 40000));
         linkDiscovery.addOrUpdateLink(lt, info);
         linkDiscovery.timeoutLinks();
         assertTrue(linkDiscovery.links.get(lt) == null);
 
         // Test again only with multicast LLDP
-        info = new LinkInfo(System.currentTimeMillis() - 40000,
-                            null, System.currentTimeMillis() - 40000);
+        info = new LinkInfo(new Date(System.currentTimeMillis() - 40000),
+                            null, new Date(System.currentTimeMillis() - 40000));
         linkDiscovery.addOrUpdateLink(lt, info);
         assertTrue(linkDiscovery.links.get(lt).getUnicastValidTime() == null);
         assertTrue(linkDiscovery.links.get(lt).getMulticastValidTime() != null);
@@ -348,36 +352,36 @@ public class LinkDiscoveryManagerTest extends FloodlightTestCase {
         assertTrue(linkDiscovery.links.get(lt) == null);
 
         // Start clean and see if loops are also added.
-        lt = new Link(1L, 1, 1L, 2);
-        srcNpt = new NodePortTuple(1L, 1);
-        dstNpt = new NodePortTuple(1L, 2);
-        info = new LinkInfo(System.currentTimeMillis() - 40000,
-                            null, System.currentTimeMillis() - 40000);
+        lt = new Link(DatapathId.of(1L), OFPort.of(1), DatapathId.of(1L), OFPort.of(2));
+        srcNpt = new NodePortTuple(DatapathId.of(1L), OFPort.of(1));
+        dstNpt = new NodePortTuple(DatapathId.of(1L), OFPort.of(2));
+        info = new LinkInfo(new Date(System.currentTimeMillis() - 40000),
+                            null, new Date(System.currentTimeMillis() - 40000));
         linkDiscovery.addOrUpdateLink(lt, info);
 
 
         // Start clean and see if loops are also added.
-        lt = new Link(1L, 1, 1L, 3);
-        srcNpt = new NodePortTuple(1L, 1);
-        dstNpt = new NodePortTuple(1L, 3);
-        info = new LinkInfo(System.currentTimeMillis() - 40000,
-                            null, System.currentTimeMillis() - 40000);
+        lt = new Link(DatapathId.of(1L), OFPort.of(1), DatapathId.of(1L), OFPort.of(3));
+        srcNpt = new NodePortTuple(DatapathId.of(1L), OFPort.of(1));
+        dstNpt = new NodePortTuple(DatapathId.of(1L), OFPort.of(3));
+        info = new LinkInfo(new Date(System.currentTimeMillis() - 40000),
+                            null, new Date(System.currentTimeMillis() - 40000));
         linkDiscovery.addOrUpdateLink(lt, info);
 
         // Start clean and see if loops are also added.
-        lt = new Link(1L, 4, 1L, 5);
-        srcNpt = new NodePortTuple(1L, 4);
-        dstNpt = new NodePortTuple(1L, 5);
-        info = new LinkInfo(System.currentTimeMillis() - 40000,
-                            null, System.currentTimeMillis() - 40000);
+        lt = new Link(DatapathId.of(1L), OFPort.of(4), DatapathId.of(1L), OFPort.of(5));
+        srcNpt = new NodePortTuple(DatapathId.of(1L), OFPort.of(4));
+        dstNpt = new NodePortTuple(DatapathId.of(1L), OFPort.of(5));
+        info = new LinkInfo(new Date(System.currentTimeMillis() - 40000),
+                            null, new Date(System.currentTimeMillis() - 40000));
         linkDiscovery.addOrUpdateLink(lt, info);
 
         // Start clean and see if loops are also added.
-        lt = new Link(1L, 3, 1L, 5);
-        srcNpt = new NodePortTuple(1L, 3);
-        dstNpt = new NodePortTuple(1L, 5);
-        info = new LinkInfo(System.currentTimeMillis() - 40000,
-                            null, System.currentTimeMillis() - 40000);
+        lt = new Link(DatapathId.of(1L), OFPort.of(3), DatapathId.of(1L), OFPort.of(5));
+        srcNpt = new NodePortTuple(DatapathId.of(1L), OFPort.of(3));
+        dstNpt = new NodePortTuple(DatapathId.of(1L), OFPort.of(5));
+        info = new LinkInfo(new Date(System.currentTimeMillis() - 40000),
+                            null, new Date(System.currentTimeMillis() - 40000));
         linkDiscovery.addOrUpdateLink(lt, info);
     }
 
@@ -387,11 +391,11 @@ public class LinkDiscoveryManagerTest extends FloodlightTestCase {
         IOFSwitch sw1 = createMockSwitch(1L);
         IOFSwitch sw2 = createMockSwitch(2L);
         replay(sw1, sw2);
-        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(), null);
+        Link lt = new Link(DatapathId.of(1L), OFPort.of(2), DatapathId.of(2L), OFPort.of(1));
+        NodePortTuple srcNpt = new NodePortTuple(DatapathId.of(1L), OFPort.of(2));
+        NodePortTuple dstNpt = new NodePortTuple(DatapathId.of(2L), OFPort.of(1));
+        LinkInfo info = new LinkInfo(new Date(),
+        		new Date(), null);
         linkDiscovery.addOrUpdateLink(lt, info);
 
         // check invariants hold
@@ -419,35 +423,34 @@ public class LinkDiscoveryManagerTest extends FloodlightTestCase {
     public void testSwitchAdded() throws Exception {
         LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
         Capture<OFMessage> wc;
-        Capture<FloodlightContext> fc;
-        Set<Short> qPorts;
-        OFPhysicalPort ofpp = new OFPhysicalPort();
-        ofpp.setName("eth4242");
-        ofpp.setPortNumber((short)4242);
-        ofpp.setHardwareAddress(HexString.fromHexString("5c:16:c7:00:00:01"));
-        ofpp.setCurrentFeatures(0);
-        ImmutablePort p1 = ImmutablePort.fromOFPhysicalPort(ofpp);
+        Set<OFPort> qPorts;
+        OFPortDesc ofpp = OFFactories.getFactory(OFVersion.OF_13).buildPortDesc()
+        .setName("eth4242")
+        .setPortNo(OFPort.of(4242))
+        .setHwAddr(MacAddress.of("5c:16:c7:00:00:01"))
+        .setCurr(null)
+        .build();
+        OFPort p1 = ofpp.getPortNo();
         IOFSwitch sw1 = createMockSwitch(1L);
 
         // Set switch map in floodlightProvider.
-        Map<Long, IOFSwitch> switches = new HashMap<Long, IOFSwitch>();
-        switches.put(1L, sw1);
-        getMockFloodlightProvider().setSwitches(switches);
+        Map<DatapathId, IOFSwitch> switches = new HashMap<DatapathId, IOFSwitch>();
+        switches.put(DatapathId.of(1L), sw1);
+        getMockSwitchService().setSwitches(switches);
 
         // Create the set of ports
-        List<Short> ports = new ArrayList<Short>();
+        List<OFPort> ports = new ArrayList<OFPort>();
         for(short p=1; p<=20; ++p) {
-            ports.add(p);
+            ports.add(OFPort.of(p));
         }
 
         // Set the captures.
         wc = new Capture<OFMessage>(CaptureType.ALL);
-        fc = new Capture<FloodlightContext>(CaptureType.ALL);
 
         // Expect switch to return those ports.
         expect(sw1.getEnabledPortNumbers()).andReturn(ports).anyTimes();
-        expect(sw1.getPort(EasyMock.anyShort())).andReturn(p1).anyTimes();
-        sw1.write(capture(wc), capture(fc));
+        expect(sw1.getPort(OFPort.of(EasyMock.anyShort())).getPortNo()).andReturn(p1).anyTimes();
+        sw1.write(capture(wc));
         expectLastCall().anyTimes();
         replay(sw1);
 
@@ -494,12 +497,12 @@ public class LinkDiscoveryManagerTest extends FloodlightTestCase {
         byte[] testPacketSerialized = testPacket.serialize();
         OFPacketIn pi;
         // build out input packet
-        pi = ((OFPacketIn) BasicFactory.getInstance().getMessage(OFType.PACKET_IN))
-                .setBufferId(-1)
-                .setInPort((short) 1)
-                .setPacketData(testPacketSerialized)
+        pi = OFFactories.getFactory(OFVersion.OF_13).buildPacketIn()
+                .setBufferId(OFBufferId.NO_BUFFER)
+                .setInPort(OFPort.of(1))
+                .setData(testPacketSerialized)
                 .setReason(OFPacketInReason.NO_MATCH)
-                .setTotalLength((short) testPacketSerialized.length);
+                .build();
         return pi;
     }
 
@@ -513,7 +516,7 @@ public class LinkDiscoveryManagerTest extends FloodlightTestCase {
         short vlan = 42;
 
         IOFSwitch mockSwitch = createMock(IOFSwitch.class);
-        expect(mockSwitch.getId()).andReturn(1L).anyTimes();
+        expect(mockSwitch.getId()).andReturn(DatapathId.of(1L)).anyTimes();
         replay(mockSwitch);
 
         /* TEST1: See basic packet flow */
@@ -521,7 +524,7 @@ public class LinkDiscoveryManagerTest extends FloodlightTestCase {
         pi = createPacketIn(mac1, mac2, srcIp, dstIp, vlan);
         FloodlightContext cntx = new FloodlightContext();
         Ethernet eth = new Ethernet();
-        eth.deserialize(pi.getPacketData(), 0, pi.getPacketData().length);
+        eth.deserialize(pi.getData(), 0, pi.getData().length);
         IFloodlightProviderService.bcStore.put(cntx,
                 IFloodlightProviderService.CONTEXT_PI_PAYLOAD,
                 eth);
@@ -532,14 +535,14 @@ public class LinkDiscoveryManagerTest extends FloodlightTestCase {
         /* TEST2: Add mac1 to the ignore MAC list and see that the packet is
          * dropped
          */
-        ldm.addMACToIgnoreList(HexString.toLong(mac1), 0);
+        ldm.addMACToIgnoreList(MacAddress.of(mac1), 0);
         ret = ldm.receive(mockSwitch, pi, cntx);
         assertEquals(Command.STOP, ret);
         /* Verify that if we send a packet with another MAC it still works */
         pi = createPacketIn(mac2, mac3, srcIp, dstIp, vlan);
         cntx = new FloodlightContext();
         eth = new Ethernet();
-        eth.deserialize(pi.getPacketData(), 0, pi.getPacketData().length);
+        eth.deserialize(pi.getData(), 0, pi.getData().length);
         IFloodlightProviderService.bcStore.put(cntx,
                 IFloodlightProviderService.CONTEXT_PI_PAYLOAD,
                 eth);
@@ -547,7 +550,7 @@ public class LinkDiscoveryManagerTest extends FloodlightTestCase {
         assertEquals(Command.CONTINUE, ret);
 
         /* TEST3: Add a MAC range and see if that is ignored */
-        ldm.addMACToIgnoreList(HexString.toLong(mac2), 8);
+        ldm.addMACToIgnoreList(MacAddress.of(mac2), 8);
         ret = ldm.receive(mockSwitch, pi, cntx);
         assertEquals(Command.STOP, ret);
         /* Send a packet with source MAC as mac3 and see that that is ignored
@@ -556,7 +559,7 @@ public class LinkDiscoveryManagerTest extends FloodlightTestCase {
         pi = createPacketIn(mac3, mac1, srcIp, dstIp, vlan);
         cntx = new FloodlightContext();
         eth = new Ethernet();
-        eth.deserialize(pi.getPacketData(), 0, pi.getPacketData().length);
+        eth.deserialize(pi.getData(), 0, pi.getData().length);
         IFloodlightProviderService.bcStore.put(cntx,
                 IFloodlightProviderService.CONTEXT_PI_PAYLOAD,
                 eth);
diff --git a/src/test/java/net/floodlightcontroller/loadbalancer/LoadBalancerTest.java b/src/test/java/net/floodlightcontroller/loadbalancer/LoadBalancerTest.java
index b1f6b0253a4c0be0cec494d0767c18c58212119e..a78460f5d00c09f62fa3ace90d7f426a8713a9f3 100644
--- a/src/test/java/net/floodlightcontroller/loadbalancer/LoadBalancerTest.java
+++ b/src/test/java/net/floodlightcontroller/loadbalancer/LoadBalancerTest.java
@@ -25,6 +25,7 @@ import static org.easymock.EasyMock.expectLastCall;
 import static org.easymock.EasyMock.replay;
 import static org.easymock.EasyMock.reset;
 import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.*;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -36,17 +37,22 @@ import org.easymock.CaptureType;
 import org.easymock.EasyMock;
 import org.junit.Before;
 import org.junit.Test;
-import org.openflow.protocol.OFFlowMod;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFPacketOut;
-import org.openflow.protocol.OFPort;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.OFPacketIn.OFPacketInReason;
-import org.openflow.protocol.action.OFAction;
-import org.openflow.protocol.action.OFActionOutput;
-import org.openflow.util.HexString;
+import org.projectfloodlight.openflow.protocol.OFFlowMod;
+import org.projectfloodlight.openflow.protocol.OFFactories;
+import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFPacketIn;
+import org.projectfloodlight.openflow.protocol.OFPacketOut;
+import org.projectfloodlight.openflow.protocol.OFVersion;
+import org.projectfloodlight.openflow.types.IPv4Address;
+import org.projectfloodlight.openflow.types.IpProtocol;
+import org.projectfloodlight.openflow.types.MacAddress;
+import org.projectfloodlight.openflow.types.OFBufferId;
+import org.projectfloodlight.openflow.types.OFPort;
+import org.projectfloodlight.openflow.types.U64;
+import org.projectfloodlight.openflow.protocol.OFPacketInReason;
+import org.projectfloodlight.openflow.protocol.action.OFAction;
+import org.projectfloodlight.openflow.util.HexString;
+import org.projectfloodlight.openflow.types.DatapathId;
 import org.sdnplatform.sync.ISyncService;
 import org.sdnplatform.sync.test.MockSyncService;
 
@@ -55,8 +61,6 @@ import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IOFSwitch;
 import net.floodlightcontroller.core.module.FloodlightModuleContext;
 import net.floodlightcontroller.core.test.MockThreadPoolService;
-import net.floodlightcontroller.counter.CounterStore;
-import net.floodlightcontroller.counter.ICounterStoreService;
 import net.floodlightcontroller.devicemanager.IDeviceService;
 import net.floodlightcontroller.devicemanager.IEntityClassifierService;
 import net.floodlightcontroller.devicemanager.internal.DefaultEntityClassifier;
@@ -82,618 +86,592 @@ import net.floodlightcontroller.topology.ITopologyService;
 import net.floodlightcontroller.topology.NodePortTuple;
 
 public class LoadBalancerTest extends FloodlightTestCase {
-    protected LoadBalancer lb;
-
-    protected FloodlightContext cntx;
-    protected FloodlightModuleContext fmc;
-    protected MockDeviceManager deviceManager;
-    protected MockThreadPoolService tps;
-    protected FlowReconcileManager frm;
-    protected DefaultEntityClassifier entityClassifier;
-    protected IRoutingService routingEngine;
-    protected ITopologyService topology;
-    protected StaticFlowEntryPusher sfp;
-    protected MemoryStorageSource storage;
-    protected RestApiServer restApi;
-    protected VipsResource vipsResource;
-    protected PoolsResource poolsResource;
-    protected MembersResource membersResource;
-    private MockSyncService mockSyncService;
-
-    protected LBVip vip1, vip2;
-    protected LBPool pool1, pool2, pool3;
-    protected LBMember member1, member2, member3, member4;
-
-    @Override
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-
-        lb = new LoadBalancer();
-
-        cntx = new FloodlightContext();
-        fmc = new FloodlightModuleContext();
-        entityClassifier = new DefaultEntityClassifier(); // dependency for device manager
-        frm = new FlowReconcileManager(); //dependency for device manager
-        tps = new MockThreadPoolService(); //dependency for device manager
-        deviceManager = new MockDeviceManager();
-        topology = createMock(ITopologyService.class);
-        routingEngine = createMock(IRoutingService.class);
-        restApi = new RestApiServer();
-        sfp = new StaticFlowEntryPusher();
-        storage = new MemoryStorageSource(); //dependency for sfp
-        mockSyncService = new MockSyncService();
-
-        fmc.addService(IRestApiService.class, restApi);
-        fmc.addService(IFloodlightProviderService.class, getMockFloodlightProvider());
-        fmc.addService(IEntityClassifierService.class, entityClassifier);
-        fmc.addService(IFlowReconcileService.class, frm);
-        fmc.addService(IThreadPoolService.class, tps);
-        fmc.addService(IDeviceService.class, deviceManager);
-        fmc.addService(ITopologyService.class, topology);
-        fmc.addService(IRoutingService.class, routingEngine);
-        fmc.addService(ICounterStoreService.class, new CounterStore());
-        fmc.addService(IStaticFlowEntryPusherService.class, sfp);
-        fmc.addService(ILoadBalancerService.class, lb);
-        fmc.addService(IStorageSourceService.class, storage);
-        fmc.addService(ISyncService.class, mockSyncService);
-
-        lb.init(fmc);
-        getMockFloodlightProvider().init(fmc);
-        entityClassifier.init(fmc);
-        frm.init(fmc);
-        tps.init(fmc);
-        mockSyncService.init(fmc);
-        deviceManager.init(fmc);
-        restApi.init(fmc);
-        sfp.init(fmc);
-        storage.init(fmc);
-
-        topology.addListener(deviceManager);
-        expectLastCall().times(1);
-        replay(topology);
-
-        lb.startUp(fmc);
-        getMockFloodlightProvider().startUp(fmc);
-        entityClassifier.startUp(fmc);
-        frm.startUp(fmc);
-        tps.startUp(fmc);
-        mockSyncService.startUp(fmc);
-        deviceManager.startUp(fmc);
-        restApi.startUp(fmc);
-        sfp.startUp(fmc);
-        storage.startUp(fmc);
-
-        verify(topology);
-
-        vipsResource = new VipsResource();
-        poolsResource = new PoolsResource();
-        membersResource = new MembersResource();
-
-        vip1=null;
-        vip2=null;
-
-        pool1=null;
-        pool2=null;
-        pool3=null;
-
-        member1=null;
-        member2=null;
-        member3=null;
-        member4=null;
-    }
-
-    @Test
-    public void testCreateVip() {
-        String postData1, postData2;
-        IOException error = null;
-
-        postData1 = "{\"id\":\"1\",\"name\":\"vip1\",\"protocol\":\"icmp\",\"address\":\"10.0.0.100\",\"port\":\"8\"}";
-        postData2 = "{\"id\":\"2\",\"name\":\"vip2\",\"protocol\":\"tcp\",\"address\":\"10.0.0.200\",\"port\":\"100\"}";
-
-        try {
-            vip1 = vipsResource.jsonToVip(postData1);
-        } catch (IOException e) {
-            error = e;
-        }
-        try {
-            vip2 = vipsResource.jsonToVip(postData2);
-        } catch (IOException e) {
-            error = e;
-        }
-
-        // verify correct parsing
-        assertFalse(vip1==null);
-        assertFalse(vip2==null);
-        assertTrue(error==null);
-
-        lb.createVip(vip1);
-        lb.createVip(vip2);
-
-        // verify correct creation
-        assertTrue(lb.vips.containsKey(vip1.id));
-        assertTrue(lb.vips.containsKey(vip2.id));
-    }
-
-    @Test
-    public void testRemoveVip() {
-
-        testCreateVip();
-
-        // verify correct initial condition
-        assertFalse(vip1==null);
-        assertFalse(vip2==null);
-
-        lb.removeVip(vip1.id);
-        lb.removeVip(vip2.id);
-
-        // verify correct removal
-        assertFalse(lb.vips.containsKey(vip1.id));
-        assertFalse(lb.vips.containsKey(vip2.id));
-
-    }
-
-    @Test
-    public void testCreatePool() {
-        String postData1, postData2, postData3;
-        IOException error = null;
-
-        testCreateVip();
-
-        postData1 = "{\"id\":\"1\",\"name\":\"pool1\",\"protocol\":\"icmp\",\"vip_id\":\"1\"}";
-        postData2 = "{\"id\":\"2\",\"name\":\"pool2\",\"protocol\":\"tcp\",\"vip_id\":\"2\"}";
-        postData3 = "{\"id\":\"3\",\"name\":\"pool3\",\"protocol\":\"udp\",\"vip_id\":\"3\"}";
-
-        try {
-            pool1 = poolsResource.jsonToPool(postData1);
-        } catch (IOException e) {
-            error = e;
-        }
-        try {
-            pool2 = poolsResource.jsonToPool(postData2);
-        } catch (IOException e) {
-            error = e;
-        }
-        try {
-            pool3 = poolsResource.jsonToPool(postData3);
-        } catch (IOException e) {
-            error = e;
-        }
-
-        // verify correct parsing
-        assertFalse(pool1==null);
-        assertFalse(pool2==null);
-        assertFalse(pool3==null);
-        assertTrue(error==null);
-
-        lb.createPool(pool1);
-        lb.createPool(pool2);
-        lb.createPool(pool3);
-
-        // verify successful creates; two registered with vips and one not
-        assertTrue(lb.pools.containsKey(pool1.id));
-        assertTrue(lb.vips.get(pool1.vipId).pools.contains(pool1.id));
-        assertTrue(lb.pools.containsKey(pool2.id));
-        assertTrue(lb.vips.get(pool2.vipId).pools.contains(pool2.id));
-        assertTrue(lb.pools.containsKey(pool3.id));
-        assertFalse(lb.vips.containsKey(pool3.vipId));
-
-    }
-
-    @Test
-    public void testRemovePool() {
-        testCreateVip();
-        testCreatePool();
-
-        // verify correct initial condition
-        assertFalse(vip1==null);
-        assertFalse(vip2==null);
-        assertFalse(pool1==null);
-        assertFalse(pool2==null);
-        assertFalse(pool3==null);
-
-        lb.removePool(pool1.id);
-        lb.removePool(pool2.id);
-        lb.removePool(pool3.id);
-
-        // verify correct removal
-        assertFalse(lb.pools.containsKey(pool1.id));
-        assertFalse(lb.pools.containsKey(pool2.id));
-        assertFalse(lb.pools.containsKey(pool3.id));
-
-        //verify pool cleanup from vip
-        assertFalse(lb.vips.get(pool1.vipId).pools.contains(pool1.id));
-        assertFalse(lb.vips.get(pool2.vipId).pools.contains(pool2.id));
-    }
-
-    @Test
-    public void testCreateMember() {
-        String postData1, postData2, postData3, postData4;
-        IOException error = null;
-
-        testCreateVip();
-        testCreatePool();
-
-        postData1 = "{\"id\":\"1\",\"address\":\"10.0.0.3\",\"port\":\"8\",\"pool_id\":\"1\"}";
-        postData2 = "{\"id\":\"2\",\"address\":\"10.0.0.4\",\"port\":\"8\",\"pool_id\":\"1\"}";
-        postData3 = "{\"id\":\"3\",\"address\":\"10.0.0.5\",\"port\":\"100\",\"pool_id\":\"2\"}";
-        postData4 = "{\"id\":\"4\",\"address\":\"10.0.0.6\",\"port\":\"100\",\"pool_id\":\"2\"}";
-
-        try {
-            member1 = membersResource.jsonToMember(postData1);
-        } catch (IOException e) {
-            error = e;
-        }
-        try {
-            member2 = membersResource.jsonToMember(postData2);
-        } catch (IOException e) {
-            error = e;
-        }
-        try {
-            member3 = membersResource.jsonToMember(postData3);
-        } catch (IOException e) {
-            error = e;
-        }
-        try {
-            member4 = membersResource.jsonToMember(postData4);
-        } catch (IOException e) {
-            error = e;
-        }
-
-        // verify correct parsing
-        assertFalse(member1==null);
-        assertFalse(member2==null);
-        assertFalse(member3==null);
-        assertFalse(member4==null);
-        assertTrue(error==null);
-
-        lb.createMember(member1);
-        lb.createMember(member2);
-        lb.createMember(member3);
-        lb.createMember(member4);
-
-        // add the same server a second time
-        lb.createMember(member1);
-
-        // verify successful creates
-        assertTrue(lb.members.containsKey(member1.id));
-        assertTrue(lb.members.containsKey(member2.id));
-        assertTrue(lb.members.containsKey(member3.id));
-        assertTrue(lb.members.containsKey(member4.id));
-
-        assertTrue(lb.pools.get(member1.poolId).members.size()==2);
-        assertTrue(lb.pools.get(member3.poolId).members.size()==2);
-
-        // member1 should inherit valid vipId from pool
-        assertTrue(lb.vips.get(member1.vipId)!=null);
-    }
-
-    @Test
-    public void testRemoveMember() {
-        testCreateVip();
-        testCreatePool();
-        testCreateMember();
-
-        // verify correct initial condition
-        assertFalse(vip1==null);
-        assertFalse(vip2==null);
-        assertFalse(pool1==null);
-        assertFalse(pool2==null);
-        assertFalse(pool3==null);
-        assertFalse(member1==null);
-        assertFalse(member2==null);
-        assertFalse(member3==null);
-        assertFalse(member4==null);
-
-        lb.removeMember(member1.id);
-        lb.removeMember(member2.id);
-        lb.removeMember(member3.id);
-        lb.removeMember(member4.id);
-
-        // verify correct removal
-        assertFalse(lb.members.containsKey(member1.id));
-        assertFalse(lb.members.containsKey(member2.id));
-        assertFalse(lb.members.containsKey(member3.id));
-        assertFalse(lb.members.containsKey(member4.id));
-
-        //verify member cleanup from pool
-        assertFalse(lb.pools.get(member1.poolId).members.contains(member1.id));
-        assertFalse(lb.pools.get(member2.poolId).members.contains(member2.id));
-        assertFalse(lb.pools.get(member3.poolId).members.contains(member3.id));
-        assertFalse(lb.pools.get(member4.poolId).members.contains(member4.id));
-
-    }
-
-    @Test
-    public void testTwoSubsequentIcmpRequests() throws Exception {
-     testCreateVip();
-     testCreatePool();
-     testCreateMember();
-
-     IOFSwitch sw1;
-
-     IPacket arpRequest1, arpReply1, icmpPacket1, icmpPacket2;
-
-     byte[] arpRequest1Serialized;
-     byte[] arpReply1Serialized;
-     byte[] icmpPacket1Serialized, icmpPacket2Serialized;
-
-     OFPacketIn arpRequestPacketIn1;
-     OFPacketIn icmpPacketIn1, icmpPacketIn2;
-
-     OFPacketOut arpReplyPacketOut1;
-
-     Capture<OFMessage> wc1 = new Capture<OFMessage>(CaptureType.ALL);
-     Capture<FloodlightContext> bc1 =
-             new Capture<FloodlightContext>(CaptureType.ALL);
-
-     int fastWildcards =
-             OFMatch.OFPFW_IN_PORT |
-             OFMatch.OFPFW_NW_PROTO |
-             OFMatch.OFPFW_TP_SRC |
-             OFMatch.OFPFW_TP_DST |
-             OFMatch.OFPFW_NW_SRC_ALL |
-             OFMatch.OFPFW_NW_DST_ALL |
-             OFMatch.OFPFW_NW_TOS;
-
-     sw1 = EasyMock.createNiceMock(IOFSwitch.class);
-     expect(sw1.getId()).andReturn(1L).anyTimes();
-     expect(sw1.getStringId()).andReturn("00:00:00:00:00:01").anyTimes();
-     expect(sw1.getAttribute(IOFSwitch.PROP_FASTWILDCARDS)).andReturn(fastWildcards).anyTimes();
-     expect(sw1.hasAttribute(IOFSwitch.PROP_SUPPORTS_OFPP_TABLE)).andReturn(true).anyTimes();
-     sw1.writeThrottled(capture(wc1), capture(bc1));
-     expectLastCall().anyTimes();
-     sw1.flush();
-     expectLastCall().anyTimes();
-
-     replay(sw1);
-     sfp.switchAdded(1L);
-     verify(sw1);
-
-     /* Test plan:
-      * - two clients and two servers on sw1 port 1, 2, 3, 4
-      * - mock arp request received towards vip1 from (1L, 1)
-      * - proxy arp got pushed out to (1L, 1)- check sw1 getting the packetout
-      * - mock icmp request received towards vip1 from (1L, 1)
-      * - device manager list of devices queried to identify source and dest devices
-      * - routing engine queried to get inbound and outbound routes
-      * - check getRoute calls and responses
-      * - sfp called to install flows
-      * - check sfp calls
-      */
-
-     // Build topology
-     reset(topology);
-     expect(topology.isIncomingBroadcastAllowed(anyLong(), anyShort())).andReturn(true).anyTimes();
-     expect(topology.getL2DomainId(1L)).andReturn(1L).anyTimes();
-     expect(topology.isAttachmentPointPort(1L, (short)1)).andReturn(true).anyTimes();
-     expect(topology.isAttachmentPointPort(1L, (short)2)).andReturn(true).anyTimes();
-     expect(topology.isAttachmentPointPort(1L, (short)3)).andReturn(true).anyTimes();
-     expect(topology.isAttachmentPointPort(1L, (short)4)).andReturn(true).anyTimes();
-     replay(topology);
-
-
-
-     // Build arp packets
-     arpRequest1 = new Ethernet()
-     .setSourceMACAddress("00:00:00:00:00:01")
-     .setDestinationMACAddress("ff:ff:ff:ff:ff:ff")
-     .setEtherType(Ethernet.TYPE_ARP)
-     .setVlanID((short) 0)
-     .setPriorityCode((byte) 0)
-     .setPayload(
-         new ARP()
-         .setHardwareType(ARP.HW_TYPE_ETHERNET)
-         .setProtocolType(ARP.PROTO_TYPE_IP)
-         .setHardwareAddressLength((byte) 6)
-         .setProtocolAddressLength((byte) 4)
-         .setOpCode(ARP.OP_REQUEST)
-         .setSenderHardwareAddress(HexString.fromHexString("00:00:00:00:00:01"))
-         .setSenderProtocolAddress(IPv4.toIPv4AddressBytes("10.0.0.1"))
-         .setTargetHardwareAddress(HexString.fromHexString("00:00:00:00:00:00"))
-         .setTargetProtocolAddress(IPv4.toIPv4AddressBytes("10.0.0.100")));
-
-     arpRequest1Serialized = arpRequest1.serialize();
-
-     arpRequestPacketIn1 =
-             ((OFPacketIn) getMockFloodlightProvider().getOFMessageFactory().
-                     getMessage(OFType.PACKET_IN))
-                     .setBufferId(-1)
-                     .setInPort((short) 1)
-                     .setPacketData(arpRequest1Serialized)
-                     .setReason(OFPacketInReason.NO_MATCH)
-                     .setTotalLength((short) arpRequest1Serialized.length);
-
-     IFloodlightProviderService.bcStore.put(cntx,
-                                            IFloodlightProviderService.CONTEXT_PI_PAYLOAD,
-                                            (Ethernet) arpRequest1);
-
-     // Mock proxy arp packet-out
-     arpReply1 = new Ethernet()
-     .setSourceMACAddress(LBVip.LB_PROXY_MAC)
-     .setDestinationMACAddress(HexString.fromHexString("00:00:00:00:00:01"))
-     .setEtherType(Ethernet.TYPE_ARP)
-     .setVlanID((short) 0)
-     .setPriorityCode((byte) 0)
-     .setPayload(
-         new ARP()
-         .setHardwareType(ARP.HW_TYPE_ETHERNET)
-         .setProtocolType(ARP.PROTO_TYPE_IP)
-         .setHardwareAddressLength((byte) 6)
-         .setProtocolAddressLength((byte) 4)
-         .setOpCode(ARP.OP_REPLY)
-         .setSenderHardwareAddress(HexString.fromHexString(LBVip.LB_PROXY_MAC))
-         .setSenderProtocolAddress(IPv4.toIPv4AddressBytes("10.0.0.100"))
-         .setTargetHardwareAddress(HexString.fromHexString("00:00:00:00:00:01"))
-         .setTargetProtocolAddress(IPv4.toIPv4AddressBytes("10.0.0.1")));
-
-     arpReply1Serialized = arpReply1.serialize();
-
-     arpReplyPacketOut1 =
-             (OFPacketOut) getMockFloodlightProvider().getOFMessageFactory().
-                 getMessage(OFType.PACKET_OUT);
-     arpReplyPacketOut1.setBufferId(OFPacketOut.BUFFER_ID_NONE)
-         .setInPort(OFPort.OFPP_NONE.getValue());
-     List<OFAction> poactions = new ArrayList<OFAction>();
-     poactions.add(new OFActionOutput(arpRequestPacketIn1.getInPort(), (short) 0xffff));
-     arpReplyPacketOut1.setActions(poactions)
-         .setActionsLength((short) OFActionOutput.MINIMUM_LENGTH)
-         .setPacketData(arpReply1Serialized)
-         .setLengthU(OFPacketOut.MINIMUM_LENGTH+
-                     arpReplyPacketOut1.getActionsLength()+
-                     arpReply1Serialized.length);
-
-     lb.receive(sw1, arpRequestPacketIn1, cntx);
-     verify(sw1, topology);
-
-     assertTrue(wc1.hasCaptured());  // wc1 should get packetout
-
-     List<OFMessage> msglist1 = wc1.getValues();
-
-     for (OFMessage m: msglist1) {
-         if (m instanceof OFPacketOut)
-             assertEquals(arpReplyPacketOut1, m);
-         else
-             assertTrue(false); // unexpected message
-     }
-
-     //
-     // Skip arpRequest2 test - in reality this will happen, but for unit test the same logic
-     // is already validated with arpRequest1 test above
-     //
-
-     // Build icmp packets
-     icmpPacket1 = new Ethernet()
-     .setSourceMACAddress("00:00:00:00:00:01")
-     .setDestinationMACAddress(LBVip.LB_PROXY_MAC)
-     .setEtherType(Ethernet.TYPE_IPv4)
-     .setVlanID((short) 0)
-     .setPriorityCode((byte) 0)
-     .setPayload(
-         new IPv4()
-         .setSourceAddress("10.0.0.1")
-         .setDestinationAddress("10.0.0.100")
-         .setProtocol(IPv4.PROTOCOL_ICMP)
-         .setPayload(new ICMP()
-         .setIcmpCode((byte) 0)
-         .setIcmpType((byte) 0)));
-
-     icmpPacket1Serialized = icmpPacket1.serialize();
-
-     icmpPacketIn1 =
-             ((OFPacketIn) getMockFloodlightProvider().getOFMessageFactory().
-                     getMessage(OFType.PACKET_IN))
-                     .setBufferId(-1)
-                     .setInPort((short) 1)
-                     .setPacketData(icmpPacket1Serialized)
-                     .setReason(OFPacketInReason.NO_MATCH)
-                     .setTotalLength((short) icmpPacket1Serialized.length);
-
-     icmpPacket2 = new Ethernet()
-     .setSourceMACAddress("00:00:00:00:00:02")
-     .setDestinationMACAddress(LBVip.LB_PROXY_MAC)
-     .setEtherType(Ethernet.TYPE_IPv4)
-     .setVlanID((short) 0)
-     .setPriorityCode((byte) 0)
-     .setPayload(
-         new IPv4()
-         .setSourceAddress("10.0.0.2")
-         .setDestinationAddress("10.0.0.100")
-         .setProtocol(IPv4.PROTOCOL_ICMP)
-         .setPayload(new ICMP()
-         .setIcmpCode((byte) 0)
-         .setIcmpType((byte) 0)));
-
-     icmpPacket2Serialized = icmpPacket2.serialize();
-
-     icmpPacketIn2 =
-             ((OFPacketIn) getMockFloodlightProvider().getOFMessageFactory().
-                     getMessage(OFType.PACKET_IN))
-                     .setBufferId(-1)
-                     .setInPort((short) 2)
-                     .setPacketData(icmpPacket2Serialized)
-                     .setReason(OFPacketInReason.NO_MATCH)
-                     .setTotalLength((short) icmpPacket2Serialized.length);
-
-     byte[] dataLayerSource1 = ((Ethernet)icmpPacket1).getSourceMACAddress();
-     int networkSource1 = ((IPv4)((Ethernet)icmpPacket1).getPayload()).getSourceAddress();
-     byte[] dataLayerDest1 = HexString.fromHexString("00:00:00:00:00:03");
-     int networkDest1 = IPv4.toIPv4Address("10.0.0.3");
-     byte[] dataLayerSource2 = ((Ethernet)icmpPacket2).getSourceMACAddress();
-     int networkSource2 = ((IPv4)((Ethernet)icmpPacket2).getPayload()).getSourceAddress();
-     byte[] dataLayerDest2 = HexString.fromHexString("00:00:00:00:00:04");
-     int networkDest2 = IPv4.toIPv4Address("10.0.0.4");
-
-     deviceManager.learnEntity(Ethernet.toLong(dataLayerSource1),
-                               null, networkSource1,
-                               1L, 1);
-     deviceManager.learnEntity(Ethernet.toLong(dataLayerSource2),
-                               null, networkSource2,
-                               1L, 2);
-     deviceManager.learnEntity(Ethernet.toLong(dataLayerDest1),
-                               null, networkDest1,
-                               1L, 3);
-     deviceManager.learnEntity(Ethernet.toLong(dataLayerDest2),
-                               null, networkDest2,
-                               1L, 4);
-
-     // in bound #1
-     Route route1 = new Route(1L, 1L);
-     List<NodePortTuple> nptList1 = new ArrayList<NodePortTuple>();
-     nptList1.add(new NodePortTuple(1L, (short)1));
-     nptList1.add(new NodePortTuple(1L, (short)3));
-     route1.setPath(nptList1);
-     expect(routingEngine.getRoute(1L, (short)1, 1L, (short)3, 0)).andReturn(route1).atLeastOnce();
-
-     // outbound #1
-     Route route2 = new Route(1L, 1L);
-     List<NodePortTuple> nptList2 = new ArrayList<NodePortTuple>();
-     nptList2.add(new NodePortTuple(1L, (short)3));
-     nptList2.add(new NodePortTuple(1L, (short)1));
-     route2.setPath(nptList2);
-     expect(routingEngine.getRoute(1L, (short)3, 1L, (short)1, 0)).andReturn(route2).atLeastOnce();
-
-     // inbound #2
-     Route route3 = new Route(1L, 1L);
-     List<NodePortTuple> nptList3 = new ArrayList<NodePortTuple>();
-     nptList3.add(new NodePortTuple(1L, (short)2));
-     nptList3.add(new NodePortTuple(1L, (short)4));
-     route3.setPath(nptList3);
-     expect(routingEngine.getRoute(1L, (short)2, 1L, (short)4, 0)).andReturn(route3).atLeastOnce();
-
-     // outbound #2
-     Route route4 = new Route(1L, 1L);
-     List<NodePortTuple> nptList4 = new ArrayList<NodePortTuple>();
-     nptList4.add(new NodePortTuple(1L, (short)4));
-     nptList4.add(new NodePortTuple(1L, (short)2));
-     route4.setPath(nptList3);
-     expect(routingEngine.getRoute(1L, (short)4, 1L, (short)2, 0)).andReturn(route4).atLeastOnce();
-
-     replay(routingEngine);
-
-     wc1.reset();
-
-     IFloodlightProviderService.bcStore.put(cntx,
-                                            IFloodlightProviderService.CONTEXT_PI_PAYLOAD,
-                                            (Ethernet) icmpPacket1);
-     lb.receive(sw1, icmpPacketIn1, cntx);
-
-     IFloodlightProviderService.bcStore.put(cntx,
-                                            IFloodlightProviderService.CONTEXT_PI_PAYLOAD,
-                                            (Ethernet) icmpPacket2);
-     lb.receive(sw1, icmpPacketIn2, cntx);
-
-     assertTrue(wc1.hasCaptured());  // wc1 should get packetout
-
-     List<OFMessage> msglist2 = wc1.getValues();
-
-     assertTrue(msglist2.size()==2); // has inbound and outbound packetouts
-                                     // TODO: not seeing flowmods yet ...
-
-     Map<String, OFFlowMod> map = sfp.getFlows("00:00:00:00:00:00:00:01");
-
-     assertTrue(map.size()==4);
-    }
+	protected LoadBalancer lb;
+
+	protected FloodlightContext cntx;
+	protected FloodlightModuleContext fmc;
+	protected MockDeviceManager deviceManager;
+	protected MockThreadPoolService tps;
+	protected FlowReconcileManager frm;
+	protected DefaultEntityClassifier entityClassifier;
+	protected IRoutingService routingEngine;
+	protected ITopologyService topology;
+	protected StaticFlowEntryPusher sfp;
+	protected MemoryStorageSource storage;
+	protected RestApiServer restApi;
+	protected VipsResource vipsResource;
+	protected PoolsResource poolsResource;
+	protected MembersResource membersResource;
+	private MockSyncService mockSyncService;
+
+	protected LBVip vip1, vip2;
+	protected LBPool pool1, pool2, pool3;
+	protected LBMember member1, member2, member3, member4;
+
+	@Override
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+
+		lb = new LoadBalancer();
+
+		cntx = new FloodlightContext();
+		fmc = new FloodlightModuleContext();
+		entityClassifier = new DefaultEntityClassifier(); // dependency for device manager
+		frm = new FlowReconcileManager(); //dependency for device manager
+		tps = new MockThreadPoolService(); //dependency for device manager
+		deviceManager = new MockDeviceManager();
+		topology = createMock(ITopologyService.class);
+		routingEngine = createMock(IRoutingService.class);
+		restApi = new RestApiServer();
+		sfp = new StaticFlowEntryPusher();
+		storage = new MemoryStorageSource(); //dependency for sfp
+		mockSyncService = new MockSyncService();
+
+		fmc.addService(IRestApiService.class, restApi);
+		fmc.addService(IFloodlightProviderService.class, getMockFloodlightProvider());
+		fmc.addService(IEntityClassifierService.class, entityClassifier);
+		fmc.addService(IFlowReconcileService.class, frm);
+		fmc.addService(IThreadPoolService.class, tps);
+		fmc.addService(IDeviceService.class, deviceManager);
+		fmc.addService(ITopologyService.class, topology);
+		fmc.addService(IRoutingService.class, routingEngine);
+		fmc.addService(IStaticFlowEntryPusherService.class, sfp);
+		fmc.addService(ILoadBalancerService.class, lb);
+		fmc.addService(IStorageSourceService.class, storage);
+		fmc.addService(ISyncService.class, mockSyncService);
+
+		lb.init(fmc);
+		getMockFloodlightProvider().init(fmc);
+		entityClassifier.init(fmc);
+		frm.init(fmc);
+		tps.init(fmc);
+		mockSyncService.init(fmc);
+		deviceManager.init(fmc);
+		restApi.init(fmc);
+		sfp.init(fmc);
+		storage.init(fmc);
+
+		topology.addListener(deviceManager);
+		expectLastCall().times(1);
+		replay(topology);
+
+		lb.startUp(fmc);
+		getMockFloodlightProvider().startUp(fmc);
+		entityClassifier.startUp(fmc);
+		frm.startUp(fmc);
+		tps.startUp(fmc);
+		mockSyncService.startUp(fmc);
+		deviceManager.startUp(fmc);
+		restApi.startUp(fmc);
+		sfp.startUp(fmc);
+		storage.startUp(fmc);
+
+		verify(topology);
+
+		vipsResource = new VipsResource();
+		poolsResource = new PoolsResource();
+		membersResource = new MembersResource();
+
+		vip1=null;
+		vip2=null;
+
+		pool1=null;
+		pool2=null;
+		pool3=null;
+
+		member1=null;
+		member2=null;
+		member3=null;
+		member4=null;
+	}
+
+	@Test
+	public void testCreateVip() {
+		String postData1, postData2;
+		IOException error = null;
+
+		postData1 = "{\"id\":\"1\",\"name\":\"vip1\",\"protocol\":\"icmp\",\"address\":\"10.0.0.100\",\"port\":\"8\"}";
+		postData2 = "{\"id\":\"2\",\"name\":\"vip2\",\"protocol\":\"tcp\",\"address\":\"10.0.0.200\",\"port\":\"100\"}";
+
+		try {
+			vip1 = vipsResource.jsonToVip(postData1);
+		} catch (IOException e) {
+			error = e;
+		}
+		try {
+			vip2 = vipsResource.jsonToVip(postData2);
+		} catch (IOException e) {
+			error = e;
+		}
+
+		// verify correct parsing
+		assertFalse(vip1==null);
+		assertFalse(vip2==null);
+		assertTrue(error==null);
+
+		lb.createVip(vip1);
+		lb.createVip(vip2);
+
+		// verify correct creation
+		assertTrue(lb.vips.containsKey(vip1.id));
+		assertTrue(lb.vips.containsKey(vip2.id));
+	}
+
+	@Test
+	public void testRemoveVip() {
+
+		testCreateVip();
+
+		// verify correct initial condition
+		assertFalse(vip1==null);
+		assertFalse(vip2==null);
+
+		lb.removeVip(vip1.id);
+		lb.removeVip(vip2.id);
+
+		// verify correct removal
+		assertFalse(lb.vips.containsKey(vip1.id));
+		assertFalse(lb.vips.containsKey(vip2.id));
+
+	}
+
+	@Test
+	public void testCreatePool() {
+		String postData1, postData2, postData3;
+		IOException error = null;
+
+		testCreateVip();
+
+		postData1 = "{\"id\":\"1\",\"name\":\"pool1\",\"protocol\":\"icmp\",\"vip_id\":\"1\"}";
+		postData2 = "{\"id\":\"2\",\"name\":\"pool2\",\"protocol\":\"tcp\",\"vip_id\":\"2\"}";
+		postData3 = "{\"id\":\"3\",\"name\":\"pool3\",\"protocol\":\"udp\",\"vip_id\":\"3\"}";
+
+		try {
+			pool1 = poolsResource.jsonToPool(postData1);
+		} catch (IOException e) {
+			error = e;
+		}
+		try {
+			pool2 = poolsResource.jsonToPool(postData2);
+		} catch (IOException e) {
+			error = e;
+		}
+		try {
+			pool3 = poolsResource.jsonToPool(postData3);
+		} catch (IOException e) {
+			error = e;
+		}
+
+		// verify correct parsing
+		assertFalse(pool1==null);
+		assertFalse(pool2==null);
+		assertFalse(pool3==null);
+		assertTrue(error==null);
+
+		lb.createPool(pool1);
+		lb.createPool(pool2);
+		lb.createPool(pool3);
+
+		// verify successful creates; two registered with vips and one not
+		assertTrue(lb.pools.containsKey(pool1.id));
+		assertTrue(lb.vips.get(pool1.vipId).pools.contains(pool1.id));
+		assertTrue(lb.pools.containsKey(pool2.id));
+		assertTrue(lb.vips.get(pool2.vipId).pools.contains(pool2.id));
+		assertTrue(lb.pools.containsKey(pool3.id));
+		assertFalse(lb.vips.containsKey(pool3.vipId));
+
+	}
+
+	@Test
+	public void testRemovePool() {
+		testCreateVip();
+		testCreatePool();
+
+		// verify correct initial condition
+		assertFalse(vip1==null);
+		assertFalse(vip2==null);
+		assertFalse(pool1==null);
+		assertFalse(pool2==null);
+		assertFalse(pool3==null);
+
+		lb.removePool(pool1.id);
+		lb.removePool(pool2.id);
+		lb.removePool(pool3.id);
+
+		// verify correct removal
+		assertFalse(lb.pools.containsKey(pool1.id));
+		assertFalse(lb.pools.containsKey(pool2.id));
+		assertFalse(lb.pools.containsKey(pool3.id));
+
+		//verify pool cleanup from vip
+		assertFalse(lb.vips.get(pool1.vipId).pools.contains(pool1.id));
+		assertFalse(lb.vips.get(pool2.vipId).pools.contains(pool2.id));
+	}
+
+	@Test
+	public void testCreateMember() {
+		String postData1, postData2, postData3, postData4;
+		IOException error = null;
+
+		testCreateVip();
+		testCreatePool();
+
+		postData1 = "{\"id\":\"1\",\"address\":\"10.0.0.3\",\"port\":\"8\",\"pool_id\":\"1\"}";
+		postData2 = "{\"id\":\"2\",\"address\":\"10.0.0.4\",\"port\":\"8\",\"pool_id\":\"1\"}";
+		postData3 = "{\"id\":\"3\",\"address\":\"10.0.0.5\",\"port\":\"100\",\"pool_id\":\"2\"}";
+		postData4 = "{\"id\":\"4\",\"address\":\"10.0.0.6\",\"port\":\"100\",\"pool_id\":\"2\"}";
+
+		try {
+			member1 = membersResource.jsonToMember(postData1);
+		} catch (IOException e) {
+			error = e;
+		}
+		try {
+			member2 = membersResource.jsonToMember(postData2);
+		} catch (IOException e) {
+			error = e;
+		}
+		try {
+			member3 = membersResource.jsonToMember(postData3);
+		} catch (IOException e) {
+			error = e;
+		}
+		try {
+			member4 = membersResource.jsonToMember(postData4);
+		} catch (IOException e) {
+			error = e;
+		}
+
+		// verify correct parsing
+		assertFalse(member1==null);
+		assertFalse(member2==null);
+		assertFalse(member3==null);
+		assertFalse(member4==null);
+		assertTrue(error==null);
+
+		lb.createMember(member1);
+		lb.createMember(member2);
+		lb.createMember(member3);
+		lb.createMember(member4);
+
+		// add the same server a second time
+		lb.createMember(member1);
+
+		// verify successful creates
+		assertTrue(lb.members.containsKey(member1.id));
+		assertTrue(lb.members.containsKey(member2.id));
+		assertTrue(lb.members.containsKey(member3.id));
+		assertTrue(lb.members.containsKey(member4.id));
+
+		assertTrue(lb.pools.get(member1.poolId).members.size()==2);
+		assertTrue(lb.pools.get(member3.poolId).members.size()==2);
+
+		// member1 should inherit valid vipId from pool
+		assertTrue(lb.vips.get(member1.vipId)!=null);
+	}
+
+	@Test
+	public void testRemoveMember() {
+		testCreateVip();
+		testCreatePool();
+		testCreateMember();
+
+		// verify correct initial condition
+		assertFalse(vip1==null);
+		assertFalse(vip2==null);
+		assertFalse(pool1==null);
+		assertFalse(pool2==null);
+		assertFalse(pool3==null);
+		assertFalse(member1==null);
+		assertFalse(member2==null);
+		assertFalse(member3==null);
+		assertFalse(member4==null);
+
+		lb.removeMember(member1.id);
+		lb.removeMember(member2.id);
+		lb.removeMember(member3.id);
+		lb.removeMember(member4.id);
+
+		// verify correct removal
+		assertFalse(lb.members.containsKey(member1.id));
+		assertFalse(lb.members.containsKey(member2.id));
+		assertFalse(lb.members.containsKey(member3.id));
+		assertFalse(lb.members.containsKey(member4.id));
+
+		//verify member cleanup from pool
+		assertFalse(lb.pools.get(member1.poolId).members.contains(member1.id));
+		assertFalse(lb.pools.get(member2.poolId).members.contains(member2.id));
+		assertFalse(lb.pools.get(member3.poolId).members.contains(member3.id));
+		assertFalse(lb.pools.get(member4.poolId).members.contains(member4.id));
+
+	}
+
+	@Test
+	public void testTwoSubsequentIcmpRequests() throws Exception {
+		testCreateVip();
+		testCreatePool();
+		testCreateMember();
+
+		IOFSwitch sw1;
+
+		IPacket arpRequest1, arpReply1, icmpPacket1, icmpPacket2;
+
+		byte[] arpRequest1Serialized;
+		byte[] arpReply1Serialized;
+		byte[] icmpPacket1Serialized, icmpPacket2Serialized;
+
+		OFPacketIn arpRequestPacketIn1;
+		OFPacketIn icmpPacketIn1, icmpPacketIn2;
+
+		OFPacketOut arpReplyPacketOut1;
+
+		Capture<OFMessage> wc1 = new Capture<OFMessage>(CaptureType.ALL);
+
+		sw1 = EasyMock.createNiceMock(IOFSwitch.class);
+		expect(sw1.getId()).andReturn(DatapathId.of(1L)).anyTimes();
+		expect(sw1.getId().toString()).andReturn("00:00:00:00:00:01").anyTimes();
+		expect(sw1.hasAttribute(IOFSwitch.PROP_SUPPORTS_OFPP_TABLE)).andReturn(true).anyTimes();
+		sw1.write(capture(wc1));
+		expectLastCall().anyTimes();
+		sw1.flush();
+		expectLastCall().anyTimes();
+
+		replay(sw1);
+		sfp.switchAdded(DatapathId.of(1L));
+		verify(sw1);
+
+		/* Test plan:
+		 * - two clients and two servers on sw1 port 1, 2, 3, 4
+		 * - mock arp request received towards vip1 from (1L, 1)
+		 * - proxy arp got pushed out to (1L, 1)- check sw1 getting the packetout
+		 * - mock icmp request received towards vip1 from (1L, 1)
+		 * - device manager list of devices queried to identify source and dest devices
+		 * - routing engine queried to get inbound and outbound routes
+		 * - check getRoute calls and responses
+		 * - sfp called to install flows
+		 * - check sfp calls
+		 */
+
+		// Build topology
+		reset(topology);
+		expect(topology.isIncomingBroadcastAllowed(DatapathId.of(anyLong()), OFPort.of(anyShort()))).andReturn(true).anyTimes();
+		expect(topology.getL2DomainId(DatapathId.of(1L))).andReturn(DatapathId.of(1L)).anyTimes();
+		expect(topology.isAttachmentPointPort(DatapathId.of(1L), OFPort.of(1))).andReturn(true).anyTimes();
+		expect(topology.isAttachmentPointPort(DatapathId.of(1L), OFPort.of(2))).andReturn(true).anyTimes();
+		expect(topology.isAttachmentPointPort(DatapathId.of(1L), OFPort.of(3))).andReturn(true).anyTimes();
+		expect(topology.isAttachmentPointPort(DatapathId.of(1L), OFPort.of(4))).andReturn(true).anyTimes();
+		replay(topology);
+
+
+
+		// Build arp packets
+		arpRequest1 = new Ethernet()
+		.setSourceMACAddress("00:00:00:00:00:01")
+		.setDestinationMACAddress("ff:ff:ff:ff:ff:ff")
+		.setEtherType(Ethernet.TYPE_ARP)
+		.setVlanID((short) 0)
+		.setPriorityCode((byte) 0)
+		.setPayload(
+				new ARP()
+				.setHardwareType(ARP.HW_TYPE_ETHERNET)
+				.setProtocolType(ARP.PROTO_TYPE_IP)
+				.setHardwareAddressLength((byte) 6)
+				.setProtocolAddressLength((byte) 4)
+				.setOpCode(ARP.OP_REQUEST)
+				.setSenderHardwareAddress(HexString.fromHexString("00:00:00:00:00:01"))
+				.setSenderProtocolAddress(IPv4.toIPv4AddressBytes("10.0.0.1"))
+				.setTargetHardwareAddress(HexString.fromHexString("00:00:00:00:00:00"))
+				.setTargetProtocolAddress(IPv4.toIPv4AddressBytes("10.0.0.100")));
+
+		arpRequest1Serialized = arpRequest1.serialize();
+
+		arpRequestPacketIn1 = OFFactories.getFactory(OFVersion.OF_13).buildPacketIn()
+				.setBufferId(OFBufferId.NO_BUFFER)
+				.setInPort(OFPort.of(1))
+				.setData(arpRequest1Serialized)
+				.setReason(OFPacketInReason.NO_MATCH)
+				.build();
+
+		IFloodlightProviderService.bcStore.put(cntx,
+				IFloodlightProviderService.CONTEXT_PI_PAYLOAD,
+				(Ethernet) arpRequest1);
+
+		// Mock proxy arp packet-out
+		arpReply1 = new Ethernet()
+		.setSourceMACAddress(LBVip.LB_PROXY_MAC)
+		.setDestinationMACAddress(HexString.fromHexString("00:00:00:00:00:01"))
+		.setEtherType(Ethernet.TYPE_ARP)
+		.setVlanID((short) 0)
+		.setPriorityCode((byte) 0)
+		.setPayload(
+				new ARP()
+				.setHardwareType(ARP.HW_TYPE_ETHERNET)
+				.setProtocolType(ARP.PROTO_TYPE_IP)
+				.setHardwareAddressLength((byte) 6)
+				.setProtocolAddressLength((byte) 4)
+				.setOpCode(ARP.OP_REPLY)
+				.setSenderHardwareAddress(HexString.fromHexString(LBVip.LB_PROXY_MAC))
+				.setSenderProtocolAddress(IPv4.toIPv4AddressBytes("10.0.0.100"))
+				.setTargetHardwareAddress(HexString.fromHexString("00:00:00:00:00:01"))
+				.setTargetProtocolAddress(IPv4.toIPv4AddressBytes("10.0.0.1")));
+
+		arpReply1Serialized = arpReply1.serialize();
+
+		List<OFAction> poactions = new ArrayList<OFAction>();
+		poactions.add(OFFactories.getFactory(OFVersion.OF_13).actions().output(arpRequestPacketIn1.getInPort(), (short) 0xffff));
+		arpReplyPacketOut1 = OFFactories.getFactory(OFVersion.OF_13).buildPacketOut()
+				.setBufferId(OFBufferId.NO_BUFFER)
+				.setInPort(OFPort.ANY)
+				.setActions(poactions)
+				.setData(arpReply1Serialized)
+				.build();
+
+		lb.receive(sw1, arpRequestPacketIn1, cntx);
+		verify(sw1, topology);
+
+		assertTrue(wc1.hasCaptured());  // wc1 should get packetout
+
+		List<OFMessage> msglist1 = wc1.getValues();
+
+		for (OFMessage m: msglist1) {
+			if (m instanceof OFPacketOut)
+				assertEquals(arpReplyPacketOut1, m);
+			else
+				assertTrue(false); // unexpected message
+		}
+
+		//
+		// Skip arpRequest2 test - in reality this will happen, but for unit test the same logic
+		// is already validated with arpRequest1 test above
+		//
+
+		// Build icmp packets
+		icmpPacket1 = new Ethernet()
+		.setSourceMACAddress("00:00:00:00:00:01")
+		.setDestinationMACAddress(LBVip.LB_PROXY_MAC)
+		.setEtherType(Ethernet.TYPE_IPv4)
+		.setVlanID((short) 0)
+		.setPriorityCode((byte) 0)
+		.setPayload(
+				new IPv4()
+				.setSourceAddress("10.0.0.1")
+				.setDestinationAddress("10.0.0.100")
+				.setProtocol(IpProtocol.ICMP)
+				.setPayload(new ICMP()
+				.setIcmpCode((byte) 0)
+				.setIcmpType((byte) 0)));
+
+		icmpPacket1Serialized = icmpPacket1.serialize();
+
+		icmpPacketIn1 = OFFactories.getFactory(OFVersion.OF_13).buildPacketIn()
+				.setBufferId(OFBufferId.NO_BUFFER)
+				.setInPort(OFPort.of(1))
+				.setData(icmpPacket1Serialized)
+				.setReason(OFPacketInReason.NO_MATCH)
+				.build();
+		icmpPacket2 = new Ethernet()
+		.setSourceMACAddress("00:00:00:00:00:02")
+		.setDestinationMACAddress(LBVip.LB_PROXY_MAC)
+		.setEtherType(Ethernet.TYPE_IPv4)
+		.setVlanID((short) 0)
+		.setPriorityCode((byte) 0)
+		.setPayload(
+				new IPv4()
+				.setSourceAddress("10.0.0.2")
+				.setDestinationAddress("10.0.0.100")
+				.setProtocol(IpProtocol.ICMP)
+				.setPayload(new ICMP()
+				.setIcmpCode((byte) 0)
+				.setIcmpType((byte) 0)));
+
+		icmpPacket2Serialized = icmpPacket2.serialize();
+
+		icmpPacketIn2 = OFFactories.getFactory(OFVersion.OF_13).buildPacketIn()
+				.setBufferId(OFBufferId.NO_BUFFER)
+				.setInPort(OFPort.of(2))
+				.setData(icmpPacket2Serialized)
+				.setReason(OFPacketInReason.NO_MATCH)
+				.build();
+		MacAddress dataLayerSource1 = ((Ethernet)icmpPacket1).getSourceMACAddress();
+		IPv4Address networkSource1 = ((IPv4)((Ethernet)icmpPacket1).getPayload()).getSourceAddress();
+		MacAddress dataLayerDest1 = MacAddress.of("00:00:00:00:00:03");
+		IPv4Address networkDest1 = IPv4Address.of("10.0.0.3");
+		MacAddress dataLayerSource2 = ((Ethernet)icmpPacket2).getSourceMACAddress();
+		IPv4Address networkSource2 = ((IPv4)((Ethernet)icmpPacket2).getPayload()).getSourceAddress();
+		MacAddress dataLayerDest2 = MacAddress.of("00:00:00:00:00:04");
+		IPv4Address networkDest2 = IPv4Address.of("10.0.0.4");
+
+		deviceManager.learnEntity(dataLayerSource1.getLong(),
+				null, networkSource1.getInt(),
+				1L, 1);
+		deviceManager.learnEntity(dataLayerSource2.getLong(),
+				null, networkSource2.getInt(),
+				1L, 2);
+		deviceManager.learnEntity(dataLayerDest1.getLong(),
+				null, networkDest1.getInt(),
+				1L, 3);
+		deviceManager.learnEntity(dataLayerDest2.getLong(),
+				null, networkDest2.getInt(),
+				1L, 4);
+
+		// in bound #1
+		Route route1 = new Route(DatapathId.of(1L), DatapathId.of(1L));
+		List<NodePortTuple> nptList1 = new ArrayList<NodePortTuple>();
+		nptList1.add(new NodePortTuple(DatapathId.of(1L), OFPort.of(1)));
+		nptList1.add(new NodePortTuple(DatapathId.of(1L), OFPort.of(3)));
+		route1.setPath(nptList1);
+		expect(routingEngine.getRoute(DatapathId.of(1L), OFPort.of(1), DatapathId.of(1L), OFPort.of(3), U64.of(0))).andReturn(route1).atLeastOnce();
+
+		// outbound #1
+		Route route2 = new Route(DatapathId.of(1L), DatapathId.of(1L));
+		List<NodePortTuple> nptList2 = new ArrayList<NodePortTuple>();
+		nptList2.add(new NodePortTuple(DatapathId.of(1L), OFPort.of(3)));
+		nptList2.add(new NodePortTuple(DatapathId.of(1L), OFPort.of(1)));
+		route2.setPath(nptList2);
+		expect(routingEngine.getRoute(DatapathId.of(1L), OFPort.of(3), DatapathId.of(1L), OFPort.of(1), U64.of(0))).andReturn(route2).atLeastOnce();
+
+		// inbound #2
+		Route route3 = new Route(DatapathId.of(1L), DatapathId.of(1L));
+		List<NodePortTuple> nptList3 = new ArrayList<NodePortTuple>();
+		nptList3.add(new NodePortTuple(DatapathId.of(1L), OFPort.of(2)));
+		nptList3.add(new NodePortTuple(DatapathId.of(1L), OFPort.of(4)));
+		route3.setPath(nptList3);
+		expect(routingEngine.getRoute(DatapathId.of(1L), OFPort.of(2), DatapathId.of(1L), OFPort.of(4), U64.of(0))).andReturn(route3).atLeastOnce();
+
+		// outbound #2
+		Route route4 = new Route(DatapathId.of(1L), DatapathId.of(1L));
+		List<NodePortTuple> nptList4 = new ArrayList<NodePortTuple>();
+		nptList4.add(new NodePortTuple(DatapathId.of(1L), OFPort.of(4)));
+		nptList4.add(new NodePortTuple(DatapathId.of(1L), OFPort.of(2)));
+		route4.setPath(nptList3);
+		expect(routingEngine.getRoute(DatapathId.of(1L), OFPort.of(4), DatapathId.of(1L), OFPort.of(2), U64.of(0))).andReturn(route4).atLeastOnce();
+
+		replay(routingEngine);
+
+		wc1.reset();
+
+		IFloodlightProviderService.bcStore.put(cntx,
+				IFloodlightProviderService.CONTEXT_PI_PAYLOAD,
+				(Ethernet) icmpPacket1);
+		lb.receive(sw1, icmpPacketIn1, cntx);
+
+		IFloodlightProviderService.bcStore.put(cntx,
+				IFloodlightProviderService.CONTEXT_PI_PAYLOAD,
+				(Ethernet) icmpPacket2);
+		lb.receive(sw1, icmpPacketIn2, cntx);
+
+		assertTrue(wc1.hasCaptured());  // wc1 should get packetout
+
+		List<OFMessage> msglist2 = wc1.getValues();
+
+		assertTrue(msglist2.size()==2); // has inbound and outbound packetouts
+		// TODO: not seeing flowmods yet ...
+
+		Map<String, OFFlowMod> map = sfp.getFlows(DatapathId.of(1L));
+
+		assertTrue(map.size()==4);
+	}
 
 
 }
diff --git a/src/test/java/net/floodlightcontroller/packet/IPv4Test.java b/src/test/java/net/floodlightcontroller/packet/IPv4Test.java
index 9aa9e3d1093e197d4536f2cc08a475da7ed70ad2..c69de687700b402f653fc4a67e4b7b613e22a25a 100644
--- a/src/test/java/net/floodlightcontroller/packet/IPv4Test.java
+++ b/src/test/java/net/floodlightcontroller/packet/IPv4Test.java
@@ -27,6 +27,7 @@ import java.util.Arrays;
 
 import org.junit.Assert;
 import org.junit.Test;
+import org.projectfloodlight.openflow.types.IpProtocol;
 
 /**
  * @author David Erickson (daviderickson@cs.stanford.edu)
@@ -62,7 +63,7 @@ public class IPv4Test {
         IPv4 packet = new IPv4()
             .setIdentification((short) 24142)
             .setTtl((byte) 63)
-            .setProtocol((byte) 0x06)
+            .setProtocol(IpProtocol.of((byte) 0x06))
             .setSourceAddress("172.24.74.223")
             .setDestinationAddress("171.64.74.48");
         byte[] actual = packet.serialize();
diff --git a/src/test/java/net/floodlightcontroller/packet/PacketTest.java b/src/test/java/net/floodlightcontroller/packet/PacketTest.java
index c5a1bb2274b51e48a1ce5801e439d73a10b86232..609feb0f0efb6df5725d4ba19cccef49959310b4 100644
--- a/src/test/java/net/floodlightcontroller/packet/PacketTest.java
+++ b/src/test/java/net/floodlightcontroller/packet/PacketTest.java
@@ -116,8 +116,8 @@ public class PacketTest {
             Ethernet eth = (Ethernet)pkt;
             Ethernet newEth = (Ethernet)newPkt;
             newEth.setDestinationMACAddress(new byte[] { 1,2,3,4,5,6});
-            assertEquals(false, newEth.getDestinationMAC()
-                                .equals(eth.getDestinationMAC()));
+            assertEquals(false, newEth.getDestinationMACAddress()
+                                .equals(eth.getDestinationMACAddress()));
             assertEquals(false, newPkt.equals(pkt));
         }
         if (pkt instanceof ARP) {
diff --git a/src/test/java/net/floodlightcontroller/routing/RouteTest.java b/src/test/java/net/floodlightcontroller/routing/RouteTest.java
index 3bd0398980078d54d8275f721eb6ace1912045e2..40b32e3d4dd903481a37d62c1559556afe451495 100644
--- a/src/test/java/net/floodlightcontroller/routing/RouteTest.java
+++ b/src/test/java/net/floodlightcontroller/routing/RouteTest.java
@@ -17,7 +17,11 @@
 
 package net.floodlightcontroller.routing;
 
+import static org.junit.Assert.*;
+
 import org.junit.Test;
+import org.projectfloodlight.openflow.types.DatapathId;
+import org.projectfloodlight.openflow.types.OFPort;
 
 import net.floodlightcontroller.routing.Route;
 import net.floodlightcontroller.test.FloodlightTestCase;
@@ -30,22 +34,22 @@ import net.floodlightcontroller.topology.NodePortTuple;
 public class RouteTest extends FloodlightTestCase {
     @Test
     public void testCloneable() throws Exception {
-        Route r1 = new Route(1L, 2L);
-        Route r2 = new Route(1L, 3L);
+        Route r1 = new Route(DatapathId.of(1L), DatapathId.of(2L));
+        Route r2 = new Route(DatapathId.of(1L), DatapathId.of(3L));
 
         assertNotSame(r1, r2);
         assertNotSame(r1.getId(), r2.getId());
 
-        r1 = new Route(1L, 3L);
-        r1.getPath().add(new NodePortTuple(1L, (short)1));
-        r1.getPath().add(new NodePortTuple(2L, (short)1));
-        r1.getPath().add(new NodePortTuple(2L, (short)2));
-        r1.getPath().add(new NodePortTuple(3L, (short)1));
+        r1 = new Route(DatapathId.of(1L), DatapathId.of(3L));
+        r1.getPath().add(new NodePortTuple(DatapathId.of(1L), OFPort.of((short)1)));
+        r1.getPath().add(new NodePortTuple(DatapathId.of(2L), OFPort.of((short)1)));
+        r1.getPath().add(new NodePortTuple(DatapathId.of(2L), OFPort.of((short)2)));
+        r1.getPath().add(new NodePortTuple(DatapathId.of(3L), OFPort.of((short)1)));
 
-        r2.getPath().add(new NodePortTuple(1L, (short)1));
-        r2.getPath().add(new NodePortTuple(2L, (short)1));
-        r2.getPath().add(new NodePortTuple(2L, (short)2));
-        r2.getPath().add(new NodePortTuple(3L, (short)1));
+        r2.getPath().add(new NodePortTuple(DatapathId.of(1L), OFPort.of((short)1)));
+        r2.getPath().add(new NodePortTuple(DatapathId.of(2L), OFPort.of((short)1)));
+        r2.getPath().add(new NodePortTuple(DatapathId.of(2L), OFPort.of((short)2)));
+        r2.getPath().add(new NodePortTuple(DatapathId.of(3L), OFPort.of((short)1)));
 
         assertEquals(r1, r2);
 
@@ -56,7 +60,7 @@ public class RouteTest extends FloodlightTestCase {
         assertEquals(r1, r2);
 
         r2.getPath().remove(1);
-        temp = new NodePortTuple(2L, (short)5);
+        temp = new NodePortTuple(DatapathId.of(2L), OFPort.of((short)5));
         r2.getPath().add(1, temp);
         assertNotSame(r1, r2);
     }
diff --git a/src/test/java/net/floodlightcontroller/staticflowentry/StaticFlowTests.java b/src/test/java/net/floodlightcontroller/staticflowentry/StaticFlowTests.java
index a1e33539ebcb2b7099740fd62d1116fd7364b782..cf73d87a60e9415ee71f8175333d57ac8c758ef6 100644
--- a/src/test/java/net/floodlightcontroller/staticflowentry/StaticFlowTests.java
+++ b/src/test/java/net/floodlightcontroller/staticflowentry/StaticFlowTests.java
@@ -24,19 +24,20 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-
 import org.easymock.Capture;
 import org.easymock.CaptureType;
 import org.junit.Test;
-import org.openflow.protocol.OFFlowMod;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPort;
-import org.openflow.protocol.action.OFAction;
-import org.openflow.protocol.action.OFActionOutput;
-import org.openflow.protocol.action.OFActionStripVirtualLan;
-import org.openflow.util.HexString;
-
+import org.projectfloodlight.openflow.protocol.OFFactories;
+import org.projectfloodlight.openflow.protocol.OFFactory;
+import org.projectfloodlight.openflow.protocol.OFFlowMod;
+import org.projectfloodlight.openflow.protocol.OFVersion;
+import org.projectfloodlight.openflow.protocol.match.Match;
+import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.types.DatapathId;
+import org.projectfloodlight.openflow.types.OFBufferId;
+import org.projectfloodlight.openflow.types.OFPort;
+import org.projectfloodlight.openflow.protocol.action.OFAction;
+import org.projectfloodlight.openflow.util.HexString;
 
 import net.floodlightcontroller.core.FloodlightContext;
 import net.floodlightcontroller.core.IFloodlightProviderService;
@@ -44,6 +45,8 @@ import net.floodlightcontroller.core.IOFSwitch;
 import net.floodlightcontroller.core.module.FloodlightModuleContext;
 import net.floodlightcontroller.core.test.MockFloodlightProvider;
 import net.floodlightcontroller.test.FloodlightTestCase;
+import net.floodlightcontroller.util.FlowModUtils;
+import net.floodlightcontroller.util.MatchUtils;
 import net.floodlightcontroller.restserver.IRestApiService;
 import net.floodlightcontroller.restserver.RestApiServer;
 import net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher;
@@ -51,11 +54,14 @@ import net.floodlightcontroller.storage.IStorageSourceService;
 import net.floodlightcontroller.storage.memory.MemoryStorageSource;
 import static net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher.*;
 import static org.easymock.EasyMock.*;
+import static org.junit.Assert.*;
 
 public class StaticFlowTests extends FloodlightTestCase {
 
     static String TestSwitch1DPID = "00:00:00:00:00:00:00:01";
     static int TotalTestRules = 3;
+    
+    static OFFactory factory = OFFactories.getFactory(OFVersion.OF_13);
 
     /***
      * Create TestRuleXXX and the corresponding FlowModXXX
@@ -64,51 +70,50 @@ public class StaticFlowTests extends FloodlightTestCase {
     static Map<String,Object> TestRule1;
     static OFFlowMod FlowMod1;
     static {
-        FlowMod1 = new OFFlowMod();
+        FlowMod1 = factory.buildFlowModify().build();
         TestRule1 = new HashMap<String,Object>();
         TestRule1.put(COLUMN_NAME, "TestRule1");
         TestRule1.put(COLUMN_SWITCH, TestSwitch1DPID);
         // setup match
-        OFMatch match = new OFMatch();
+        Match match;
         TestRule1.put(COLUMN_DL_DST, "00:20:30:40:50:60");
-        match.fromString("dl_dst=00:20:30:40:50:60");
+        match = MatchUtils.fromString("dl_dst=00:20:30:40:50:60", factory.getVersion());
         // setup actions
         List<OFAction> actions = new LinkedList<OFAction>();
         TestRule1.put(COLUMN_ACTIONS, "output=1");
-        actions.add(new OFActionOutput((short)1, Short.MAX_VALUE));
+        actions.add(factory.actions().output(OFPort.of(1), Integer.MAX_VALUE));
         // done
-        FlowMod1.setMatch(match);
-        FlowMod1.setActions(actions);
-        FlowMod1.setBufferId(-1);
-        FlowMod1.setOutPort(OFPort.OFPP_NONE.getValue());
-        FlowMod1.setPriority(Short.MAX_VALUE);
-        FlowMod1.setLengthU(OFFlowMod.MINIMUM_LENGTH + 8);  // 8 bytes of actions
+        FlowMod1 = FlowMod1.createBuilder().setMatch(match)
+        .setActions(actions)
+        .setBufferId(OFBufferId.NO_BUFFER)
+        .setOutPort(OFPort.ANY)
+        .setPriority(Short.MAX_VALUE)
+        .build();
     }
 
     static Map<String,Object> TestRule2;
     static OFFlowMod FlowMod2;
 
     static {
-        FlowMod2 = new OFFlowMod();
+        FlowMod2 = factory.buildFlowModify().build();
         TestRule2 = new HashMap<String,Object>();
         TestRule2.put(COLUMN_NAME, "TestRule2");
         TestRule2.put(COLUMN_SWITCH, TestSwitch1DPID);
         // setup match
-        OFMatch match = new OFMatch();
+        Match match;        
         TestRule2.put(COLUMN_NW_DST, "192.168.1.0/24");
-        match.fromString("nw_dst=192.168.1.0/24");
+        match = MatchUtils.fromString("nw_dst=192.168.1.0/24", factory.getVersion());
         // setup actions
         List<OFAction> actions = new LinkedList<OFAction>();
         TestRule2.put(COLUMN_ACTIONS, "output=1");
-        actions.add(new OFActionOutput((short)1, Short.MAX_VALUE));
+        actions.add(factory.actions().output(OFPort.of(1), Integer.MAX_VALUE));
         // done
-        FlowMod2.setMatch(match);
-        FlowMod2.setActions(actions);
-        FlowMod2.setBufferId(-1);
-        FlowMod2.setOutPort(OFPort.OFPP_NONE.getValue());
-        FlowMod2.setPriority(Short.MAX_VALUE);
-        FlowMod2.setLengthU(OFFlowMod.MINIMUM_LENGTH + 8);  // 8 bytes of actions
-
+        FlowMod2 = FlowMod2.createBuilder().setMatch(match)
+                .setActions(actions)
+                .setBufferId(OFBufferId.NO_BUFFER)
+                .setOutPort(OFPort.ANY)
+                .setPriority(Short.MAX_VALUE)
+                .build();
     }
 
 
@@ -122,35 +127,33 @@ public class StaticFlowTests extends FloodlightTestCase {
     private long dpid;
     private IStorageSourceService storage;
     static {
-        FlowMod3 = new OFFlowMod();
+        FlowMod3 = factory.buildFlowModify().build();
         TestRule3 = new HashMap<String,Object>();
         TestRule3.put(COLUMN_NAME, "TestRule3");
         TestRule3.put(COLUMN_SWITCH, TestSwitch1DPID);
         // setup match
-        OFMatch match = new OFMatch();
+        Match match;
         TestRule3.put(COLUMN_DL_DST, "00:20:30:40:50:60");
         TestRule3.put(COLUMN_DL_VLAN, 4096);
-        match.fromString("dl_dst=00:20:30:40:50:60,dl_vlan=4096");
+        match = MatchUtils.fromString("dl_dst=00:20:30:40:50:60,dl_vlan=4096", factory.getVersion());
         // setup actions
         TestRule3.put(COLUMN_ACTIONS, "output=controller");
         List<OFAction> actions = new LinkedList<OFAction>();
-        actions.add(new OFActionOutput(OFPort.OFPP_CONTROLLER.getValue(), Short.MAX_VALUE));
+        actions.add(factory.actions().output(OFPort.CONTROLLER, Integer.MAX_VALUE));
         // done
-        FlowMod3.setMatch(match);
-        FlowMod3.setActions(actions);
-        FlowMod3.setBufferId(-1);
-        FlowMod3.setOutPort(OFPort.OFPP_NONE.getValue());
-        FlowMod3.setPriority(Short.MAX_VALUE);
-        FlowMod3.setLengthU(OFFlowMod.MINIMUM_LENGTH + 8);  // 8 bytes of actions
-
+        FlowMod3 = FlowMod3.createBuilder().setMatch(match)
+                .setActions(actions)
+                .setBufferId(OFBufferId.NO_BUFFER)
+                .setOutPort(OFPort.ANY)
+                .setPriority(Short.MAX_VALUE)
+                .build();
     }
 
-    private void verifyFlowMod(OFFlowMod testFlowMod,
-            OFFlowMod goodFlowMod) {
+    private void verifyFlowMod(OFFlowMod testFlowMod, OFFlowMod goodFlowMod) {
         verifyMatch(testFlowMod, goodFlowMod);
         verifyActions(testFlowMod, goodFlowMod);
         // dont' bother testing the cookie; just copy it over
-        goodFlowMod.setCookie(testFlowMod.getCookie());
+        goodFlowMod = goodFlowMod.createBuilder().setCookie(testFlowMod.getCookie()).build();
         // .. so we can continue to use .equals()
         assertEquals(goodFlowMod, testFlowMod);
     }
@@ -184,13 +187,12 @@ public class StaticFlowTests extends FloodlightTestCase {
 
         mockSwitch = createNiceMock(IOFSwitch.class);
         writeCapture = new Capture<OFMessage>(CaptureType.ALL);
-        contextCapture = new Capture<FloodlightContext>(CaptureType.ALL);
         writeCaptureList = new Capture<List<OFMessage>>(CaptureType.ALL);
 
         //OFMessageSafeOutStream mockOutStream = createNiceMock(OFMessageSafeOutStream.class);
-        mockSwitch.write(capture(writeCapture), capture(contextCapture));
+        mockSwitch.write(capture(writeCapture));
         expectLastCall().anyTimes();
-        mockSwitch.write(capture(writeCaptureList), capture(contextCapture));
+        mockSwitch.write(capture(writeCaptureList));
         expectLastCall().anyTimes();
         mockSwitch.flush();
         expectLastCall().anyTimes();
@@ -200,10 +202,10 @@ public class StaticFlowTests extends FloodlightTestCase {
         fmc.addService(IStorageSourceService.class, storage);
 
         MockFloodlightProvider mockFloodlightProvider = getMockFloodlightProvider();
-        Map<Long, IOFSwitch> switchMap = new HashMap<Long, IOFSwitch>();
-        switchMap.put(dpid, mockSwitch);
+        Map<DatapathId, IOFSwitch> switchMap = new HashMap<DatapathId, IOFSwitch>();
+        switchMap.put(DatapathId.of(dpid), mockSwitch);
         // NO ! expect(mockFloodlightProvider.getSwitches()).andReturn(switchMap).anyTimes();
-        mockFloodlightProvider.setSwitches(switchMap);
+        getMockSwitchService().setSwitches(switchMap);
         fmc.addService(IFloodlightProviderService.class, mockFloodlightProvider);
         RestApiServer restApi = new RestApiServer();
         fmc.addService(IRestApiService.class, restApi);
@@ -222,12 +224,12 @@ public class StaticFlowTests extends FloodlightTestCase {
         //expect(mockSwitch.getOutputStream()).andReturn(mockOutStream).anyTimes();
 
         // if someone calls getId(), return this dpid instead
-        expect(mockSwitch.getId()).andReturn(dpid).anyTimes();
-        expect(mockSwitch.getStringId()).andReturn(TestSwitch1DPID).anyTimes();
+        expect(mockSwitch.getId()).andReturn(DatapathId.of(dpid)).anyTimes();
+        expect(mockSwitch.getId()).andReturn(DatapathId.of(TestSwitch1DPID)).anyTimes();
         replay(mockSwitch);
 
         // hook the static pusher up to the fake switch
-        staticFlowEntryPusher.switchAdded(dpid);
+        staticFlowEntryPusher.switchAdded(DatapathId.of(dpid));
 
         verify(mockSwitch);
 
@@ -257,16 +259,16 @@ public class StaticFlowTests extends FloodlightTestCase {
         assertEquals(2, writeCapture.getValues().size());
 
         OFFlowMod firstDelete = (OFFlowMod) writeCapture.getValues().get(0);
-        FlowMod1.setCommand(OFFlowMod.OFPFC_DELETE_STRICT);
+        FlowMod1 = FlowModUtils.toFlowDeleteStrict(FlowMod1);
         verifyFlowMod(firstDelete, FlowMod1);
 
         OFFlowMod secondDelete = (OFFlowMod) writeCapture.getValues().get(1);
-        FlowMod2.setCommand(OFFlowMod.OFPFC_DELETE_STRICT);
+        FlowMod2 = FlowModUtils.toFlowDeleteStrict(FlowMod2);
         verifyFlowMod(secondDelete, FlowMod2);
 
         // add rules back to make sure that staticFlowPusher.rowsInserted() works
         writeCapture.reset();
-        FlowMod2.setCommand(OFFlowMod.OFPFC_ADD);
+        FlowMod2= FlowModUtils.toFlowAdd(FlowMod1);
         storage.insertRow(StaticFlowEntryPusher.TABLE_NAME, TestRule2);
         assertEquals(2, staticFlowEntryPusher.countEntries());
         assertEquals(1, writeCaptureList.getValues().size());
@@ -288,10 +290,10 @@ public class StaticFlowTests extends FloodlightTestCase {
         outList = writeCaptureList.getValues().get(0);
         assertEquals(2, outList.size());
         OFFlowMod removeFlowMod = (OFFlowMod) outList.get(0);
-        FlowMod3.setCommand(OFFlowMod.OFPFC_DELETE_STRICT);
+        FlowMod3 = FlowModUtils.toFlowDeleteStrict(FlowMod3);
         verifyFlowMod(removeFlowMod, FlowMod3);
-        FlowMod3.setCommand(OFFlowMod.OFPFC_ADD);
-        FlowMod3.getMatch().fromString("dl_dst=00:20:30:40:50:60,dl_vlan=333");
+        FlowMod3 = FlowModUtils.toFlowAdd(FlowMod3);
+        FlowMod3 = FlowMod3.createBuilder().setMatch(MatchUtils.fromString("dl_dst=00:20:30:40:50:60,dl_vlan=333", factory.getVersion())).build();
         OFFlowMod updateFlowMod = (OFFlowMod) outList.get(1);
         verifyFlowMod(updateFlowMod, FlowMod3);
         writeCaptureList.reset();
@@ -305,13 +307,11 @@ public class StaticFlowTests extends FloodlightTestCase {
         outList = writeCaptureList.getValues().get(0);
         assertEquals(1, outList.size());
         OFFlowMod modifyFlowMod = (OFFlowMod) outList.get(0);
-        FlowMod3.setCommand(OFFlowMod.OFPFC_MODIFY_STRICT);
+        FlowMod3 = FlowModUtils.toFlowModifyStrict(FlowMod3);
         List<OFAction> modifiedActions = FlowMod3.getActions();
-        modifiedActions.add(new OFActionStripVirtualLan()); // add the new action to what we should expect
-        FlowMod3.setActions(modifiedActions);
-        FlowMod3.setLengthU(OFFlowMod.MINIMUM_LENGTH + 16); // accommodate the addition of new actions
+        modifiedActions.add(factory.actions().stripVlan()); // add the new action to what we should expect
+        FlowMod3 = FlowMod3.createBuilder().setActions(modifiedActions).build();
         verifyFlowMod(modifyFlowMod, FlowMod3);
-
     }
 
 
diff --git a/src/test/java/net/floodlightcontroller/topology/TopologyInstanceTest.java b/src/test/java/net/floodlightcontroller/topology/TopologyInstanceTest.java
index 58d76fe4dc5bc7079a6e9ebce2f637931632dbb2..d05013cbc848f7056fd3542c776f51074570d94b 100644
--- a/src/test/java/net/floodlightcontroller/topology/TopologyInstanceTest.java
+++ b/src/test/java/net/floodlightcontroller/topology/TopologyInstanceTest.java
@@ -21,8 +21,8 @@ import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
-import static org.junit.Assert.*;
 
+import static org.junit.Assert.*;
 import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.module.FloodlightModuleContext;
 import net.floodlightcontroller.core.test.MockFloodlightProvider;
@@ -37,6 +37,8 @@ import net.floodlightcontroller.topology.TopologyManager;
 import org.easymock.EasyMock;
 import org.junit.Before;
 import org.junit.Test;
+import org.projectfloodlight.openflow.types.DatapathId;
+import org.projectfloodlight.openflow.types.OFPort;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -71,7 +73,7 @@ public class TopologyInstanceTest {
     }
 
     protected void verifyClusters(int[][] clusters, boolean tunnelsEnabled) {
-        List<Long> verifiedSwitches = new ArrayList<Long>();
+        List<DatapathId> verifiedSwitches = new ArrayList<DatapathId>();
 
         // Make sure the expected cluster arrays are sorted so we can
         // use binarySearch to test for membership
@@ -80,24 +82,24 @@ public class TopologyInstanceTest {
 
         TopologyInstance ti = 
                 topologyManager.getCurrentInstance(tunnelsEnabled);
-        Set<Long> switches = ti.getSwitches();
+        Set<DatapathId> switches = ti.getSwitches();
 
-        for (long sw: switches) {
+        for (DatapathId sw: switches) {
             if (!verifiedSwitches.contains(sw)) {
 
                 int[] expectedCluster = null;
 
                 for (int j = 0; j < clusters.length; j++) {
-                    if (Arrays.binarySearch(clusters[j], (int) sw) >= 0) {
+                    if (Arrays.binarySearch(clusters[j], (int)sw.getLong()) >= 0) {
                         expectedCluster = clusters[j];
                         break;
                     }
                 }
                 if (expectedCluster != null) {
-                    Set<Long> cluster = ti.getSwitchesInOpenflowDomain(sw);
+                    Set<DatapathId> cluster = ti.getSwitchesInOpenflowDomain(sw);
                     assertEquals(expectedCluster.length, cluster.size());
-                    for (long sw2: cluster) {
-                        assertTrue(Arrays.binarySearch(expectedCluster, (int)sw2) >= 0);
+                    for (DatapathId sw2: cluster) {
+                        assertTrue(Arrays.binarySearch(expectedCluster, (int)sw2.getLong()) >= 0);
                         verifiedSwitches.add(sw2);
                     }
                 }
@@ -119,7 +121,7 @@ public class TopologyInstanceTest {
             int [][] nptList = ebp[i];
             expected.clear();
             for(int j=0; j<nptList.length; ++j) {
-                npt = new NodePortTuple((long)nptList[j][0], (short)nptList[j][1]);
+                npt = new NodePortTuple(DatapathId.of(nptList[j][0]), OFPort.of(nptList[j][1]));
                 expected.add(npt);
             }
             TopologyInstance ti = topologyManager.getCurrentInstance(tunnelsEnabled);
@@ -145,7 +147,7 @@ public class TopologyInstanceTest {
             else if (r[4] == TUNNEL_LINK)
                 type = ILinkDiscovery.LinkType.TUNNEL;
 
-            topologyManager.addOrUpdateLink((long)r[0], (short)r[1], (long)r[2], (short)r[3], type);
+            topologyManager.addOrUpdateLink(DatapathId.of(r[0]), OFPort.of((short)r[1]), DatapathId.of(r[2]), OFPort.of((short)r[3]), type);
         }
         topologyManager.createNewInstance();
     }
@@ -258,8 +260,8 @@ public class TopologyInstanceTest {
 
         // Test 3. Remove links
         {
-            tm.removeLink((long)5,(short)3,(long)6,(short)1);
-            tm.removeLink((long)6,(short)1,(long)5,(short)3);
+            tm.removeLink(DatapathId.of(5), OFPort.of((short)3), DatapathId.of(6), OFPort.of((short)1));
+            tm.removeLink(DatapathId.of(6), OFPort.of((short)1), DatapathId.of(5), OFPort.of((short)3));
 
             int [][] expectedClusters = {
                                          {1,2,3,4,5},
@@ -270,7 +272,7 @@ public class TopologyInstanceTest {
 
         // Remove Switch
         {
-            tm.removeSwitch(4);
+            tm.removeSwitch(DatapathId.of(4));
             int [][] expectedClusters = {
                                          {1,2,3,5},
             };
diff --git a/src/test/java/net/floodlightcontroller/topology/TopologyManagerTest.java b/src/test/java/net/floodlightcontroller/topology/TopologyManagerTest.java
index b1027349cfc203a744a9cc18e828fe5d981064d1..2ff76ee513484b72b78e677b5dd689c84165410e 100644
--- a/src/test/java/net/floodlightcontroller/topology/TopologyManagerTest.java
+++ b/src/test/java/net/floodlightcontroller/topology/TopologyManagerTest.java
@@ -16,6 +16,7 @@
 
 package net.floodlightcontroller.topology;
 
+import static org.junit.Assert.*;
 import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.module.FloodlightModuleContext;
 import net.floodlightcontroller.core.test.MockThreadPoolService;
@@ -26,6 +27,8 @@ import net.floodlightcontroller.topology.TopologyManager;
 
 import org.junit.Before;
 import org.junit.Test;
+import org.projectfloodlight.openflow.types.DatapathId;
+import org.projectfloodlight.openflow.types.OFPort;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -50,7 +53,7 @@ public class TopologyManagerTest extends FloodlightTestCase {
 
     @Test
     public void testBasic1() throws Exception {
-        tm.addOrUpdateLink(1, (short)1, 2, (short)1, ILinkDiscovery.LinkType.DIRECT_LINK);
+        tm.addOrUpdateLink(DatapathId.of(1), OFPort.of((short)1), DatapathId.of(2), OFPort.of((short)1), ILinkDiscovery.LinkType.DIRECT_LINK);
         assertTrue(tm.getSwitchPorts().size() == 2);  // for two nodes.
         assertTrue(tm.getSwitchPorts().get((long)1).size()==1);
         assertTrue(tm.getSwitchPorts().get((long)2).size()==1);
@@ -58,7 +61,7 @@ public class TopologyManagerTest extends FloodlightTestCase {
         assertTrue(tm.getPortBroadcastDomainLinks().size()==0);
         assertTrue(tm.getTunnelPorts().size()==0);
 
-        tm.addOrUpdateLink(1, (short)2, 2, (short)2, ILinkDiscovery.LinkType.MULTIHOP_LINK);
+        tm.addOrUpdateLink(DatapathId.of(1), OFPort.of((short)2), DatapathId.of(2), OFPort.of((short)2), ILinkDiscovery.LinkType.MULTIHOP_LINK);
         assertTrue(tm.getSwitchPorts().size() == 2);  // for two nodes.
         assertTrue(tm.getSwitchPorts().get((long)1).size()==2);
         assertTrue(tm.getSwitchPorts().get((long)2).size()==2);
@@ -66,14 +69,14 @@ public class TopologyManagerTest extends FloodlightTestCase {
         assertTrue(tm.getPortBroadcastDomainLinks().size()==2);
         assertTrue(tm.getTunnelPorts().size()==0);
 
-        tm.removeLink(1, (short)2, 2, (short)2);
+        tm.removeLink(DatapathId.of(1), OFPort.of((short)2), DatapathId.of(2), OFPort.of((short)2));
         assertTrue(tm.getSwitchPorts().get((long)1).size()==1);
         assertTrue(tm.getSwitchPorts().get((long)2).size()==1);
         assertTrue(tm.getSwitchPorts().size() == 2);
         assertTrue(tm.getSwitchPortLinks().size()==2);
         assertTrue(tm.getPortBroadcastDomainLinks().size()==0);
 
-        tm.removeLink(1, (short)1, 2, (short)1);
+        tm.removeLink(DatapathId.of(1), OFPort.of((short)1), DatapathId.of(2), OFPort.of((short)1));
         assertTrue(tm.getSwitchPorts().size() == 0);
         assertTrue(tm.getSwitchPortLinks().size()==0);
         assertTrue(tm.getPortBroadcastDomainLinks().size()==0);
@@ -81,8 +84,8 @@ public class TopologyManagerTest extends FloodlightTestCase {
 
     @Test
     public void testBasic2() throws Exception {
-        tm.addOrUpdateLink(1, (short)1, 2, (short)1, ILinkDiscovery.LinkType.DIRECT_LINK);
-        tm.addOrUpdateLink(2, (short)2, 3, (short)1, ILinkDiscovery.LinkType.MULTIHOP_LINK);
+        tm.addOrUpdateLink(DatapathId.of(1), OFPort.of((short)1), DatapathId.of(2), OFPort.of((short)1), ILinkDiscovery.LinkType.DIRECT_LINK);
+        tm.addOrUpdateLink(DatapathId.of(2), OFPort.of((short)2), DatapathId.of(3), OFPort.of((short)1), ILinkDiscovery.LinkType.MULTIHOP_LINK);
         assertTrue(tm.getSwitchPorts().size() == 3);  // for two nodes.
         assertTrue(tm.getSwitchPorts().get((long)1).size()==1);
         assertTrue(tm.getSwitchPorts().get((long)2).size()==2);
@@ -90,7 +93,7 @@ public class TopologyManagerTest extends FloodlightTestCase {
         assertTrue(tm.getSwitchPortLinks().size()==4);
         assertTrue(tm.getPortBroadcastDomainLinks().size()==2);
 
-        tm.removeLink(1, (short)1, 2, (short)1);
+        tm.removeLink(DatapathId.of(1), OFPort.of((short)1), DatapathId.of(2), OFPort.of((short)1));
         assertTrue(tm.getSwitchPorts().size() == 2);
         assertTrue(tm.getSwitchPorts().get((long)1) == null);
         assertTrue(tm.getSwitchPorts().get((long)2).size()==1);
@@ -99,7 +102,7 @@ public class TopologyManagerTest extends FloodlightTestCase {
         assertTrue(tm.getPortBroadcastDomainLinks().size()==2);
 
         // nonexistent link // no null pointer exceptions.
-        tm.removeLink(3, (short)1, 2, (short)2);
+        tm.removeLink(DatapathId.of(3), OFPort.of((short)1), DatapathId.of(2), OFPort.of((short)2));
         assertTrue(tm.getSwitchPorts().size() == 2);
         assertTrue(tm.getSwitchPorts().get((long)1) == null);
         assertTrue(tm.getSwitchPorts().get((long)2).size()==1);
@@ -107,7 +110,7 @@ public class TopologyManagerTest extends FloodlightTestCase {
         assertTrue(tm.getSwitchPortLinks().size()==2);
         assertTrue(tm.getPortBroadcastDomainLinks().size()==2);
 
-        tm.removeLink(3, (short)2, 1, (short)2);
+        tm.removeLink(DatapathId.of(3), OFPort.of((short)2), DatapathId.of(1), OFPort.of((short)2));
         assertTrue(tm.getSwitchPorts().size() == 2);
         assertTrue(tm.getSwitchPorts().get((long)1)==null);
         assertTrue(tm.getSwitchPorts().get((long)2).size()==1);
@@ -115,7 +118,7 @@ public class TopologyManagerTest extends FloodlightTestCase {
         assertTrue(tm.getSwitchPortLinks().size()==2);
         assertTrue(tm.getPortBroadcastDomainLinks().size()==2);
 
-        tm.removeLink(2, (short)2, 3, (short)1);
+        tm.removeLink(DatapathId.of(2), OFPort.of((short)2), DatapathId.of(3), OFPort.of((short)1));
         assertTrue(tm.getSwitchPorts().size() == 0);  // for two nodes.
         assertTrue(tm.getSwitchPortLinks().size()==0);
         assertTrue(tm.getPortBroadcastDomainLinks().size()==0);
diff --git a/src/test/java/net/floodlightcontroller/util/MACAddressTest.java b/src/test/java/net/floodlightcontroller/util/MACAddressTest.java
deleted file mode 100644
index 0846f691de0f753a268bf1611b23e0bd54a51ec8..0000000000000000000000000000000000000000
--- a/src/test/java/net/floodlightcontroller/util/MACAddressTest.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/**
- *    Copyright 2013, Big Switch Networks, Inc.
- *
- *    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
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- *    Unless required by applicable law or agreed to in writing, software
- *    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- *    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.floodlightcontroller.util;
-
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-/**
- * @author Sho Shimizu (sho.shimizu@gmail.com)
- */
-public class MACAddressTest {
-    @Test
-    public void testValueOf() {
-        MACAddress address = MACAddress.valueOf("00:01:02:03:04:05");
-        assertEquals(address,
-                MACAddress.valueOf(new byte[]{0x00, 0x01, 0x02, 0x03, 0x04, 0x05}));
-        assertEquals("00:01:02:03:04:05", address.toString());
-
-        address = MACAddress.valueOf("FF:FE:FD:10:20:30");
-        assertEquals(address,
-                MACAddress.valueOf(new byte[]{(byte) 0xFF, (byte) 0xFE, (byte) 0xFD, 0x10, 0x20, 0x30}));
-        assertEquals("FF:FE:FD:10:20:30", address.toString());
-        
-        address = MACAddress.valueOf("00:11:22:aa:bb:cc");
-        assertEquals(address,
-                MACAddress.valueOf(new byte[]{0x00, 0x11, 0x22, (byte)0xaa, (byte)0xbb, (byte)0xcc}));
-    }
-
-    @Test(expected=NumberFormatException.class)
-    public void testIllegalFormat() {
-        MACAddress.valueOf("0T:00:01:02:03:04");
-    }
-
-    @Test(expected=IllegalArgumentException.class)
-    public void testLongStringFields() {
-        MACAddress.valueOf("00:01:02:03:04:05:06");
-    }
-
-    @Test(expected=IllegalArgumentException.class)
-    public void testShortStringFields() {
-        MACAddress.valueOf("00:01:02:03:04");
-    }
-
-    @Test(expected=IllegalArgumentException.class)
-    public void testLongByteFields() {
-        MACAddress.valueOf(new byte[]{0x01, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06});
-    }
-
-    @Test(expected=IllegalArgumentException.class)
-    public void testShortByteField() {
-        MACAddress.valueOf(new byte[]{0x01, 0x01, 0x02, 0x03, 0x04});
-    }
-
-    //  Test data is imported from net.floodlightcontroller.packet.EthernetTest
-    @Test
-    public void testToLong() {
-        assertEquals(
-                281474976710655L,
-                MACAddress.valueOf(new byte[]{(byte) 0xff, (byte) 0xff,
-                        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff}).toLong());
-
-        assertEquals(
-                1103823438081L,
-                MACAddress.valueOf(new byte[] { (byte) 0x01, (byte) 0x01,
-                        (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01 }).toLong());
-
-        assertEquals(
-                141289400074368L,
-                MACAddress.valueOf(new byte[] { (byte) 0x80, (byte) 0x80,
-                        (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80 }).toLong());
-
-    }
-    
-    @Test
-    public void testIsBroadcast() {
-        assertTrue(MACAddress.valueOf("FF:FF:FF:FF:FF:FF").isBroadcast());
-        assertFalse(MACAddress.valueOf("11:22:33:44:55:66").isBroadcast());
-    }
-
-    @Test
-    public void testIsMulticast() {
-        assertTrue(MACAddress.valueOf("01:80:C2:00:00:00").isMulticast());
-        assertFalse(MACAddress.valueOf("FF:FF:FF:FF:FF:FF").isMulticast());
-        assertFalse(MACAddress.valueOf("11:22:33:44:55:66").isBroadcast());
-    }
-}
diff --git a/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java b/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java
index 547371cc0ba2e3694c2c810d8dd928f5f12059c0..75ee145acd13b24504e1766689715b067838b728 100644
--- a/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java
+++ b/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java
@@ -17,30 +17,47 @@
 package net.floodlightcontroller.util;
 
 import static org.junit.Assert.*;
+
 import java.io.IOException;
 import java.net.SocketAddress;
-
 import java.util.Collection;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.Future;
+
 import net.floodlightcontroller.core.FloodlightContext;
+import net.floodlightcontroller.core.IOFConnection;
 import net.floodlightcontroller.core.IOFMessageListener;
 import net.floodlightcontroller.core.IOFSwitch;
 import net.floodlightcontroller.core.HARole;
+import net.floodlightcontroller.core.LogicalOFMessageCategory;
+import net.floodlightcontroller.core.OFConnection;
+import net.floodlightcontroller.core.SwitchDescription;
 import net.floodlightcontroller.core.internal.Controller;
 import net.floodlightcontroller.debugcounter.IDebugCounterService;
 import net.floodlightcontroller.threadpool.IThreadPoolService;
 
 import org.jboss.netty.channel.Channel;
+import org.projectfloodlight.openflow.protocol.OFActionType;
+import org.projectfloodlight.openflow.protocol.OFCapabilities;
+import org.projectfloodlight.openflow.protocol.OFControllerRole;
+import org.projectfloodlight.openflow.protocol.OFFactory;
 import org.projectfloodlight.openflow.protocol.OFFeaturesReply;
 import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFPortDesc;
 import org.projectfloodlight.openflow.protocol.OFPortStatus;
+import org.projectfloodlight.openflow.protocol.OFRequest;
 import org.projectfloodlight.openflow.protocol.OFStatsReply;
 import org.projectfloodlight.openflow.protocol.OFStatsRequest;
 import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
 import org.projectfloodlight.openflow.protocol.OFDescStatsRequest;
+import org.projectfloodlight.openflow.types.DatapathId;
+import org.projectfloodlight.openflow.types.OFPort;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.util.concurrent.ListenableFuture;
 
 
 /**
@@ -95,86 +112,11 @@ public class OFMessageDamperMockSwitch implements IOFSwitch {
 
     //-------------------------------------------------------
     // IOFSwitch: mocked methods
-    @Override
-    public void write(OFMessage m, FloodlightContext bc) throws IOException {
-        assertNull("write() called but already have message", writtenMessage);
-        assertNull("write() called but already have context", writtenContext);
-        writtenContext = bc;
-        writtenMessage = m;
-    }
 
-    @Override
-    public void writeThrottled(OFMessage msg, FloodlightContext cntx)
-            throws IOException {
-        write(msg, cntx);
-    }
 
     //-------------------------------------------------------
     // IOFSwitch: not-implemented methods
 
-    @Override
-    public void writeThrottled(List<OFMessage> msglist, FloodlightContext bc)
-            throws IOException {
-        assertTrue("Unexpected method call", false);
-    }
-
-    @Override
-    public void write(List<OFMessage> msglist, FloodlightContext bc)
-            throws IOException {
-        assertTrue("Unexpected method call", false);
-    }
-
-    @Override
-    public void disconnectOutputStream() {
-        assertTrue("Unexpected method call", false);
-    }
-
-    @Override
-    public void setFeaturesReply(OFFeaturesReply featuresReply) {
-        assertTrue("Unexpected method call", false);
-    }
-
-    @Override
-    public void setSwitchProperties(OFDescriptionStatistics description) {
-        assertTrue("Unexpected method call", false);
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public Collection<ImmutablePort> getEnabledPorts() {
-        assertTrue("Unexpected method call", false);
-        return null;
-    }
-
-    @Override
-    public Collection<Short> getEnabledPortNumbers() {
-        assertTrue("Unexpected method call", false);
-        return null;
-    }
-
-    @Override
-    public ImmutablePort getPort(short portNumber) {
-        assertTrue("Unexpected method call", false);
-        return null;
-    }
-
-    @Override
-    public ImmutablePort getPort(String portName) {
-        assertTrue("Unexpected method call", false);
-        return null;
-    }
-
-    @Override
-    public Collection<ImmutablePort> getPorts() {
-        assertTrue("Unexpected method call", false);
-        return null;
-    }
-
-    @Override
-    public boolean portEnabled(short portName) {
-        assertTrue("Unexpected method call", false);
-        return false;
-    }
 
     @Override
     public boolean portEnabled(String portName) {
@@ -183,15 +125,9 @@ public class OFMessageDamperMockSwitch implements IOFSwitch {
     }
 
     @Override
-    public long getId() {
+    public DatapathId getId() {
         assertTrue("Unexpected method call", false);
-        return 0;
-    }
-
-    @Override
-    public String getStringId() {
-        assertTrue("Unexpected method call", false);
-        return null;
+        return DatapathId.NONE;
     }
 
     @Override
@@ -212,51 +148,12 @@ public class OFMessageDamperMockSwitch implements IOFSwitch {
         return null;
     }
 
-    @Override
-    public int getNextTransactionId() {
-        assertTrue("Unexpected method call", false);
-        return 0;
-    }
-
-    @Override
-    public Future<List<OFStatistics>>
-            queryStatistics(OFStatisticsRequest request) throws IOException {
-        assertTrue("Unexpected method call", false);
-        return null;
-    }
-
     @Override
     public boolean isConnected() {
         assertTrue("Unexpected method call", false);
         return false;
     }
 
-    @Override
-    public void setConnected(boolean connected) {
-        assertTrue("Unexpected method call", false);
-    }
-
-    @Override
-    public Role getHARole() {
-        assertTrue("Unexpected method call", false);
-        return null;
-    }
-
-    @Override
-    public void deliverStatisticsReply(OFStatisticsReply reply) {
-        assertTrue("Unexpected method call", false);
-    }
-
-    @Override
-    public void cancelStatisticsReply(int transactionId) {
-        assertTrue("Unexpected method call", false);
-    }
-
-    @Override
-    public void cancelAllStatisticsReplies() {
-        assertTrue("Unexpected method call", false);
-    }
-
     @Override
     public boolean hasAttribute(String name) {
         assertTrue("Unexpected method call", false);
@@ -280,108 +177,33 @@ public class OFMessageDamperMockSwitch implements IOFSwitch {
         return null;
     }
 
-    @Override
-    public void clearAllFlowMods() {
-        assertTrue("Unexpected method call", false);
-    }
-
-    @Override
-    public boolean updateBroadcastCache(Long entry, Short port) {
-        assertTrue("Unexpected method call", false);
-        return false;
-    }
-
-    @Override
-    public Map<Short, Long> getPortBroadcastHits() {
-        assertTrue("Unexpected method call", false);
-        return null;
-    }
-
-    @Override
-    public void sendStatsQuery(OFStatisticsRequest request, int xid,
-                               IOFMessageListener caller)
-                                                         throws IOException {
-        assertTrue("Unexpected method call", false);
-    }
-
     @Override
     public void flush() {
         assertTrue("Unexpected method call", false);
     }
 
     @Override
-    public Future<OFFeaturesReply> querySwitchFeaturesReply()
-            throws IOException {
-        fail("Unexpected method call");
-        return null;
-    }
-
-    @Override
-    public void deliverOFFeaturesReply(OFMessage reply) {
-        fail("Unexpected method call");
-    }
-
-    @Override
-    public void cancelFeaturesReply(int transactionId) {
-        fail("Unexpected method call");
-    }
-
-    @Override
-    public int getBuffers() {
-        fail("Unexpected method call");
-        return 0;
-    }
-
-    @Override
-    public int getActions() {
+    public long getBuffers() {
         fail("Unexpected method call");
         return 0;
     }
 
     @Override
-    public int getCapabilities() {
-        fail("Unexpected method call");
-        return 0;
-    }
-
-    @Override
-    public byte getTables() {
-        fail("Unexpected method call");
-        return 0;
-    }
-
-    @Override
-    public void setChannel(Channel channel) {
-        fail("Unexpected method call");
-    }
-
-    @Override
-    public void setFloodlightProvider(OLD__Controller controller) {
-        fail("Unexpected method call");
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void setThreadPoolService(IThreadPoolService threadPool) {
-        fail("Unexpected method call");
-    }
-
-    @Override
-    public void setHARole(Role role) {
+    public Set<OFActionType> getActions() {
         fail("Unexpected method call");
+        return null;
     }
 
     @Override
-    public OFPortType getPortType(short port_num) {
+    public Set<OFCapabilities> getCapabilities() {
         fail("Unexpected method call");
         return null;
     }
 
     @Override
-    public boolean isFastPort(short port_num) {
+    public short getTables() {
         fail("Unexpected method call");
-        return false;
+        return 0;
     }
 
     @Override
@@ -390,103 +212,147 @@ public class OFMessageDamperMockSwitch implements IOFSwitch {
         return false;
     }
 
-    @Override
-    public OFDescriptionStatistics getDescriptionStatistics() {
-        fail("Unexpected method call");
-        return null;
-    }
-
     @Override
     public boolean isActive() {
         fail("Unexpected method call");
         return false; // never reached
     }
 
-    @Override
-    public boolean inputThrottled(OFMessage ofm) {
-        fail("Unexpected method call");
-        return false;
-    }
-
-    @Override
-    public boolean isOverloaded() {
-        fail("Unexpected method call");
-        return false;
-    }
-
-    @Override
-    public boolean isWriteThrottleEnabled() {
-        fail("Unexpected method call");
-        return false;
-    }
-
-    @Override
-    public void setDebugCounterService(IDebugCounterService debugCounters) {
-        fail("Unexpected method call");
-    }
-
-    @Override
-    public OrderedCollection<PortChangeEvent>
-            processOFPortStatus(OFPortStatus ps) {
-        fail("Unexpected method call");
-        return null;
-    }
-
-    @Override
-    public OrderedCollection<PortChangeEvent>
-            comparePorts(Collection<ImmutablePort> ports) {
-        fail("Unexpected method call");
-        return null;
-    }
-
-    @Override
-    public OrderedCollection<PortChangeEvent>
-            setPorts(Collection<ImmutablePort> ports) {
-        fail("Unexpected method call");
-        return null;
-    }
-
-    @Override
-    public void setTableFull(boolean isFull) {
-        fail("Unexpected method call");
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setAccessFlowPriority(short prio) {
-        fail("Unexpected method call");
-    }
-
-    @Override
-    public void setCoreFlowPriority(short prio) {
-        fail("Unexpected method call");
-    }
-
-    @Override
-    public short getAccessFlowPriority() {
-        fail("Unexpected method call");
-        return 0;
-    }
-
-    @Override
-    public short getCoreFlowPriority() {
-        fail("Unexpected method call");
-        return 0;
-    }
-
-    @Override
-    public void startDriverHandshake() {
-        fail("Unexpected method call");
-    }
-
-    @Override
-    public boolean isDriverHandshakeComplete() {
-        fail("Unexpected method call");
-        return false;
-    }
-
-    @Override
-    public void processDriverHandshakeMessage(OFMessage m) {
-        fail("Unexpected method call");
-    }
+	@Override
+	public void write(OFMessage m) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public void write(Iterable<OFMessage> msglist) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public <R extends OFMessage> ListenableFuture<R> writeRequest(
+			OFRequest<R> request) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public <REPLY extends OFStatsReply> ListenableFuture<List<REPLY>> writeStatsRequest(
+			OFStatsRequest<REPLY> request) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public SwitchStatus getStatus() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public void disconnect() {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public SwitchDescription getSwitchDescription() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public OFPortDesc getPort(OFPort portNumber) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Collection<OFPortDesc> getSortedPorts() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public boolean portEnabled(OFPort portNumber) {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	@Override
+	public OFControllerRole getControllerRole() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public OFFactory getOFFactory() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public ImmutableList<IOFConnection> getConnections() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public void write(OFMessage m, LogicalOFMessageCategory category) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public void write(Iterable<OFMessage> msglist,
+			LogicalOFMessageCategory category) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public OFConnection getConnectionByCategory(
+			LogicalOFMessageCategory category) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public <REPLY extends OFStatsReply> ListenableFuture<List<REPLY>> writeStatsRequest(
+			OFStatsRequest<REPLY> request, LogicalOFMessageCategory category) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public <R extends OFMessage> ListenableFuture<R> writeRequest(
+			OFRequest<R> request, LogicalOFMessageCategory category) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Collection<OFPortDesc> getEnabledPorts() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Collection<OFPort> getEnabledPortNumbers() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public OFPortDesc getPort(String portName) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Collection<OFPortDesc> getPorts() {
+		// TODO Auto-generated method stub
+		return null;
+	}
 }
diff --git a/src/test/java/net/floodlightcontroller/util/OFMessageDamperTest.java b/src/test/java/net/floodlightcontroller/util/OFMessageDamperTest.java
index 84db817f747542c1d5b5ef3f04e2d0061657dd5f..acd32e1e60c5f0d7cfb2fe47c4c94c882d71b3dd 100644
--- a/src/test/java/net/floodlightcontroller/util/OFMessageDamperTest.java
+++ b/src/test/java/net/floodlightcontroller/util/OFMessageDamperTest.java
@@ -17,23 +17,23 @@
 package net.floodlightcontroller.util;
 
 import static org.junit.Assert.*;
-
 import net.floodlightcontroller.core.FloodlightContext;
 
 import org.junit.Before;
 import org.junit.Test;
-import org.openflow.protocol.OFEchoRequest;
-import org.openflow.protocol.OFHello;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.factory.BasicFactory;
-import org.openflow.protocol.factory.OFMessageFactory;
+import org.projectfloodlight.openflow.protocol.OFEchoRequest;
+import org.projectfloodlight.openflow.protocol.OFFactory;
+import org.projectfloodlight.openflow.protocol.OFHello;
+import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFType;
+import org.projectfloodlight.openflow.protocol.OFFactories;
+import org.projectfloodlight.openflow.protocol.OFVersion;
 
 import java.io.IOException;
 import java.util.EnumSet;
 
 public class OFMessageDamperTest {
-    OFMessageFactory factory;
+    OFFactory factory;
     OFMessageDamper damper;
     FloodlightContext cntx;
     
@@ -50,25 +50,18 @@ public class OFMessageDamperTest {
     
     @Before
     public void setUp() throws IOException {
-        factory = BasicFactory.getInstance();
+        factory = OFFactories.getFactory(OFVersion.OF_13);
         cntx = new FloodlightContext();
         
         sw1 = new OFMessageDamperMockSwitch();
         sw2 = new OFMessageDamperMockSwitch();
         
-        echoRequst1 = (OFEchoRequest)factory.getMessage(OFType.ECHO_REQUEST);
-        echoRequst1.setPayload(new byte[] { 1 });
-        echoRequst1Clone = (OFEchoRequest)
-                factory.getMessage(OFType.ECHO_REQUEST);
-        echoRequst1Clone.setPayload(new byte[] { 1 });
-        echoRequst2 = (OFEchoRequest)factory.getMessage(OFType.ECHO_REQUEST);
-        echoRequst2.setPayload(new byte[] { 2 });
-        
-        hello1 = (OFHello)factory.getMessage(OFType.HELLO);
-        hello1.setXid(1);
-        hello2 = (OFHello)factory.getMessage(OFType.HELLO);
-        hello2.setXid(2);
+        echoRequst1 = factory.buildEchoRequest().setData(new byte[] { 1 }).build();
+        echoRequst1Clone = echoRequst1.createBuilder().build();
+        echoRequst2 = factory.buildEchoRequest().setData(new byte[] { 2 }).build();
         
+        hello1 = factory.buildHello().setXid(1L).build();
+        hello2 = factory.buildHello().setXid(2L).build();
     }
     
     protected void doWrite(boolean expectWrite, 
diff --git a/src/test/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkFilterTest.java b/src/test/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkFilterTest.java
index d8dc143617beb40454ce9b67c7ea1940ea79a8f2..2eafde2369fcc60d7467fab673388743b153d199 100644
--- a/src/test/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkFilterTest.java
+++ b/src/test/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkFilterTest.java
@@ -17,16 +17,23 @@
 package net.floodlightcontroller.virtualnetwork;
 
 import static org.easymock.EasyMock.*;
+import static org.junit.Assert.*;
 
 import java.util.List;
 
 import org.easymock.EasyMock;
 import org.junit.Before;
 import org.junit.Test;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.OFPacketIn.OFPacketInReason;
+import org.projectfloodlight.openflow.protocol.OFFactories;
+import org.projectfloodlight.openflow.protocol.OFPacketIn;
+import org.projectfloodlight.openflow.protocol.OFType;
+import org.projectfloodlight.openflow.protocol.OFPacketInReason;
+import org.projectfloodlight.openflow.protocol.OFVersion;
+import org.projectfloodlight.openflow.types.DatapathId;
+import org.projectfloodlight.openflow.types.IPv4Address;
+import org.projectfloodlight.openflow.types.MacAddress;
+import org.projectfloodlight.openflow.types.OFBufferId;
+import org.projectfloodlight.openflow.types.OFPort;
 import org.sdnplatform.sync.ISyncService;
 import org.sdnplatform.sync.test.MockSyncService;
 
@@ -54,7 +61,6 @@ import net.floodlightcontroller.restserver.RestApiServer;
 import net.floodlightcontroller.test.FloodlightTestCase;
 import net.floodlightcontroller.threadpool.IThreadPoolService;
 import net.floodlightcontroller.topology.ITopologyService;
-import net.floodlightcontroller.util.MACAddress;
 import net.floodlightcontroller.virtualnetwork.VirtualNetworkFilter;
 
 public class VirtualNetworkFilterTest extends FloodlightTestCase {
@@ -70,14 +76,10 @@ public class VirtualNetworkFilterTest extends FloodlightTestCase {
     protected static String net3 = "net3";
     protected static String gw2 = "2.2.2.2";
 
-    protected static MACAddress mac1 =
-            new MACAddress(Ethernet.toMACAddress("00:11:22:33:44:55"));
-    protected static MACAddress mac2 =
-            new MACAddress(Ethernet.toMACAddress("00:11:22:33:44:66"));
-    protected static MACAddress mac3 =
-            new MACAddress(Ethernet.toMACAddress("00:11:22:33:44:77"));
-    protected static MACAddress mac4 =
-            new MACAddress(Ethernet.toMACAddress("00:11:22:33:44:88"));
+    protected static MacAddress mac1 = MacAddress.of("00:11:22:33:44:55");
+    protected static MacAddress mac2 = MacAddress.of("00:11:22:33:44:66");
+    protected static MacAddress mac3 = MacAddress.of("00:11:22:33:44:77");
+    protected static MacAddress mac4 = MacAddress.of("00:11:22:33:44:88");
     protected static String hostPort1 = "port1";
     protected static String hostPort2 = "port2";
     protected static String hostPort3 = "port3";
@@ -142,25 +144,16 @@ public class VirtualNetworkFilterTest extends FloodlightTestCase {
         replay(topology);
         // Mock switches
         //fastWilcards mocked as this constant
-        int fastWildcards =
-                OFMatch.OFPFW_IN_PORT |
-                OFMatch.OFPFW_NW_PROTO |
-                OFMatch.OFPFW_TP_SRC |
-                OFMatch.OFPFW_TP_DST |
-                OFMatch.OFPFW_NW_SRC_ALL |
-                OFMatch.OFPFW_NW_DST_ALL |
-                OFMatch.OFPFW_NW_TOS;
         sw1 = EasyMock.createNiceMock(IOFSwitch.class);
-        expect(sw1.getId()).andReturn(1L).anyTimes();
-        expect(sw1.getAttribute(IOFSwitch.PROP_FASTWILDCARDS)).andReturn(fastWildcards).anyTimes();
+        expect(sw1.getId()).andReturn(DatapathId.of(1L)).anyTimes();
         expect(sw1.hasAttribute(IOFSwitch.PROP_SUPPORTS_OFPP_TABLE)).andReturn(true).anyTimes();
         replay(sw1);
 
         // Mock packets
         // Mock from MAC1 -> MAC2
         mac1ToMac2PacketIntestPacket = new Ethernet()
-            .setDestinationMACAddress(mac2.toBytes())
-            .setSourceMACAddress(mac1.toBytes())
+            .setDestinationMACAddress(mac2.getBytes())
+            .setSourceMACAddress(mac1.getBytes())
             .setEtherType(Ethernet.TYPE_IPv4)
             .setPayload(
                 new IPv4()
@@ -172,19 +165,16 @@ public class VirtualNetworkFilterTest extends FloodlightTestCase {
                             .setDestinationPort((short) 5001)
                             .setPayload(new Data(new byte[] {0x01}))));
         mac1ToMac2PacketIntestPacketSerialized = mac1ToMac2PacketIntestPacket.serialize();
-        mac1ToMac2PacketIn =
-                ((OFPacketIn) mockFloodlightProvider.getOFMessageFactory().
-                        getMessage(OFType.PACKET_IN))
-                        .setBufferId(-1)
-                        .setInPort((short) 1)
-                        .setPacketData(mac1ToMac2PacketIntestPacketSerialized)
+        mac1ToMac2PacketIn = OFFactories.getFactory(OFVersion.OF_13).buildPacketIn()
+                        .setBufferId(OFBufferId.NO_BUFFER)
+                        .setInPort(OFPort.of(1))
+                        .setData(mac1ToMac2PacketIntestPacketSerialized)
                         .setReason(OFPacketInReason.NO_MATCH)
-                        .setTotalLength((short) mac1ToMac2PacketIntestPacketSerialized.length);
-
+                        .build();
         // Mock from MAC1 -> MAC4
         mac1ToMac4PacketIntestPacket = new Ethernet()
-        .setDestinationMACAddress(mac4.toBytes())
-        .setSourceMACAddress(mac1.toBytes())
+        .setDestinationMACAddress(mac4.getBytes())
+        .setSourceMACAddress(mac1.getBytes())
         .setEtherType(Ethernet.TYPE_IPv4)
         .setPayload(
             new IPv4()
@@ -195,20 +185,17 @@ public class VirtualNetworkFilterTest extends FloodlightTestCase {
                         .setSourcePort((short) 5000)
                         .setDestinationPort((short) 5001)
                         .setPayload(new Data(new byte[] {0x01}))));
-        mac1ToMac4PacketIntestPacketSerialized = mac1ToMac4PacketIntestPacket.serialize();
-        mac1ToMac4PacketIn =
-            ((OFPacketIn) mockFloodlightProvider.getOFMessageFactory().
-                    getMessage(OFType.PACKET_IN))
-                    .setBufferId(-1)
-                    .setInPort((short) 1)
-                    .setPacketData(mac1ToMac4PacketIntestPacketSerialized)
+        mac1ToMac4PacketIntestPacketSerialized = mac1ToMac4PacketIntestPacket.serialize(); 
+        mac1ToMac4PacketIn = OFFactories.getFactory(OFVersion.OF_13).buildPacketIn()
+                    .setBufferId(OFBufferId.NO_BUFFER)
+                    .setInPort(OFPort.of(1))
+                    .setData(mac1ToMac4PacketIntestPacketSerialized)
                     .setReason(OFPacketInReason.NO_MATCH)
-                    .setTotalLength((short) mac1ToMac4PacketIntestPacketSerialized.length);
-
+                    .build();
         // Mock from MAC1 to gateway1
         mac1ToGwPacketIntestPacket = new Ethernet()
-        .setDestinationMACAddress("00:11:33:33:44:55") // mac shouldn't matter, can't be other host
-        .setSourceMACAddress(mac1.toBytes())
+        .setDestinationMACAddress("00:11:33:33:44:55")
+        .setSourceMACAddress(mac1.getBytes())
         .setEtherType(Ethernet.TYPE_IPv4)
         .setPayload(
             new IPv4()
@@ -220,23 +207,21 @@ public class VirtualNetworkFilterTest extends FloodlightTestCase {
                         .setDestinationPort((short) 5001)
                         .setPayload(new Data(new byte[] {0x01}))));
         mac1ToGwPacketIntestPacketSerialized = mac1ToGwPacketIntestPacket.serialize();
-        mac1ToGwPacketIn =
-            ((OFPacketIn) mockFloodlightProvider.getOFMessageFactory().
-                    getMessage(OFType.PACKET_IN))
-                    .setBufferId(-1)
-                    .setInPort((short) 1)
-                    .setPacketData(mac1ToGwPacketIntestPacketSerialized)
+        mac1ToGwPacketIn =  OFFactories.getFactory(OFVersion.OF_13).buildPacketIn()
+                    .setBufferId(OFBufferId.NO_BUFFER)
+                    .setInPort(OFPort.of(1))
+                    .setData(mac1ToGwPacketIntestPacketSerialized)
                     .setReason(OFPacketInReason.NO_MATCH)
-                    .setTotalLength((short) mac1ToGwPacketIntestPacketSerialized.length);
+                    .build();
     }
 
     @Test
     public void testCreateNetwork() {
         // Test creating a network with all parameters
-        vns.createNetwork(guid1, net1, IPv4.toIPv4Address(gw1));
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid1));
+        vns.createNetwork(guid1, net1, IPv4Address.of(gw1));
+        assertTrue(vns.gatewayToGuid.get(IPv4Address.of(gw1)).contains(guid1));
         assertTrue(vns.nameToGuid.get(net1).equals(guid1));
-        assertTrue(vns.guidToGateway.get(guid1).equals(IPv4.toIPv4Address(gw1)));
+        assertTrue(vns.guidToGateway.get(guid1).equals(IPv4Address.of(gw1)));
         assertTrue(vns.vNetsByGuid.get(guid1).name.equals(net1));
         assertTrue(vns.vNetsByGuid.get(guid1).guid.equals(guid1));
         assertTrue(vns.vNetsByGuid.get(guid1).gateway.equals(gw1));
@@ -246,19 +231,19 @@ public class VirtualNetworkFilterTest extends FloodlightTestCase {
         vns.createNetwork(guid2, net2, null);
         assertTrue(vns.nameToGuid.get(net2).equals(guid2));
         assertTrue(vns.guidToGateway.get(guid2) == null);
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).size() == 1);
+        assertTrue(vns.gatewayToGuid.get(IPv4Address.of(gw1)).size() == 1);
         assertTrue(vns.vNetsByGuid.get(guid2).name.equals(net2));
         assertTrue(vns.vNetsByGuid.get(guid2).guid.equals(guid2));
         assertTrue(vns.vNetsByGuid.get(guid2).gateway == null);
         assertTrue(vns.vNetsByGuid.get(guid2).portToMac.size()==0);
 
         // Test creating a network that shares the gateway with net1
-        vns.createNetwork(guid3, net3, IPv4.toIPv4Address(gw1));
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid1));
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid3));
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).size() == 2);
+        vns.createNetwork(guid3, net3, IPv4Address.of(gw1));
+        assertTrue(vns.gatewayToGuid.get(IPv4Address.of(gw1)).contains(guid1));
+        assertTrue(vns.gatewayToGuid.get(IPv4Address.of(gw1)).contains(guid3));
+        assertTrue(vns.gatewayToGuid.get(IPv4Address.of(gw1)).size() == 2);
         assertTrue(vns.nameToGuid.get(net3).equals(guid3));
-        assertTrue(vns.guidToGateway.get(guid3).equals(IPv4.toIPv4Address(gw1)));
+        assertTrue(vns.guidToGateway.get(guid3).equals(IPv4Address.of(gw1)));
         assertTrue(vns.vNetsByGuid.get(guid3).name.equals(net3));
         assertTrue(vns.vNetsByGuid.get(guid3).guid.equals(guid3));
         assertTrue(vns.vNetsByGuid.get(guid3).gateway.equals(gw1));
@@ -272,17 +257,17 @@ public class VirtualNetworkFilterTest extends FloodlightTestCase {
 
         testCreateNetwork();
         // Modify net2 to add a gateway
-        vns.createNetwork(guid2, net2, IPv4.toIPv4Address(gw1));
+        vns.createNetwork(guid2, net2, IPv4Address.of(gw1));
         assertTrue(vns.nameToGuid.get(net2).equals(guid2));
-        assertTrue(vns.guidToGateway.get(guid2).equals(IPv4.toIPv4Address(gw1)));
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid1));
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid2));
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid3));
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).size() == 3);
+        assertTrue(vns.guidToGateway.get(guid2).equals(IPv4Address.of(gw1)));
+        assertTrue(vns.gatewayToGuid.get(IPv4Address.of(gw1)).contains(guid1));
+        assertTrue(vns.gatewayToGuid.get(IPv4Address.of(gw1)).contains(guid2));
+        assertTrue(vns.gatewayToGuid.get(IPv4Address.of(gw1)).contains(guid3));
+        assertTrue(vns.gatewayToGuid.get(IPv4Address.of(gw1)).size() == 3);
         // Modify net2 to change it's name
         vns.createNetwork(guid2, "newnet2", null);
         // Make sure the gateway is still there
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid2));
+        assertTrue(vns.gatewayToGuid.get(IPv4Address.of(gw1)).contains(guid2));
         assertTrue(vns.vNetsByGuid.get(guid2).gateway.equals(gw1));
         // make sure the new name mapping was learned
         assertTrue(vns.nameToGuid.get("newnet2").equals(guid2));
@@ -296,9 +281,9 @@ public class VirtualNetworkFilterTest extends FloodlightTestCase {
         testModifyNetwork();
         // Delete newnet2
         vns.deleteNetwork(guid2);
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid1));
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid3));
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).size() == 2);
+        assertTrue(vns.gatewayToGuid.get(IPv4Address.of(gw1)).contains(guid1));
+        assertTrue(vns.gatewayToGuid.get(IPv4Address.of(gw1)).contains(guid3));
+        assertTrue(vns.gatewayToGuid.get(IPv4Address.of(gw1)).size() == 2);
         assertFalse(vns.nameToGuid.containsKey(net2));
         assertFalse(vns.guidToGateway.containsKey(net2));
         assertTrue(vns.vNetsByGuid.get(guid2)==null);
@@ -372,7 +357,7 @@ public class VirtualNetworkFilterTest extends FloodlightTestCase {
         IFloodlightProviderService.bcStore.put(cntx,
                            IFloodlightProviderService.CONTEXT_PI_PAYLOAD,
                                (Ethernet)mac1ToGwPacketIntestPacket);
-        deviceService.learnEntity(((Ethernet)mac1ToGwPacketIntestPacket).getDestinationMAC().toLong(),
+        deviceService.learnEntity(((Ethernet)mac1ToGwPacketIntestPacket).getDestinationMACAddress().getLong(),
         		null, IPv4.toIPv4Address(gw1), null, null);
         Command ret = listener.receive(sw1, mac1ToGwPacketIn, cntx);
         assertTrue(ret == Command.CONTINUE);
@@ -382,7 +367,7 @@ public class VirtualNetworkFilterTest extends FloodlightTestCase {
     public void testDhcp() {
         IOFMessageListener listener = getVirtualNetworkListener();
         Ethernet dhcpPacket = PacketFactory.DhcpDiscoveryRequestEthernet(mac1);
-        OFPacketIn dhcpPacketOf = PacketFactory.DhcpDiscoveryRequestOFPacketIn(mac1);
+        OFPacketIn dhcpPacketOf = PacketFactory.DhcpDiscoveryRequestOFPacketIn(sw1, mac1);
         cntx = new FloodlightContext();
         IFloodlightProviderService.bcStore.put(cntx,
                            IFloodlightProviderService.CONTEXT_PI_PAYLOAD,
diff --git a/src/test/java/org/sdnplatform/sync/client/ClientTest.java b/src/test/java/org/sdnplatform/sync/client/ClientTest.java
index d9c291e428cfff58f0808a01e183f98b82bb5125..a4182ad3895c63e5ef19021f920753782d2af7e7 100644
--- a/src/test/java/org/sdnplatform/sync/client/ClientTest.java
+++ b/src/test/java/org/sdnplatform/sync/client/ClientTest.java
@@ -8,8 +8,6 @@ import java.io.PrintStream;
 import java.util.ArrayList;
 
 import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.debugcounter.IDebugCounterService;
-import net.floodlightcontroller.debugcounter.NullDebugCounter;
 import net.floodlightcontroller.threadpool.IThreadPoolService;
 import net.floodlightcontroller.threadpool.ThreadPool;
 
@@ -58,7 +56,6 @@ public class ClientTest {
         
         FloodlightModuleContext fmc = new FloodlightModuleContext();
         fmc.addService(IThreadPoolService.class, tp);
-        fmc.addService(IDebugCounterService.class, new NullDebugCounter());
         
         fmc.addConfigParam(syncManager, "nodes", nodeString);
         fmc.addConfigParam(syncManager, "thisNode", ""+1);
diff --git a/src/test/java/org/sdnplatform/sync/internal/BootstrapTest.java b/src/test/java/org/sdnplatform/sync/internal/BootstrapTest.java
index 5a9c40b4e1347e418c26620678ec6203b85e5cf5..d04cdaa4b8246d9c0b5a9217b924c46b082786ba 100644
--- a/src/test/java/org/sdnplatform/sync/internal/BootstrapTest.java
+++ b/src/test/java/org/sdnplatform/sync/internal/BootstrapTest.java
@@ -3,8 +3,6 @@ package org.sdnplatform.sync.internal;
 import java.io.File;
 import java.util.ArrayList;
 import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.debugcounter.IDebugCounterService;
-import net.floodlightcontroller.debugcounter.NullDebugCounter;
 import net.floodlightcontroller.threadpool.IThreadPoolService;
 import net.floodlightcontroller.threadpool.ThreadPool;
 
@@ -61,7 +59,6 @@ public class BootstrapTest {
             syncManagers.add(syncManager);
 
             fmc.addService(IThreadPoolService.class, tp);
-            fmc.addService(IDebugCounterService.class, new NullDebugCounter());
             String dbPath = 
                     new File(dbFolder.getRoot(), 
                              "server" + i).getAbsolutePath();
diff --git a/src/test/java/org/sdnplatform/sync/internal/SyncManagerTest.java b/src/test/java/org/sdnplatform/sync/internal/SyncManagerTest.java
index 88a9e876661770dccc9c8362e6eeb6b710094bed..c9201b47948c498e35bbe36f7593019ade1c43c9 100644
--- a/src/test/java/org/sdnplatform/sync/internal/SyncManagerTest.java
+++ b/src/test/java/org/sdnplatform/sync/internal/SyncManagerTest.java
@@ -13,8 +13,6 @@ import java.util.List;
 import java.util.Map.Entry;
 
 import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.debugcounter.IDebugCounterService;
-import net.floodlightcontroller.debugcounter.NullDebugCounter;
 import net.floodlightcontroller.threadpool.IThreadPoolService;
 import net.floodlightcontroller.threadpool.ThreadPool;
 
@@ -70,7 +68,6 @@ public class SyncManagerTest {
                                     SyncManager syncManager, Node thisNode)
             throws Exception {        
         fmc.addService(IThreadPoolService.class, tp);
-        fmc.addService(IDebugCounterService.class, new NullDebugCounter());
         fmc.addConfigParam(syncManager, "configProviders", 
                            PropertyCCProvider.class.getName());
         fmc.addConfigParam(syncManager, "nodes", nodeString);
diff --git a/src/test/java/org/sdnplatform/sync/internal/store/RemoteStoreTest.java b/src/test/java/org/sdnplatform/sync/internal/store/RemoteStoreTest.java
index c269e7ed29e20d6b80577b37c5091c264757221d..1ee7f8eefa3acbdf8ee4fa0f0b30a4fa5c424950 100644
--- a/src/test/java/org/sdnplatform/sync/internal/store/RemoteStoreTest.java
+++ b/src/test/java/org/sdnplatform/sync/internal/store/RemoteStoreTest.java
@@ -4,8 +4,6 @@ import java.util.ArrayList;
 import java.util.List;
 
 import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.debugcounter.IDebugCounterService;
-import net.floodlightcontroller.debugcounter.NullDebugCounter;
 import net.floodlightcontroller.threadpool.IThreadPoolService;
 import net.floodlightcontroller.threadpool.ThreadPool;
 
@@ -35,7 +33,6 @@ public class RemoteStoreTest extends AbstractStoreT<ByteArray,byte[]> {
         remoteSyncManager = new RemoteSyncManager();
 
         fmc.addService(IThreadPoolService.class, tp);
-        fmc.addService(IDebugCounterService.class, new NullDebugCounter());
         fmc.addConfigParam(syncManager, "persistenceEnabled", "false");
         
         tp.init(fmc);
diff --git a/src/test/java/org/sdnplatform/sync/internal/version/VectorClockInconsistencyResolverTest.java b/src/test/java/org/sdnplatform/sync/internal/version/VectorClockInconsistencyResolverTest.java
index 1ad45ec9cd15400658c48085d8003a82415ce0fd..eca321f7f2bee00d6932c97171cfe14a2fc1e78b 100644
--- a/src/test/java/org/sdnplatform/sync/internal/version/VectorClockInconsistencyResolverTest.java
+++ b/src/test/java/org/sdnplatform/sync/internal/version/VectorClockInconsistencyResolverTest.java
@@ -58,7 +58,6 @@ public class VectorClockInconsistencyResolverTest {
         assertEquals(0, resolver.resolveConflicts(new ArrayList<Versioned<String>>()).size());
     }
 
-    @SuppressWarnings("unchecked")
     @Test
     public void testDuplicatesResolve() {
         assertEquals(2, resolver.resolveConflicts(Arrays.asList(concurrent,
@@ -68,7 +67,6 @@ public class VectorClockInconsistencyResolverTest {
                                                                 current)).size());
     }
 
-    @SuppressWarnings("unchecked")
     @Test
     public void testResolveNormal() {
         assertEquals(later, resolver.resolveConflicts(Arrays.asList(current, prior, later)).get(0));
@@ -76,7 +74,6 @@ public class VectorClockInconsistencyResolverTest {
         assertEquals(later, resolver.resolveConflicts(Arrays.asList(later, current, prior)).get(0));
     }
 
-    @SuppressWarnings("unchecked")
     @Test
     public void testResolveConcurrent() {
         List<Versioned<String>> resolved = resolver.resolveConflicts(Arrays.asList(current,
@@ -87,7 +84,6 @@ public class VectorClockInconsistencyResolverTest {
         assertTrue("Version not found", resolved.contains(concurrent));
     }
 
-    @SuppressWarnings("unchecked")
     @Test
     public void testResolveLargerConcurrent() {
         assertEquals(3, resolver.resolveConflicts(Arrays.asList(concurrent,
@@ -99,7 +95,6 @@ public class VectorClockInconsistencyResolverTest {
                                                                 current)).size());
     }
 
-    @SuppressWarnings("unchecked")
     @Test
     public void testResolveConcurrentPairWithLater() {
         Versioned<String> later2 = getVersioned(1, 2, 3, 3, 4, 4);