diff --git a/.gitignore b/.gitignore
index dcc106a8e1436ff767ad147545bdfe308800b665..6bb47c581906a2d592173e1b0532486f4ace9bdc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,3 +11,4 @@ thrift
 *.swp
 *.pyc
 findbugs-results
+*.launch
diff --git a/README.md b/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..710e6dc392122d7fbf59b48cb9640ddbf9ae3dc8
--- /dev/null
+++ b/README.md
@@ -0,0 +1,16 @@
+Floodlight is the leading open source SDN controller. It is supported by a community of developers including a number of engineers from Big Switch Networks (http://www.bigswitch.com/).
+
+OpenFlow is a open standard managed by Open Networking Foundation. It specifies a protocol through switch a remote controller can modify the behavior of networking devices through a well-defined “forwarding instruction set”. Floodlight is designed to work with the growing number of switches, routers, virtual witches, and access points that support the OpenFlow standard.
+
+Feature Highlights:
+
+- Offers a module loading system that make it simple to extend and enhance.
+- Easy to set up with minimal dependencies
+- Supports a broad range of virtual- and physical- OpenFlow switches\n
+- Can handle mixed OpenFlow and non-OpenFlow networks – it can manage multiple “islands” of OpenFlow hardware switches\n
+- Designed to be high-performance – is the core of a commercial product from Big Switch Networks.\n
+- Support for OpenStack Quantum cloud orchestration platform}
+
+To download a pre-built VM appliance, access documentation, and sign up for the mailing list, go to:
+
+  http://www.projectfloodlight.org/floodlight
diff --git a/README.txt b/README.txt
deleted file mode 100644
index 44f509d5fb35d5874e331a94f520ef4b05273ae3..0000000000000000000000000000000000000000
--- a/README.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-  
-  Floodlight
-  An Apache licensed, Java based OpenFlow controller
-
-Floodlight is a Java based OpenFlow controller originally written by David Erickson at Stanford
-University. It is available under the Apache 2.0 license.
-
-For documentation, forums, issue tracking and more visit:
-
-      http://www.openflowhub.org/display/Floodlight/Floodlight+Home
diff --git a/setup-eclipse.sh b/setup-eclipse.sh
index 01a6a95ef0f34cee64e85d0707c3d5b29ca0d219..4224a3c5c982f4fee5768a0e5bd788ea36f0b765 100755
--- a/setup-eclipse.sh
+++ b/setup-eclipse.sh
@@ -25,6 +25,36 @@ cat >"$d/.project" <<EOF
 </projectDescription>
 EOF
 
+cat >"$d/Floodlight-Default-Conf.launch" << EOF
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
+    <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
+        <listEntry value="/floodlight/src/main/java/net/floodlightcontroller/core/Main.java"/>
+    </listAttribute>
+    <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
+        <listEntry value="1"/>
+    </listAttribute>
+    <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="net.floodlightcontroller.core.Main"/>
+    <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="floodlight"/>
+    <stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea"/>
+</launchConfiguration>
+EOF
+
+cat > "$d/Floodlight-Quantum-Conf.launch" << EOF
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
+    <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
+        <listEntry value="/floodlight/src/main/java/net/floodlightcontroller/core/Main.java"/>
+    </listAttribute>
+    <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
+        <listEntry value="1"/>
+    </listAttribute>
+    <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="net.floodlightcontroller.core.Main"/>
+    <stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-cf src/main/resources/quantum.properties"/>
+    <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="floodlight"/>
+    <stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea"/>
+</launchConfiguration>
+EOF
 
 cat >"$d/.classpath" <<EOF
 <?xml version="1.0" encoding="UTF-8"?>
diff --git a/src/main/java/net/floodlightcontroller/core/FloodlightProvider.java b/src/main/java/net/floodlightcontroller/core/FloodlightProvider.java
index bf7d6524b587d0535bfcd6e77a4aefff9eb7bff3..cfe315ddc2d0fd57f4fdeb7bf459b23c9bc28d7f 100644
--- a/src/main/java/net/floodlightcontroller/core/FloodlightProvider.java
+++ b/src/main/java/net/floodlightcontroller/core/FloodlightProvider.java
@@ -27,6 +27,11 @@ import net.floodlightcontroller.core.module.FloodlightModuleException;
 import net.floodlightcontroller.core.module.IFloodlightModule;
 import net.floodlightcontroller.core.module.IFloodlightService;
 import net.floodlightcontroller.counter.ICounterStoreService;
+<<<<<<< HEAD
+=======
+import net.floodlightcontroller.debugcounter.IDebugCounterService;
+import net.floodlightcontroller.flowcache.IFlowCacheService;
+>>>>>>> bigswitch/master
 import net.floodlightcontroller.perfmon.IPktInProcessingTimeService;
 import net.floodlightcontroller.restserver.IRestApiService;
 import net.floodlightcontroller.storage.IStorageSourceService;
@@ -34,7 +39,7 @@ import net.floodlightcontroller.threadpool.IThreadPoolService;
 
 public class FloodlightProvider implements IFloodlightModule {
     Controller controller;
-    
+
     @Override
     public Collection<Class<? extends IFloodlightService>> getModuleServices() {
         Collection<Class<? extends IFloodlightService>> services =
@@ -47,9 +52,9 @@ public class FloodlightProvider implements IFloodlightModule {
     public Map<Class<? extends IFloodlightService>,
                IFloodlightService> getServiceImpls() {
         controller = new Controller();
-        
+
         Map<Class<? extends IFloodlightService>,
-            IFloodlightService> m = 
+            IFloodlightService> m =
                 new HashMap<Class<? extends IFloodlightService>,
                             IFloodlightService>();
         m.put(IFloodlightProviderService.class, controller);
@@ -64,6 +69,11 @@ public class FloodlightProvider implements IFloodlightModule {
         dependencies.add(IPktInProcessingTimeService.class);
         dependencies.add(IRestApiService.class);
         dependencies.add(ICounterStoreService.class);
+<<<<<<< HEAD
+=======
+        dependencies.add(IDebugCounterService.class);
+        dependencies.add(IFlowCacheService.class);
+>>>>>>> bigswitch/master
         dependencies.add(IThreadPoolService.class);
         return dependencies;
     }
@@ -76,6 +86,13 @@ public class FloodlightProvider implements IFloodlightModule {
            context.getServiceImpl(IPktInProcessingTimeService.class));
        controller.setCounterStore(
            context.getServiceImpl(ICounterStoreService.class));
+<<<<<<< HEAD
+=======
+       controller.setDebugCounter(
+           context.getServiceImpl(IDebugCounterService.class));
+       controller.setFlowCacheMgr(
+           context.getServiceImpl(IFlowCacheService.class));
+>>>>>>> bigswitch/master
        controller.setRestApiService(
            context.getServiceImpl(IRestApiService.class));
        controller.setThreadPoolService(
diff --git a/src/main/java/net/floodlightcontroller/core/IListener.java b/src/main/java/net/floodlightcontroller/core/IListener.java
index 1bd656022d257cac1508eb80e064b79e03fbfdbc..9a3b8af9182196ad2fa2aa834d8734ff32657311 100644
--- a/src/main/java/net/floodlightcontroller/core/IListener.java
+++ b/src/main/java/net/floodlightcontroller/core/IListener.java
@@ -31,9 +31,9 @@ public interface IListener<T> {
     /**
      * Check if the module called name is a callback ordering prerequisite
      * for this module.  In other words, if this function returns true for 
-     * the given name, then this message listener will be called after that
+     * the given name, then this listener will be called after that
      * message listener.
-     * @param type the message type to which this applies
+     * @param type the object type to which this applies
      * @param name the name of the module
      * @return whether name is a prerequisite.
      */
@@ -42,9 +42,9 @@ public interface IListener<T> {
     /**
      * Check if the module called name is a callback ordering post-requisite
      * for this module.  In other words, if this function returns true for 
-     * the given name, then this message listener will be called before that
+     * the given name, then this listener will be called before that
      * message listener.
-     * @param type the message type to which this applies
+     * @param type the object type to which this applies
      * @param name the name of the module
      * @return whether name is a post-requisite.
      */
diff --git a/src/main/java/net/floodlightcontroller/core/IOFSwitch.java b/src/main/java/net/floodlightcontroller/core/IOFSwitch.java
index 428dc7f7e07ceb0598b2854668d6705a2cfa7efe..6bc92c98fae1e9866c99606d352f6115d1b0c618 100644
--- a/src/main/java/net/floodlightcontroller/core/IOFSwitch.java
+++ b/src/main/java/net/floodlightcontroller/core/IOFSwitch.java
@@ -107,7 +107,28 @@ public interface IOFSwitch {
     public void setChannel(Channel channel);
 
     /**
-     * Writes to the OFMessage to the output stream.
+     * Write OFMessage to the output stream, subject to switch rate limiting.
+     * The message will be handed to the floodlightProvider for possible filtering
+     * and processing by message listeners
+     * @param msg
+     * @param cntx
+     * @throws IOException
+     */
+    public void writeThrottled(OFMessage msg, FloodlightContext cntx) throws IOException;
+
+    /**
+     * Writes the list of messages to the output stream, subject to rate limiting.
+     * The message will be handed to the floodlightProvider for possible filtering
+     * and processing by message listeners.
+     * @param msglist
+     * @param bc
+     * @throws IOException
+     */
+    void writeThrottled(List<OFMessage> msglist, FloodlightContext bc)
+            throws IOException;
+
+    /**
+     * Writes to the OFMessage to the output stream, bypassing rate limiting.
      * The message will be handed to the floodlightProvider for possible filtering
      * and processing by message listeners
      * @param m   
@@ -117,7 +138,7 @@ public interface IOFSwitch {
     public void write(OFMessage m, FloodlightContext bc) throws IOException; 
     
     /**
-     * Writes the list of messages to the output stream
+     * Writes the list of messages to the output stream, bypassing rate limiting.
      * The message will be handed to the floodlightProvider for possible filtering
      * and processing by message listeners.
      * @param msglist
@@ -488,5 +509,4 @@ public interface IOFSwitch {
      * @return
      */
     public List<Short> getUplinkPorts();
-    
 }
diff --git a/src/main/java/net/floodlightcontroller/core/OFSwitchBase.java b/src/main/java/net/floodlightcontroller/core/OFSwitchBase.java
index 98eb372404b3bbcf490d5dcde5bd43baaee43afc..5c8248d5e88e5c4ce17d5a7768622e7cb2e79974 100644
--- a/src/main/java/net/floodlightcontroller/core/OFSwitchBase.java
+++ b/src/main/java/net/floodlightcontroller/core/OFSwitchBase.java
@@ -36,6 +36,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 import net.floodlightcontroller.core.IFloodlightProviderService.Role;
 import net.floodlightcontroller.core.annotations.LogMessageDoc;
+import net.floodlightcontroller.core.annotations.LogMessageDocs;
 import net.floodlightcontroller.core.internal.Controller;
 import net.floodlightcontroller.core.internal.OFFeaturesReplyFuture;
 import net.floodlightcontroller.core.internal.OFStatisticsFuture;
@@ -48,6 +49,7 @@ import org.codehaus.jackson.annotate.JsonProperty;
 import org.codehaus.jackson.map.annotate.JsonSerialize;
 import org.codehaus.jackson.map.ser.ToStringSerializer;
 import org.jboss.netty.channel.Channel;
+import org.openflow.protocol.OFBarrierRequest;
 import org.openflow.protocol.OFFeaturesReply;
 import org.openflow.protocol.OFFlowMod;
 import org.openflow.protocol.OFMatch;
@@ -109,6 +111,8 @@ public abstract class OFSwitchBase implements IOFSwitch {
     private final ReentrantReadWriteLock listenerLock;
     private final ConcurrentMap<Short, AtomicLong> portBroadcastCacheHitMap;
 
+    // Private members for throttling
+    private boolean writeThrottleEnabled = false;
 
     protected final static ThreadLocal<Map<IOFSwitch,List<OFMessage>>> local_msg_buffer =
             new ThreadLocal<Map<IOFSwitch,List<OFMessage>>>() {
@@ -181,7 +185,52 @@ public abstract class OFSwitchBase implements IOFSwitch {
     public void setChannel(Channel channel) {
         this.channel = channel;
     }
-    
+
+    // For driver subclass to set throttling
+    protected void enableWriteThrottle(boolean enable) {
+        this.writeThrottleEnabled = enable;
+    }
+
+    @Override
+    @LogMessageDocs({
+        @LogMessageDoc(level="WARN",
+                message="Drop throttled OF message to switch {switch}",
+                explanation="The controller is sending more messages" +
+                "than the switch can handle. Some messages are dropped" +
+                "to prevent switch outage",
+                recommendation=LogMessageDoc.REPORT_CONTROLLER_BUG)
+    })
+    public void writeThrottled(OFMessage m, FloodlightContext bc)
+            throws IOException {
+        /**
+         * By default, channel uses an unbounded send queue. Enable throttling
+         * prevents the queue from growing big.
+         *
+         * channel.isWritable() returns true when queue length is less than
+         * high water mark (64 kbytes). Once exceeded, isWritable() becomes
+         * false after queue length drops below low water mark (32 kbytes).
+         */
+        if (!writeThrottleEnabled || channel.isWritable()) {
+            write(m, bc);
+        } else {
+            // Let logback duplicate filtering take care of excessive logs
+            // TODO Convert to counter and events
+            log.warn("Drop throttled OF message to switch {}", this);
+        }
+    }
+
+    @Override
+    public void writeThrottled(List<OFMessage> msglist, FloodlightContext bc)
+            throws IOException {
+        if (!writeThrottleEnabled || channel.isWritable()) {
+            write(msglist, bc);
+        } else {
+            // Let logback duplicate filtering take care of excessive logs
+            // TODO Convert to counter and events
+            log.warn("Drop throttled OF message to switch {}", this);
+        }
+    }
+
     @Override
     public void write(OFMessage m, FloodlightContext bc)
             throws IOException {
@@ -201,7 +250,6 @@ public abstract class OFSwitchBase implements IOFSwitch {
             msg_buffer.clear();
         }
     }
-
     @Override
     @LogMessageDoc(level="WARN",
                    message="Sending OF message that modifies switch " +
@@ -230,6 +278,11 @@ public abstract class OFSwitchBase implements IOFSwitch {
         this.write(msglist);
     }
 
+    /**
+     * Not callable by writers, but allow IOFSwitch implementation to override
+     * @param msglist
+     * @throws IOException
+     */
     private void write(List<OFMessage> msglist) throws IOException {
         this.channel.write(msglist);
     }
@@ -397,7 +450,7 @@ public abstract class OFSwitchBase implements IOFSwitch {
         this.iofMsgListenersMap.put(xid, caller);
         List<OFMessage> msglist = new ArrayList<OFMessage>(1);
         msglist.add(request);
-        this.channel.write(msglist);
+        this.write(msglist);
         return;
     }
 
@@ -408,7 +461,7 @@ public abstract class OFSwitchBase implements IOFSwitch {
         this.statsFutureMap.put(request.getXid(), future);
         List<OFMessage> msglist = new ArrayList<OFMessage>(1);
         msglist.add(request);
-        this.channel.write(msglist);
+        this.write(msglist);
         return future;
     }
 
@@ -509,10 +562,18 @@ public abstract class OFSwitchBase implements IOFSwitch {
             .setCommand(OFFlowMod.OFPFC_DELETE)
             .setOutPort(OFPort.OFPP_NONE)
             .setLength(U16.t(OFFlowMod.MINIMUM_LENGTH));
+        fm.setXid(getNextTransactionId());
+        OFMessage barrierMsg = (OFBarrierRequest)
+                floodlightProvider.getOFMessageFactory().getMessage(
+                        OFType.BARRIER_REQUEST);
+        barrierMsg.setXid(getNextTransactionId());
         try {
             List<OFMessage> msglist = new ArrayList<OFMessage>(1);
             msglist.add(fm);
-            channel.write(msglist);
+            write(msglist);
+            msglist = new ArrayList<OFMessage>(1);
+            msglist.add(barrierMsg);
+            write(msglist);
         } catch (Exception e) {
             log.error("Failed to clear all flows on switch " + this, e);
         }
@@ -630,7 +691,7 @@ public abstract class OFSwitchBase implements IOFSwitch {
         this.featuresFutureMap.put(request.getXid(), future);
         List<OFMessage> msglist = new ArrayList<OFMessage>(1);
         msglist.add(request);
-        this.channel.write(msglist);
+        this.write(msglist);
         return future;
     }
 
diff --git a/src/main/java/net/floodlightcontroller/core/internal/Controller.java b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
index a71e7abc3da905873f60d23ed417b26414788e3a..b745f4636c41ece93bca66c043ec6865e4a38238 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/Controller.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
@@ -66,6 +66,11 @@ import net.floodlightcontroller.core.util.ListenerDispatcher;
 import net.floodlightcontroller.core.util.SingletonTask;
 import net.floodlightcontroller.core.web.CoreWebRoutable;
 import net.floodlightcontroller.counter.ICounterStoreService;
+<<<<<<< HEAD
+=======
+import net.floodlightcontroller.debugcounter.IDebugCounterService;
+import net.floodlightcontroller.flowcache.IFlowCacheService;
+>>>>>>> bigswitch/master
 import net.floodlightcontroller.packet.Ethernet;
 import net.floodlightcontroller.perfmon.IPktInProcessingTimeService;
 import net.floodlightcontroller.restserver.IRestApiService;
@@ -171,6 +176,11 @@ public class Controller implements IFloodlightProviderService,
     // Module dependencies
     protected IRestApiService restApi;
     protected ICounterStoreService counterStore = null;
+<<<<<<< HEAD
+=======
+    protected IDebugCounterService debugCounter;
+    protected IFlowCacheService bigFlowCacheMgr;
+>>>>>>> bigswitch/master
     protected IStorageSourceService storageSource;
     protected IPktInProcessingTimeService pktinProcTime;
     protected IThreadPoolService threadPool;
@@ -189,7 +199,7 @@ public class Controller implements IFloodlightProviderService,
     // we have sent to the listeners. On a transition to slave we first set
     // this role and then notify, on a transition to master we first notify
     // and then set the role. We then use it to make sure we don't forward
-    // OF messages while the modules are in slave role. 
+    // OF messages while the modules are in slave role.
     // The pendingRole is a role change just received, but not sent out
     // notifications yet.
     protected Role pendingRole;
@@ -217,7 +227,7 @@ public class Controller implements IFloodlightProviderService,
     protected static final String CONTROLLER_INTERFACE_DISCOVERED_IP = "discovered_ip";
 
     // Perf. related configuration
-    protected static final int SEND_BUFFER_SIZE = 4 * 1024 * 1024;
+    protected int sendBufferSize = 4 * 1024 * 1024;
     public static final int BATCH_MAX_SIZE = 100;
     protected static final boolean ALWAYS_DECODE_ETH = true;
 
@@ -300,7 +310,7 @@ public class Controller implements IFloodlightProviderService,
                           newRole, oldRole);
             }
             // Set notified role to slave before notifying listeners. This
-            // stops OF messages from being sent to listeners 
+            // stops OF messages from being sent to listeners
             if (newRole == Role.SLAVE)
                 Controller.this.notifiedRole = newRole;
             if (haListeners != null) {
@@ -308,7 +318,7 @@ public class Controller implements IFloodlightProviderService,
                         listener.roleChanged(oldRole, newRole);
                 }
             }
-            // Set notified role to master/equal after notifying listeners. 
+            // Set notified role to master/equal after notifying listeners.
             // We now forward messages again
             if (newRole != Role.SLAVE)
                 Controller.this.notifiedRole = newRole;
@@ -361,6 +371,17 @@ public class Controller implements IFloodlightProviderService,
         this.counterStore = counterStore;
     }
 
+<<<<<<< HEAD
+=======
+    public void setDebugCounter(IDebugCounterService debugCounter) {
+        this.debugCounter = debugCounter;
+    }
+
+    public void setFlowCacheMgr(IFlowCacheService flowCacheMgr) {
+        this.bigFlowCacheMgr = flowCacheMgr;
+    }
+
+>>>>>>> bigswitch/master
     public void setPktInProcessingService(IPktInProcessingTimeService pits) {
         this.pktinProcTime = pits;
     }
@@ -663,6 +684,11 @@ public class Controller implements IFloodlightProviderService,
                 // Flush all flow-mods/packet-out/stats generated from this "train"
                 OFSwitchBase.flush_all();
                 counterStore.updateFlush();
+<<<<<<< HEAD
+=======
+                debugCounter.flushCounters();
+                bigFlowCacheMgr.updateFlush();
+>>>>>>> bigswitch/master
             }
         }
 
@@ -1054,7 +1080,7 @@ public class Controller implements IFloodlightProviderService,
 
                         if (sw.isConnected()) {
                             // Only dispatch message if the switch is in the
-                            // activeSwitch map and if the switches role is 
+                            // activeSwitch map and if the switches role is
                             // not slave and the modules are not in slave
                             // TODO: Should we dispatch messages that we expect to
                             // receive when we're in the slave role, e.g. port
@@ -1064,7 +1090,7 @@ public class Controller implements IFloodlightProviderService,
                             // to them. On the other hand there might be special
                             // modules that care about all of the connected switches
                             // and would like to receive port status notifications.
-                            if (sw.getHARole() == Role.SLAVE || 
+                            if (sw.getHARole() == Role.SLAVE ||
                                     notifiedRole == Role.SLAVE ||
                                     !activeSwitches.containsKey(sw.getId())) {
                                 // Don't log message if it's a port status message
@@ -1092,19 +1118,31 @@ public class Controller implements IFloodlightProviderService,
     // Message handlers
     // ****************
 
+    @LogMessageDocs({
+        @LogMessageDoc(message="Port modified on switch {switch}: {port} ",
+                explanation="Received notification from switch about port status change"),
+        @LogMessageDoc(message="Port added on switch {switch}: {port} ",
+                explanation="Received notification from switch about a new port addition"),
+        @LogMessageDoc(message="Port deleted on switch {switch}: port_no = {port} ",
+                explanation="Received notification from switch about a port removal"),
+        @LogMessageDoc(level="ERROR",
+                message="Failure adding update to queue",
+                explanation="Failed to add port status change to internal queue for processing",
+                recommendation=LogMessageDoc.REPORT_CONTROLLER_BUG)
+    })
     protected void handlePortStatusMessage(IOFSwitch sw, OFPortStatus m) {
         short portNumber = m.getDesc().getPortNumber();
         OFPhysicalPort port = m.getDesc();
         if (m.getReason() == (byte)OFPortReason.OFPPR_MODIFY.ordinal()) {
             sw.setPort(port);
-            log.debug("Port #{} modified for {}", portNumber, sw);
+            log.info("Port modified on switch {}: {}", sw, port);
         } else if (m.getReason() == (byte)OFPortReason.OFPPR_ADD.ordinal()) {
             sw.setPort(port);
-            log.debug("Port #{} added for {}", portNumber, sw);
+            log.info("Port added on switch {}: {}", sw, port);
         } else if (m.getReason() ==
                    (byte)OFPortReason.OFPPR_DELETE.ordinal()) {
             sw.deletePort(portNumber);
-            log.debug("Port #{} deleted for {}", portNumber, sw);
+            log.info("Port deleted on switch {}: port_no = {}", sw, portNumber);
         }
         SwitchUpdate update = new SwitchUpdate(sw, SwitchUpdateType.PORTCHANGED);
         try {
@@ -1175,7 +1213,7 @@ public class Controller implements IFloodlightProviderService,
                                  FloodlightContext bContext)
             throws IOException {
         Ethernet eth = null;
-        
+
         switch (m.getType()) {
             case PACKET_IN:
                 OFPacketIn pi = (OFPacketIn)m;
@@ -1241,7 +1279,10 @@ public class Controller implements IFloodlightProviderService,
                     }
                     pktinProcTime.recordEndTimePktIn(sw, m, bc);
                 } else {
-                    log.warn("Unhandled OF Message: {} from {}", m, sw);
+                    if (m.getType() != OFType.BARRIER_REPLY)
+                        log.warn("Unhandled OF Message: {} from {}", m, sw);
+                    else
+                        log.debug("Received a Barrier Reply, no listeners for it");
                 }
 
                 if ((bContext == null) && (bc != null)) flcontext_free(bc);
@@ -1692,7 +1733,7 @@ public class Controller implements IFloodlightProviderService,
             bootstrap.setOption("reuseAddr", true);
             bootstrap.setOption("child.keepAlive", true);
             bootstrap.setOption("child.tcpNoDelay", true);
-            bootstrap.setOption("child.sendBufferSize", Controller.SEND_BUFFER_SIZE);
+            bootstrap.setOption("child.sendBufferSize", sendBufferSize);
 
             ChannelPipelineFactory pfact =
                     new OpenflowPipelineFactory(this, null);
@@ -1748,7 +1789,11 @@ public class Controller implements IFloodlightProviderService,
             this.workerThreads = Integer.parseInt(threads);
         }
         log.debug("Number of worker threads set to {}", this.workerThreads);
-        
+        String sendBufferStr = configParams.get("sendBufferSize");
+        if (sendBufferStr != null) {
+            this.sendBufferSize = Integer.parseInt(sendBufferStr);
+        }
+        log.debug("Send buffer size set to {}", sendBufferSize);
     }
 
     private void initVendorMessages() {
diff --git a/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleContext.java b/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleContext.java
index 77b7e76c79717189a825715fff7c96d3b510d46b..2ebe41e3ca404992a379cc7ec12d4adc7461cc46 100644
--- a/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleContext.java
+++ b/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleContext.java
@@ -25,96 +25,97 @@ import java.util.Map;
  * @author alexreimers
  */
 public class FloodlightModuleContext implements IFloodlightModuleContext {
-	protected Map<Class<? extends IFloodlightService>, IFloodlightService> serviceMap;
-	protected Map<Class<? extends IFloodlightModule>, Map<String, String>> configParams;
-	protected Collection<IFloodlightModule> moduleSet;
-	
-	/**
-	 * Creates the ModuleContext for use with this IFloodlightProvider.
-	 * This will be used as a module registry for all IFloodlightModule(s).
-	 */
-	public FloodlightModuleContext() {
-		serviceMap = 
-		        new HashMap<Class<? extends IFloodlightService>,
-		                              IFloodlightService>();
-		configParams =
-		        new HashMap<Class<? extends IFloodlightModule>,
-		                        Map<String, String>>();
-	}
-	
-	/**
-	 * Adds a IFloodlightModule for this Context.
-	 * @param clazz the service class
-	 * @param service The IFloodlightService to add to the registry
-	 */
-	public void addService(Class<? extends IFloodlightService> clazz, 
-	                       IFloodlightService service) {
-		serviceMap.put(clazz, service);
-	}
-	
-	@SuppressWarnings("unchecked")
+    protected Map<Class<? extends IFloodlightService>, IFloodlightService> serviceMap;
+    protected Map<Class<? extends IFloodlightModule>, Map<String, String>> configParams;
+    protected Collection<IFloodlightModule> moduleSet;
+    
+    /**
+     * Creates the ModuleContext for use with this IFloodlightProvider.
+     * This will be used as a module registry for all IFloodlightModule(s).
+     */
+    public FloodlightModuleContext() {
+        serviceMap = 
+                new HashMap<Class<? extends IFloodlightService>,
+                                      IFloodlightService>();
+        configParams =
+                new HashMap<Class<? extends IFloodlightModule>,
+                                Map<String, String>>();
+    }
+    
+    /**
+     * Adds a IFloodlightModule for this Context.
+     * @param clazz the service class
+     * @param service The IFloodlightService to add to the registry
+     */
+    public void addService(Class<? extends IFloodlightService> clazz, 
+                           IFloodlightService service) {
+        serviceMap.put(clazz, service);
+    }
+    
+    @SuppressWarnings("unchecked")
     @Override
-	public <T extends IFloodlightService> T getServiceImpl(Class<T> service) {
-	    IFloodlightService s = serviceMap.get(service);
-		return (T)s;
-	}
-	
-	@Override
-	public Collection<Class<? extends IFloodlightService>> getAllServices() {
-	    return serviceMap.keySet();
-	}
-	
-	@Override
-	public Collection<IFloodlightModule> getAllModules() {
-	    return moduleSet;
-	}
-	
-	public void setModuleSet(Collection<IFloodlightModule> modSet) {
-	    this.moduleSet = modSet;
-	}
-	
-	/**
-	 * Gets the configuration parameter map for a module
-	 * @param module The module to get the configuration map for, usually yourself
-	 * @return A map containing all the configuration parameters for the module, may be empty
-	 */
-	@Override
-	public Map<String, String> getConfigParams(IFloodlightModule module) {
-	    Map<String, String> retMap = configParams.get(module.getClass());
-	    if (retMap == null) {
-	        // Return an empty map if none exists so the module does not
-	        // need to null check the map
-	        retMap = new HashMap<String, String>();
-	        configParams.put(module.getClass(), retMap);
-	    }
+    public <T extends IFloodlightService> T getServiceImpl(Class<T> service) {
+        IFloodlightService s = serviceMap.get(service);
+        return (T)s;
+    }
+    
+    @Override
+    public Collection<Class<? extends IFloodlightService>> getAllServices() {
+        return serviceMap.keySet();
+    }
+    
+    @Override
+    public Collection<IFloodlightModule> getAllModules() {
+        return moduleSet;
+    }
+    
+    public void setModuleSet(Collection<IFloodlightModule> modSet) {
+        this.moduleSet = modSet;
+    }
+
+    @Override
+    public Map<String, String> getConfigParams(IFloodlightModule module) {
+        Class<? extends IFloodlightModule> clazz = module.getClass();
+        return getConfigParams(clazz);
+    }
+
+    @Override
+    public Map<String, String> getConfigParams(Class<? extends IFloodlightModule> clazz) {
+        Map<String, String> retMap = configParams.get(clazz);
+        if (retMap == null) {
+            // Return an empty map if none exists so the module does not
+            // need to null check the map
+            retMap = new HashMap<String, String>();
+            configParams.put(clazz, retMap);
+        }
 
-	    // also add any configuration parameters for superclasses, but
-	    // only if more specific configuration does not override it
-	    for (Class<? extends IFloodlightModule> c : configParams.keySet()) {
-	        if (c.isInstance(module)) {
-	            for (Map.Entry<String, String> ent : configParams.get(c).entrySet()) {
-	                if (!retMap.containsKey(ent.getKey())) {
-	                    retMap.put(ent.getKey(), ent.getValue());
-	                }
-	            }
-	        }
-	    }
+        // also add any configuration parameters for superclasses, but
+        // only if more specific configuration does not override it
+        for (Class<? extends IFloodlightModule> c : configParams.keySet()) {
+            if (c.isAssignableFrom(clazz)) {
+                for (Map.Entry<String, String> ent : configParams.get(c).entrySet()) {
+                    if (!retMap.containsKey(ent.getKey())) {
+                        retMap.put(ent.getKey(), ent.getValue());
+                    }
+                }
+            }
+        }
 
-	    return retMap;
-	}
-	
-	/**
-	 * Adds a configuration parameter for a module
-	 * @param mod The fully qualified module name to add the parameter to
-	 * @param key The configuration parameter key
-	 * @param value The configuration parameter value
-	 */
-	public void addConfigParam(IFloodlightModule mod, String key, String value) {
-	    Map<String, String> moduleParams = configParams.get(mod.getClass());
-	    if (moduleParams == null) {
-	        moduleParams = new HashMap<String, String>();
-	        configParams.put(mod.getClass(), moduleParams);
-	    }
-	    moduleParams.put(key, value);
-	}
+        return retMap;
+    }
+    
+    /**
+     * Adds a configuration parameter for a module
+     * @param mod The fully qualified module name to add the parameter to
+     * @param key The configuration parameter key
+     * @param value The configuration parameter value
+     */
+    public void addConfigParam(IFloodlightModule mod, String key, String value) {
+        Map<String, String> moduleParams = configParams.get(mod.getClass());
+        if (moduleParams == null) {
+            moduleParams = new HashMap<String, String>();
+            configParams.put(mod.getClass(), moduleParams);
+        }
+        moduleParams.put(key, value);
+    }
  }
diff --git a/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleException.java b/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleException.java
index 1bb1e1e1a6b3042399104057e2081b3127c29c44..5cddd37fccb8564ae7e31b6f2418a2339ce354c7 100644
--- a/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleException.java
+++ b/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleException.java
@@ -22,4 +22,16 @@ public class FloodlightModuleException extends Exception {
 	public FloodlightModuleException(String error) {
 		super(error);
 	}
+
+    public FloodlightModuleException() {
+        super();
+    }
+
+    public FloodlightModuleException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public FloodlightModuleException(Throwable cause) {
+        super(cause);
+    }
 }
diff --git a/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleLoader.java b/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleLoader.java
index c4b7d76fb39b9a2c0c245d78bc24935cb508e6dc..78422e50a9472970a57d446f042f9b3fb2ac910d 100644
--- a/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleLoader.java
+++ b/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleLoader.java
@@ -305,6 +305,7 @@ public class FloodlightModuleLoader {
                                 throw new FloodlightModuleException("ERROR! Found more " + 
                                     "than one (" + mods.size() + ") IFloodlightModules that provides " +
                                     "service " + c.toString() + 
+                                    ". This service is required for " + moduleName + 
                                     ". Please specify one of the following modules in the config: " + 
                                     duplicateMods);
                             }
@@ -405,8 +406,10 @@ public class FloodlightModuleLoader {
     /**
      * Call each loaded module's startup method
      * @param moduleSet the module set to start up
+     * @throws FloodlightModuleException 
      */
-    protected void startupModules(Collection<IFloodlightModule> moduleSet) {
+    protected void startupModules(Collection<IFloodlightModule> moduleSet) 
+            throws FloodlightModuleException {
         for (IFloodlightModule m : moduleSet) {
             if (logger.isDebugEnabled()) {
                 logger.debug("Starting " + m.getClass().getCanonicalName());
diff --git a/src/main/java/net/floodlightcontroller/core/module/IFloodlightModule.java b/src/main/java/net/floodlightcontroller/core/module/IFloodlightModule.java
index 217ab8072e17a4b241e4d324d420fd8e5a7499ec..982e4be26a7e073dd700599a96a4393697088ed3 100644
--- a/src/main/java/net/floodlightcontroller/core/module/IFloodlightModule.java
+++ b/src/main/java/net/floodlightcontroller/core/module/IFloodlightModule.java
@@ -34,57 +34,59 @@ import java.util.Map;
  * @author alexreimers
  */
 public interface IFloodlightModule {
-	
-	/**
-	 * Return the list of interfaces that this module implements.
-	 * All interfaces must inherit IFloodlightService
-	 * @return
-	 */
-	
-	public Collection<Class<? extends IFloodlightService>> getModuleServices();
-	
-	/**
-	 * Instantiate (as needed) and return objects that implement each
-	 * of the services exported by this module.  The map returned maps
-	 * the implemented service to the object.  The object could be the
-	 * same object or different objects for different exported services.
-	 * @return The map from service interface class to service implementation
-	 */
-	public Map<Class<? extends IFloodlightService>,
-	           IFloodlightService> getServiceImpls();
-	
-	/**
-	 * Get a list of Modules that this module depends on.  The module system
-	 * will ensure that each these dependencies is resolved before the 
-	 * subsequent calls to init().
-	 * @return The Collection of IFloodlightServices that this module depends
-	 *         on.
-	 */
-	
-	public Collection<Class<? extends IFloodlightService>> getModuleDependencies();
-	
-	/**
-	 * This is a hook for each module to do its <em>internal</em> initialization, 
-	 * e.g., call setService(context.getService("Service"))
-	 * 
-	 * All module dependencies are resolved when this is called, but not every module 
-	 * is initialized.
-	 * 
-	 * @param context
-	 * @throws FloodlightModuleException
-	 */
-	
-	void init(FloodlightModuleContext context) throws FloodlightModuleException;
-	
-	/**
-	 * This is a hook for each module to do its <em>external</em> initializations,
-	 * e.g., register for callbacks or query for state in other modules
-	 * 
-	 * It is expected that this function will not block and that modules that want
-	 * non-event driven CPU will spawn their own threads.
-	 * 
-	 * @param context
-	 */
-	
-	void startUp(FloodlightModuleContext context); 
+    
+    /**
+     * Return the list of interfaces that this module implements.
+     * All interfaces must inherit IFloodlightService
+     * @return
+     */
+    
+    public Collection<Class<? extends IFloodlightService>> getModuleServices();
+    
+    /**
+     * Instantiate (as needed) and return objects that implement each
+     * of the services exported by this module.  The map returned maps
+     * the implemented service to the object.  The object could be the
+     * same object or different objects for different exported services.
+     * @return The map from service interface class to service implementation
+     */
+    public Map<Class<? extends IFloodlightService>,
+               IFloodlightService> getServiceImpls();
+    
+    /**
+     * Get a list of Modules that this module depends on.  The module system
+     * will ensure that each these dependencies is resolved before the 
+     * subsequent calls to init().
+     * @return The Collection of IFloodlightServices that this module depends
+     *         on.
+     */
+    
+    public Collection<Class<? extends IFloodlightService>> getModuleDependencies();
+    
+    /**
+     * This is a hook for each module to do its <em>internal</em> initialization, 
+     * e.g., call setService(context.getService("Service"))
+     * 
+     * All module dependencies are resolved when this is called, but not every module 
+     * is initialized.
+     * 
+     * @param context
+     * @throws FloodlightModuleException
+     */
+    
+    void init(FloodlightModuleContext context) throws FloodlightModuleException;
+    
+    /**
+     * This is a hook for each module to do its <em>external</em> initializations,
+     * e.g., register for callbacks or query for state in other modules
+     * 
+     * It is expected that this function will not block and that modules that want
+     * non-event driven CPU will spawn their own threads.
+     * 
+     * @param context
+     * @throws FloodlightModuleException 
+     */
+    
+    void startUp(FloodlightModuleContext context) 
+            throws FloodlightModuleException; 
 }
diff --git a/src/main/java/net/floodlightcontroller/core/module/IFloodlightModuleContext.java b/src/main/java/net/floodlightcontroller/core/module/IFloodlightModuleContext.java
index 6288cb7898d4f792a583b7a17c22d29f6da4caf2..6dce334f8cd15c529c9aa56e55f07418e0adb705 100644
--- a/src/main/java/net/floodlightcontroller/core/module/IFloodlightModuleContext.java
+++ b/src/main/java/net/floodlightcontroller/core/module/IFloodlightModuleContext.java
@@ -48,4 +48,12 @@ public interface IFloodlightModuleContext {
      * @return A key, value map of the configuration options
      */
     public Map<String, String> getConfigParams(IFloodlightModule module);
+
+    /**
+     * Gets module specific configuration parameters.
+     * @param clazz The class of the module to get configuration parameters for
+     * @return A key, value map of the configuration options
+     */
+    public Map<String, String> getConfigParams(Class<? extends
+                                                     IFloodlightModule> clazz);
 }
diff --git a/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java b/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java
index 45ef6e9978fdebf82e3476dd8dfe6b94552499b4..c4d3419eb20c4822a16746fe44c9c7466d4caeff 100644
--- a/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java
+++ b/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java
@@ -1,7 +1,7 @@
 /**
-*    Copyright 2011, Big Switch Networks, Inc. 
+*    Copyright 2011, Big Switch Networks, Inc.
 *    Originally created by David Erickson, Stanford University
-* 
+*
 *    Licensed under the Apache License, Version 2.0 (the "License"); you may
 *    not use this file except in compliance with the License. You may obtain
 *    a copy of the License at
@@ -18,6 +18,9 @@
 package net.floodlightcontroller.core.web;
 
 import net.floodlightcontroller.core.module.ModuleLoaderResource;
+import net.floodlightcontroller.debugcounter.DebugCounterGetResource;
+import net.floodlightcontroller.debugcounter.DebugCounterResetResource;
+import net.floodlightcontroller.debugcounter.DebugCounterStateResource;
 import net.floodlightcontroller.restserver.RestletRoutable;
 
 import org.restlet.Context;
@@ -60,6 +63,9 @@ public class CoreWebRoutable implements RestletRoutable {
         router.attach("/role/json", ControllerRoleResource.class);
         router.attach("/health/json", HealthCheckResource.class);
         router.attach("/system/uptime/json", SystemUptimeResource.class);
+        router.attach("/debugcounter/{param}/json", DebugCounterGetResource.class);
+        router.attach("/debugcounter/reset/{param}/json", DebugCounterResetResource.class);
+        router.attach("/debugcounter/{moduleCounterName}/{state}/json", DebugCounterStateResource.class);
         return router;
     }
 }
diff --git a/src/main/java/net/floodlightcontroller/counter/ConcurrentCounter.java b/src/main/java/net/floodlightcontroller/counter/ConcurrentCounter.java
deleted file mode 100644
index cdec1e0ed3e2e036af82c96fe35b100510296166..0000000000000000000000000000000000000000
--- a/src/main/java/net/floodlightcontroller/counter/ConcurrentCounter.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/**
-*    Copyright 2011, Big Switch Networks, Inc. 
-*    Originally created by David Erickson, Stanford University
-* 
-*    Licensed under the Apache License, Version 2.0 (the "License"); you may
-*    not use this file except in compliance with the License. You may obtain
-*    a copy of the License at
-*
-*         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.counter;
-
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Queue;
-import java.util.Set;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-
-import net.floodlightcontroller.counter.CounterValue.CounterType;
-
-
-/**
- * This module needs to be updated with CounterValue.
- * 
- * This is a crumby attempt at a highly concurrent implementation of the Counter interface.
- * 
- * (Help! Help!  Someone please re-write me!  This will almost certainly break at high loads.)
- * 
- * The gist is that this class, ConcurrentCounter, keeps an internal highly transient buffer that is occasionally flushed
- * in to a set of CountBuffers (circular buffers) which store a longer term historical view of the count values at different
- * moments in time.
- * 
- * This Counter implementation may be a bit over-engineered...  The goal here was to present an implementation that is very
- * predictable with respect to memory and CPU time and, at the same time, present a very fast increment() method.  The reasoning
- * here is that this will be a go-to class when it comes to debugging, particularly in high-load situations where logging
- * may introduce so much variability to the system that it foils the results.
- * 
- * @author kyle
- *
- */
-public class ConcurrentCounter implements ICounter {
-
-  protected static final Map<DateSpan, Integer> MAX_HISTORY = new HashMap<DateSpan, Integer>();
-  static {
-    MAX_HISTORY.put(DateSpan.REALTIME, new Integer(1));
-    MAX_HISTORY.put(DateSpan.SECONDS, new Integer(120));
-    MAX_HISTORY.put(DateSpan.MINUTES, new Integer(60));
-    MAX_HISTORY.put(DateSpan.HOURS, new Integer(48));
-    MAX_HISTORY.put(DateSpan.DAYS, new Integer(60));
-    MAX_HISTORY.put(DateSpan.WEEKS, new Integer(2)); 
-  }
-  
-  protected static Set<ConcurrentCounter> liveCounters;
-  
-  static {
-    liveCounters = Collections.newSetFromMap(new ConcurrentHashMap<ConcurrentCounter, Boolean>()); //nifty way to get concurrent hash set
-    //Set a background thread to flush any liveCounters every 100 milliseconds
-    Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {
-        public void run() {
-            for(ConcurrentCounter c : liveCounters) {
-                c.flush();
-            }
-        }}, 100, 100, TimeUnit.MILLISECONDS);
-  }
-
-  /**
-   * Very simple data structure to store off a single count entry at a single point in time
-   * @author kyle
-   *
-   */
-  protected static final class CountAtom {
-    protected Date date;
-    protected Long delta;
-    
-    protected CountAtom(Date date, Long delta) {
-      this.date = date;
-      this.delta = delta;
-    }
-    
-    public String toString() {
-      return "[" + this.date + ": " + this.delta + "]";
-    }
-  }
-
-  
-  protected Queue<CountAtom> unprocessedCountBuffer;
-  protected Map<DateSpan, CountBuffer> counts;
-  protected Date startDate;
-  
-  /**
-   * Factory method to create a new counter instance.  (Design note - 
-   * use a factory pattern here as it may be necessary to hook in other
-   * registrations around counter objects as they are created.)
-   * 
-   * @param startDate
-   * @return
-   */
-  public static ICounter createCounter(Date startDate) {
-    ConcurrentCounter cc = new ConcurrentCounter(startDate);
-    ConcurrentCounter.liveCounters.add(cc);
-    return cc;
-    
-  }
-  
-  /**
-   * Protected constructor - use createCounter factory method instead
-   * @param startDate
-   */
-  protected ConcurrentCounter(Date startDate) {
-    init(startDate);
-  }
-  
-  protected void init(Date startDate) {
-    this.startDate = startDate;
-    this.unprocessedCountBuffer = new ConcurrentLinkedQueue<CountAtom>();
-    this.counts = new HashMap<DateSpan, CountBuffer>();
-      
-    for(DateSpan ds : DateSpan.values()) {
-      CountBuffer cb = new CountBuffer(startDate, ds, MAX_HISTORY.get(ds));
-      counts.put(ds, cb);
-    }
-  }
-  /**
-   * This is the key method that has to be both fast and very thread-safe.
-   */
-  @Override
-  public void increment() {
-    this.increment(new Date(), (long)1);
-  }
-  
-  @Override
-  public void increment(Date d, long delta) {
-    this.unprocessedCountBuffer.add(new CountAtom(d, delta));
-  }
-  
-  @Override
-  public void setCounter(Date d, CounterValue value) {
-      // To be done later
-  }
-  
-  /**
-   * Reset the value.
-   */
-  @Override
-  public void reset(Date startDate) {
-    init(startDate);
-  }
-  
-  /**
-   * Flushes values out of the internal buffer and in to structures
-   * that can be fetched with a call to snapshot()
-   */
-  public synchronized void flush() {
-    for(CountAtom c = this.unprocessedCountBuffer.poll(); c != null; c = this.unprocessedCountBuffer.poll()) {
-      for(DateSpan ds : DateSpan.values()) {
-        CountBuffer cb = counts.get(ds);
-        cb.increment(c.date, c.delta);
-      }
-    }
-  }
-  
-  @Override
-  public CounterValue getCounterValue() {
-      // To be done later
-      //CountSeries cs = counts.get(DateSpan.REALTIME).snapshot();
-      //return cs.getSeries()[0];
-      return new CounterValue(CounterType.LONG);
-  }
-  
-  @Override
-  public Date getCounterDate() {
-      // To be done later
-      //CountSeries cs = counts.get(DateSpan.REALTIME).snapshot();
-      //return cs.getSeries()[0];
-      return new Date();
-  }
-  
-  @Override
-  /**
-   * This method returns a disconnected copy of the underlying CountSeries corresponding to dateSpan.
-   */
-  public CountSeries snapshot(DateSpan dateSpan) {
-    flush();
-    CountSeries cs = counts.get(dateSpan).snapshot();
-    return cs;
-  }
-
-  
-  
-}
diff --git a/src/main/java/net/floodlightcontroller/counter/CountBuffer.java b/src/main/java/net/floodlightcontroller/counter/CountBuffer.java
deleted file mode 100644
index fa45862e8b938cad6a5b7e57600861986a68f7ff..0000000000000000000000000000000000000000
--- a/src/main/java/net/floodlightcontroller/counter/CountBuffer.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/**
-*    Copyright 2011, Big Switch Networks, Inc. 
-*    Originally created by David Erickson, Stanford University
-* 
-*    Licensed under the Apache License, Version 2.0 (the "License"); you may
-*    not use this file except in compliance with the License. You may obtain
-*    a copy of the License at
-*
-*         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.counter;
-
-import java.util.Date;
-
-import net.floodlightcontroller.counter.ICounter.DateSpan;
-
-
-/**
- * Implements a circular buffer to store the last x time-based counter values.  This is pretty crumby
- * implementation, basically wrapping everything with synchronized blocks, in order to ensure that threads
- * which will be updating the series don't result in a thread which is reading the series getting stuck with
- * a start date which does not correspond to the count values in getSeries.
- * 
- * This could probably use a re-think...
- * 
- * @author kyle
- *
- */
-public class CountBuffer {
-  protected long[] counterValues;
-  protected Date startDate;
-  protected DateSpan dateSpan;
-  protected int currentIndex;
-  protected int seriesLength;
-
-
-  public CountBuffer(Date startDate, DateSpan dateSpan, int seriesLength) {
-    this.seriesLength = seriesLength;
-    this.counterValues = new long[seriesLength];
-    this.dateSpan = dateSpan;
-    
-    this.startDate = startDate;
-    this.currentIndex = 0;
-  }
-  
-  /**
-   * Increment the count associated with Date d, forgetting some of the older count values if necessary to ensure
-   * that the total span of time covered by this series corresponds to DateSpan * seriesLength (circular buffer).
-   * 
-   * Note - fails silently if the Date falls prior to the start of the tracked count values.
-   * 
-   * Note - this should be a reasonably fast method, though it will have to block if there is another thread reading the
-   * series at the same time.
-   * 
-   * @param d
-   * @param delta
-   */
-  public synchronized void increment(Date d, long delta) {
-
-    long dsMillis = CountSeries.dateSpanToMilliseconds(this.dateSpan);
-    Date endDate = new Date(startDate.getTime() + seriesLength * dsMillis - 1);
-
-    if(d.getTime() < startDate.getTime()) {
-      return; //silently fail rather than insert a count at a time older than the history buffer we're keeping
-    }
-    else if (d.getTime() >= startDate.getTime() && d.getTime() <= endDate.getTime()) {
-        int index = (int)  (( d.getTime() - startDate.getTime() ) / dsMillis); // java rounds down on long/long
-        int modIndex = (index + currentIndex) % seriesLength;
-        long currentValue = counterValues[modIndex];
-        counterValues[modIndex] = currentValue + delta;
-    }
-    else if (d.getTime() > endDate.getTime()) {
-      //Initialize new buckets
-      int newBuckets = (int)((d.getTime() - endDate.getTime()) / dsMillis) + 1; // java rounds down on long/long
-      for(int i = 0; i < newBuckets; i++) {
-        int modIndex = (i + currentIndex) % seriesLength;
-        counterValues[modIndex] = 0;
-      }
-      //Update internal vars
-      this.startDate = new Date(startDate.getTime() + dsMillis * newBuckets);
-      this.currentIndex = (currentIndex + newBuckets) % this.seriesLength;    
-
-      //Call again (date should be in the range this time)
-      this.increment(d, delta);
-    }
-  }
-  
-  /**
-   * Relatively slow method, expected to be called primarily from UI rather than from in-packet-path.
-   * 
-   * @return the count values associated with each time interval starting with startDate and demarc'ed by dateSpan
-   */
-  public long[] getSeries() { //synchronized here should lock on 'this', implying that it shares the lock with increment
-    long[] ret = new long[this.seriesLength];
-    for(int i = 0; i < this.seriesLength; i++) {
-      int modIndex = (currentIndex + i) % this.seriesLength;
-      ret[i] = this.counterValues[modIndex];
-    }
-    return ret;
-  }
-
-  
-  /**
-   * Returns an immutable count series that represents a snapshot of this
-   * series at a specific moment in time.
-   * @return
-   */
-  public synchronized CountSeries snapshot() {
-    long[] cvs = new long[this.seriesLength];
-    for(int i = 0; i < this.seriesLength; i++) {
-      int modIndex = (this.currentIndex + i) % this.seriesLength;
-      cvs[i] = this.counterValues[modIndex];
-    }
-
-    return new CountSeries(this.startDate, this.dateSpan, cvs);
-  }
-  
-}
diff --git a/src/main/java/net/floodlightcontroller/counter/CountSeries.java b/src/main/java/net/floodlightcontroller/counter/CountSeries.java
deleted file mode 100644
index e8a547a516bab83395aa9b73affd425e85b897bd..0000000000000000000000000000000000000000
--- a/src/main/java/net/floodlightcontroller/counter/CountSeries.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/**
-*    Copyright 2011, Big Switch Networks, Inc. 
-*    Originally created by David Erickson, Stanford University
-* 
-*    Licensed under the Apache License, Version 2.0 (the "License"); you may
-*    not use this file except in compliance with the License. You may obtain
-*    a copy of the License at
-*
-*         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.counter;
-
-import java.util.Arrays;
-import java.util.Date;
-
-import net.floodlightcontroller.counter.ICounter.DateSpan;
-
-/**
- * Simple immutable class to store a series of historic counter values
- * 
- * This could probably use a re-think...
- * 
- * @author kyle
- *
- */
-public class CountSeries {  
-  protected long[] counterValues;
-  protected Date startDate;
-  protected DateSpan dateSpan;
-  
-  public CountSeries(Date startDate, DateSpan dateSpan, long[] counterValues) {
-    this.counterValues = counterValues.clone();
-    this.dateSpan = dateSpan;    
-    this.startDate = startDate;
-  }
-  
-
-  public long[] getSeries() { //synchronized here should lock on 'this', implying that it shares the lock with increment
-    return this.counterValues.clone();
-  }
-  
-  /**
-   * Returns the startDate of this series.  The first long in getSeries represents the sum of deltas from increment calls with dates
-   * that correspond to >= startDate and < startDate + DateSpan.
-   * @return
-   */
-  public Date getStartDate() {//synchronized here should lock on 'this', implying that it shares the lock with increment
-    return this.startDate;
-  }
-  
-  public String toString() {
-    String ret = "{start: " + this.startDate + ", span: " + this.dateSpan + ", series: " + Arrays.toString(getSeries()) + "}";
-    return ret;
-  }
-  
-  /**
-   * Return a long that is the number of milliseconds in a ds (second/minute/hour/day/week).  (Utility method.)
-   * 
-   * @param ds
-   * @return
-   */
-  public static final long dateSpanToMilliseconds(DateSpan ds) {
-    long delta = 1;
-    switch(ds) {
-	    case WEEKS:
-	    	delta *= 7;
-	    case DAYS:
-	    	delta *= 24;
-	    case HOURS:
-	    	delta *= 60;
-	    case MINUTES:
-	    	delta *= 60;
-	    case SECONDS:
-	    	delta *= 1000;
-	    default:
-	    	break;
-    }
-    return delta;
-  }
-
-}
diff --git a/src/main/java/net/floodlightcontroller/counter/CounterStore.java b/src/main/java/net/floodlightcontroller/counter/CounterStore.java
index 16465ba630aa9fd43747d08e9037110200d76052..bfe3b963f82b61bc0529005e4edd5b1f0b4d5164 100644
--- a/src/main/java/net/floodlightcontroller/counter/CounterStore.java
+++ b/src/main/java/net/floodlightcontroller/counter/CounterStore.java
@@ -1,7 +1,7 @@
 /**
- *    Copyright 2011, Big Switch Networks, Inc. 
+ *    Copyright 2011, Big Switch Networks, Inc.
  *    Originally created by David Erickson, Stanford University
- * 
+ *
  *    Licensed under the Apache License, Version 2.0 (the "License"); you may
  *    not use this file except in compliance with the License. You may obtain
  *    a copy of the License at
@@ -15,9 +15,6 @@
  *    under the License.
  **/
 
-/**
- * Implements a very simple central store for system counters
- */
 package net.floodlightcontroller.counter;
 
 import java.util.ArrayList;
@@ -27,11 +24,6 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-
-import javax.annotation.PostConstruct;
-
 import net.floodlightcontroller.core.IOFSwitch;
 import net.floodlightcontroller.core.module.FloodlightModuleContext;
 import net.floodlightcontroller.core.module.FloodlightModuleException;
@@ -46,10 +38,16 @@ import org.openflow.protocol.OFPacketIn;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-
 /**
- * @author kyle
+ * Implements a central store for system counters. These counters include
+ * overall packet-in, packet-out, and flow-mod counters. Additional packet-in
+ * counters are maintained for bcast/unicast/multicast traffic, as well as counters
+ * for traffic types based on ethertype and ip-proto (maintained on a per switch
+ * and controller level). These counters are maintained without the involvement of
+ * any other module in the system. For per-module counters and other detailed
+ * debug services, consider IDebugCounterService.
  *
+ *  @authors Kyle, Kanzhe, Mandeep and Saurav
  */
 public class CounterStore implements IFloodlightModule, ICounterStoreService {
     protected static Logger log = LoggerFactory.getLogger(CounterStore.class);
@@ -70,69 +68,102 @@ public class CounterStore implements IFloodlightModule, ICounterStoreService {
           public void set(int val) { value = val; }
         }
 
-    /**
-     * A map of counterName --> Counter
-     */
-    protected ConcurrentHashMap<String, CounterEntry> nameToCEIndex = 
-            new ConcurrentHashMap<String, CounterEntry>();
+    protected class CounterKeyTuple {
+        byte msgType;
+        long dpid;
+        short l3type;
+        byte l4type;
+
+        public CounterKeyTuple(byte msgType, long dpid, short l3type, byte l4type){
+            this.msgType = msgType;
+            this.dpid = dpid;
+            this.l3type = l3type;
+            this.l4type = l4type;
+        }
 
-    protected ICounter heartbeatCounter;
-    protected ICounter randomCounter;
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) return true;
+            if (obj == null) return false;
+            if (!(obj instanceof CounterKeyTuple)) return false;
+            CounterKeyTuple other = (CounterKeyTuple) obj;
+            if (this.msgType == other.msgType &&
+                this.dpid == other.dpid &&
+                this.l3type == other.l3type &&
+                this.l4type == other.l4type)
+                    return true;
+            return false;
+        }
 
-    protected ConcurrentHashMap<String, List<ICounter>>
-        pktinCounters = new ConcurrentHashMap<String, List<ICounter>>();
-    protected ConcurrentHashMap<String, List<ICounter>>
-        pktoutCounters = new ConcurrentHashMap<String, List<ICounter>>();
+        @Override
+        public int hashCode() {
+            final int prime = 283;
+            int result = 1;
+            result = prime * result + msgType;
+            result = prime * result + (int) (dpid ^ (dpid >>> 32));
+            result = prime * result + l3type;
+            result = prime * result + l4type;
+            return result;
+        }
+    }
+
+    /**
+     * Counter storage across all threads. These are periodically updated from the
+     * local per thread counters by the updateFlush method.
+     */
+    protected ConcurrentHashMap<CounterKeyTuple, List<ICounter>>
+        pktinCounters = new ConcurrentHashMap<CounterKeyTuple, List<ICounter>>();
+    protected ConcurrentHashMap<CounterKeyTuple, List<ICounter>>
+        pktoutCounters = new ConcurrentHashMap<CounterKeyTuple, List<ICounter>>();
 
-    protected final ThreadLocal<Map<String,MutableInt>> pktin_local_buffer =
-        new ThreadLocal<Map<String,MutableInt>>() {
+    /**
+     * Thread local counter stores
+     */
+    protected final ThreadLocal<Map<CounterKeyTuple,MutableInt>> pktin_local_buffer =
+        new ThreadLocal<Map<CounterKeyTuple,MutableInt>>() {
         @Override
-        protected Map<String,MutableInt> initialValue() {
-            return new HashMap<String,MutableInt>();
+        protected Map<CounterKeyTuple,MutableInt> initialValue() {
+            return new HashMap<CounterKeyTuple,MutableInt>();
         }
     };
-    protected final ThreadLocal<Map<String,MutableInt>> pktout_local_buffer =
-        new ThreadLocal<Map<String,MutableInt>>() {
+
+    protected final ThreadLocal<Map<CounterKeyTuple,MutableInt>> pktout_local_buffer =
+        new ThreadLocal<Map<CounterKeyTuple,MutableInt>>() {
         @Override
-        protected Map<String,MutableInt> initialValue() {
-            return new HashMap<String,MutableInt>();
+        protected Map<CounterKeyTuple,MutableInt> initialValue() {
+            return new HashMap<CounterKeyTuple,MutableInt>();
         }
     };
 
+    /**
+     * A cache of counterName --> Counter used to retrieve counters quickly via
+     * string-counter-keys
+     */
+    protected ConcurrentHashMap<String, CounterEntry> nameToCEIndex =
+            new ConcurrentHashMap<String, CounterEntry>();
 
     /**
      * Counter Categories grouped by network layers
      * NetworkLayer -> CounterToCategories
      */
-    protected static Map<NetworkLayer, Map<String, List<String>>> layeredCategories = 
+    protected static Map<NetworkLayer, Map<String, List<String>>> layeredCategories =
             new ConcurrentHashMap<NetworkLayer, Map<String, List<String>>> ();
 
-    public void updatePacketInCounters(IOFSwitch sw, OFMessage m, Ethernet eth) {
-        if (((OFPacketIn)m).getPacketData().length <= 0) {
-            return;
-        }
-
-        List<ICounter> counters = this.getPacketInCounters(sw, m, eth);
-        if (counters != null) {
-            for (ICounter c : counters) {
-                c.increment();
-            }
-        }
-        return;
-    }
+    //*******************************
+    //   ICounterStoreService
+    //*******************************
 
     @Override
     public void updatePacketInCountersLocal(IOFSwitch sw, OFMessage m, Ethernet eth) {
         if (((OFPacketIn)m).getPacketData().length <= 0) {
             return;
         }
-
-        String countersKey = this.getCountersKey(sw, m, eth);
-        Map<String, MutableInt> pktin_buffer = this.pktin_local_buffer.get();
+        CounterKeyTuple countersKey = this.getCountersKey(sw, m, eth);
+        Map<CounterKeyTuple, MutableInt> pktin_buffer = this.pktin_local_buffer.get();
         MutableInt currval = pktin_buffer.get(countersKey);
 
-        if ( currval == null ) {
-            this.getPacketInCounters(sw, m, eth); // create counters as side effect (if required)
+        if (currval == null) {
+            this.createPacketInCounters(sw, m, eth); // create counters as side effect (if required)
             currval = new MutableInt();
             pktin_buffer.put(countersKey, currval);
         }
@@ -140,30 +171,13 @@ public class CounterStore implements IFloodlightModule, ICounterStoreService {
         return;
     }
 
-    /**
-     * This method can only be used to update packetOut and flowmod counters
-     *  NOTE: flowmod is counted per switch and for controller, not per port/proto
-     *
-     * @param sw
-     * @param m
-     */
-    public void updatePktOutFMCounterStore(IOFSwitch sw, OFMessage m) {
-        List<ICounter> counters = this.getPktOutFMCounters(sw, m);
-        if (counters != null) {
-            for (ICounter c : counters) {
-                c.increment();
-            }
-        }
-        return;
-    }
-
     @Override
     public void updatePktOutFMCounterStoreLocal(IOFSwitch sw, OFMessage m) {
-        String countersKey = this.getCountersKey(sw, m, null);
-        Map<String, MutableInt> pktout_buffer = this.pktout_local_buffer.get();
+        CounterKeyTuple countersKey = this.getCountersKey(sw, m, null);
+        Map<CounterKeyTuple, MutableInt> pktout_buffer = this.pktout_local_buffer.get();
         MutableInt currval = pktout_buffer.get(countersKey);
 
-        if ( currval == null ) {
+        if (currval == null) {
             this.getPktOutFMCounters(sw, m); // create counters as side effect (if required)
             currval = new MutableInt();
             pktout_buffer.put(countersKey, currval);
@@ -175,8 +189,8 @@ public class CounterStore implements IFloodlightModule, ICounterStoreService {
     @Override
     public void updateFlush() {
         Date date = new Date();
-        Map<String, MutableInt> pktin_buffer = this.pktin_local_buffer.get();
-        for (String key : pktin_buffer.keySet()) {
+        Map<CounterKeyTuple, MutableInt> pktin_buffer = this.pktin_local_buffer.get();
+        for (CounterKeyTuple key : pktin_buffer.keySet()) {
                 MutableInt currval = pktin_buffer.get(key);
                 int delta = currval.get();
 
@@ -192,8 +206,8 @@ public class CounterStore implements IFloodlightModule, ICounterStoreService {
         // We could do better "GC" of counters that have not been update "recently"
         pktin_buffer.clear();
 
-        Map<String, MutableInt> pktout_buffer = this.pktout_local_buffer.get();
-        for (String key : pktout_buffer.keySet()) {
+        Map<CounterKeyTuple, MutableInt> pktout_buffer = this.pktout_local_buffer.get();
+        for (CounterKeyTuple key : pktout_buffer.keySet()) {
                 MutableInt currval = pktout_buffer.get(key);
                 int delta = currval.get();
 
@@ -210,56 +224,102 @@ public class CounterStore implements IFloodlightModule, ICounterStoreService {
         pktout_buffer.clear();
     }
 
-    protected String getCountersKey(IOFSwitch sw, OFMessage m, Ethernet eth) {
+    @Override
+    public ICounter createCounter(String key, CounterValue.CounterType type) {
+        CounterEntry ce;
+        ICounter c;
+
+        c = SimpleCounter.createCounter(new Date(), type);
+        ce = new CounterEntry();
+        ce.counter = c;
+        ce.title = key;
+        nameToCEIndex.putIfAbsent(key, ce);
+
+        return nameToCEIndex.get(key).counter;
+    }
+
+    @Override
+    public ICounter getCounter(String key) {
+        CounterEntry counter = nameToCEIndex.get(key);
+        if (counter != null) {
+            return counter.counter;
+        } else {
+            return null;
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see net.floodlightcontroller.counter.ICounterStoreService#getAll()
+     */
+    @Override
+    public Map<String, ICounter> getAll() {
+        Map<String, ICounter> ret = new ConcurrentHashMap<String, ICounter>();
+        for(Map.Entry<String, CounterEntry> counterEntry : this.nameToCEIndex.entrySet()) {
+            String key = counterEntry.getKey();
+            ICounter counter = counterEntry.getValue().counter;
+            ret.put(key, counter);
+        }
+        return ret;
+    }
+
+    @Override
+    public List<String> getAllCategories(String counterName, NetworkLayer layer) {
+        if (layeredCategories.containsKey(layer)) {
+            Map<String, List<String>> counterToCategories = layeredCategories.get(layer);
+            if (counterToCategories.containsKey(counterName)) {
+                return counterToCategories.get(counterName);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Create a title based on switch ID, portID, vlanID, and counterName
+     * If portID is -1, the title represents the given switch only
+     * If portID is a non-negative number, the title represents the port on the given switch
+     */
+    public static String createCounterName(String switchID, int portID, String counterName) {
+        if (portID < 0) {
+            return switchID + TitleDelimitor + counterName;
+        } else {
+            return switchID + TitleDelimitor + portID + TitleDelimitor + counterName;
+        }
+    }
+
+    //*******************************
+    //   Internal Methods
+    //*******************************
+
+    protected CounterKeyTuple getCountersKey(IOFSwitch sw, OFMessage m, Ethernet eth) {
         byte mtype = m.getType().getTypeValue();
-        //long swid = sw.getId();
-        String swsid = sw.getStringId();
-        short port = 0;
         short l3type = 0;
         byte l4type = 0;
-        
+
         if (eth != null) {
-            // Packet in counters
-            // Need port and protocol level differentiation
-            OFPacketIn packet = (OFPacketIn)m;
-            port = packet.getInPort();
             l3type = eth.getEtherType();
-            if (l3type == (short)0x0800) {
+            if (eth.getPayload() instanceof IPv4) {
                 IPv4 ipV4 = (IPv4)eth.getPayload();
                 l4type = ipV4.getProtocol();
             }
         }
-
-        /* If possible, find and return counters for this tuple
-         *
-         * NOTE: this can be converted to a tuple for better performance,
-         * for now we are using a string representation as a the key
-         */
-        String countersKey =
-            Byte.toString(mtype) + "-" +
-            swsid + "-" + Short.toString(port) + "-" +
-            Short.toString(l3type) + "-" +
-            Byte.toString(l4type);
-        return countersKey;
+        return new CounterKeyTuple(mtype, sw.getId(), l3type, l4type);
     }
 
-    protected List<ICounter> getPacketInCounters(IOFSwitch sw, OFMessage m, Ethernet eth) {
+    protected List<ICounter> createPacketInCounters(IOFSwitch sw, OFMessage m, Ethernet eth) {
         /* If possible, find and return counters for this tuple */
-        String countersKey = this.getCountersKey(sw, m, eth);
+        CounterKeyTuple countersKey = this.getCountersKey(sw, m, eth);
         List<ICounter> counters =
                 this.pktinCounters.get(countersKey);
         if (counters != null) {
                 return counters;
         }
-        
+
         /*
          *  Create the required counters
          */
         counters = new ArrayList<ICounter>();
 
-        /* values for names */
-        short port = ((OFPacketIn)m).getInPort();
-        short l3type = eth.getEtherType();
+        int l3type = eth.getEtherType() & 0xffff;
         String switchIdHex = sw.getStringId();
         String etherType = String.format("%04x", eth.getEtherType());
         String packetName = m.getType().toClass().getName();
@@ -285,14 +345,14 @@ public class CounterStore implements IFloodlightModule, ICounterStoreService {
         if (l3type < 0x0600) {
             etherType = "0599";
         }
-        if (TypeAliases.l3TypeAliasMap != null && 
+        if (TypeAliases.l3TypeAliasMap != null &&
             TypeAliases.l3TypeAliasMap.containsKey(etherType)) {
             etherType = TypeAliases.l3TypeAliasMap.get(etherType);
         }
         else {
             etherType = "L3_" + etherType;
         }
-   
+
         // overall controller packet counter names
         String controllerCounterName =
             CounterStore.createCounterName(
@@ -310,14 +370,6 @@ public class CounterStore implements IFloodlightModule, ICounterStoreService {
         counters.add(createCounter(switchCounterName,
                                    CounterType.LONG));
 
-        String portCounterName =
-            CounterStore.createCounterName(
-                switchIdHex,
-                port,
-                packetName);
-        counters.add(createCounter(portCounterName,
-                                   CounterType.LONG));
-
         // L2 counter names
             String controllerL2CategoryCounterName =
                 CounterStore.createCounterName(
@@ -339,16 +391,6 @@ public class CounterStore implements IFloodlightModule, ICounterStoreService {
             counters.add(createCounter(switchL2CategoryCounterName,
                                        CounterType.LONG));
 
-            String portL2CategoryCounterName =
-                CounterStore.createCounterName(
-                    switchIdHex,
-                    port,
-                    packetName,
-                    l2Type,
-                    NetworkLayer.L2);
-            counters.add(createCounter(portL2CategoryCounterName,
-                                       CounterType.LONG));
-
         // L3 counter names
             String controllerL3CategoryCounterName =
                 CounterStore.createCounterName(
@@ -370,23 +412,13 @@ public class CounterStore implements IFloodlightModule, ICounterStoreService {
             counters.add(createCounter(switchL3CategoryCounterName,
                                        CounterType.LONG));
 
-            String portL3CategoryCounterName =
-                CounterStore.createCounterName(
-                    switchIdHex,
-                    port,
-                    packetName,
-                    etherType,
-                    NetworkLayer.L3);
-            counters.add(createCounter(portL3CategoryCounterName,
-                                       CounterType.LONG));
-
         // L4 counters
-        if (l3type == (short)0x0800) {
+        if (eth.getPayload() instanceof IPv4) {
 
             // resolve protocol alias
             IPv4 ipV4 = (IPv4)eth.getPayload();
             String l4name = String.format("%02x", ipV4.getProtocol());
-            if (TypeAliases.l4TypeAliasMap != null && 
+            if (TypeAliases.l4TypeAliasMap != null &&
                 TypeAliases.l4TypeAliasMap.containsKey(l4name)) {
                 l4name = TypeAliases.l4TypeAliasMap.get(l4name);
             }
@@ -415,25 +447,16 @@ public class CounterStore implements IFloodlightModule, ICounterStoreService {
             counters.add(createCounter(switchL4CategoryCounterName,
                                        CounterType.LONG));
 
-            String portL4CategoryCounterName =
-                CounterStore.createCounterName(
-                    switchIdHex,
-                    port,
-                    packetName,
-                    l4name,
-                    NetworkLayer.L4);
-            counters.add(createCounter(portL4CategoryCounterName,
-                                       CounterType.LONG));
         }
 
         /* Add to map and return */
         this.pktinCounters.putIfAbsent(countersKey, counters);
         return this.pktinCounters.get(countersKey);
     }
-    
+
     protected List<ICounter> getPktOutFMCounters(IOFSwitch sw, OFMessage m) {
         /* If possible, find and return counters for this tuple */
-        String countersKey = this.getCountersKey(sw, m, null);
+        CounterKeyTuple countersKey = this.getCountersKey(sw, m, null);
         List<ICounter> counters =
             this.pktoutCounters.get(countersKey);
         if (counters != null) {
@@ -472,26 +495,13 @@ public class CounterStore implements IFloodlightModule, ICounterStoreService {
 
     }
 
-    /**
-     * Create a title based on switch ID, portID, vlanID, and counterName
-     * If portID is -1, the title represents the given switch only
-     * If portID is a non-negative number, the title represents the port on the given switch
-     */
-    public static String createCounterName(String switchID, int portID, String counterName) {
-        if (portID < 0) {
-            return switchID + TitleDelimitor + counterName;
-        } else {
-            return switchID + TitleDelimitor + portID + TitleDelimitor + counterName;
-        }
-    }
-
     /**
      * Create a title based on switch ID, portID, vlanID, counterName, and subCategory
      * If portID is -1, the title represents the given switch only
      * If portID is a non-negative number, the title represents the port on the given switch
      * For example: PacketIns can be further categorized based on L2 etherType or L3 protocol
      */
-    public static String createCounterName(String switchID, int portID, String counterName,
+    protected static String createCounterName(String switchID, int portID, String counterName,
             String subCategory, NetworkLayer layer) {
         String fullCounterName = "";
         String groupCounterName = "";
@@ -504,7 +514,7 @@ public class CounterStore implements IFloodlightModule, ICounterStoreService {
             fullCounterName = groupCounterName + TitleDelimitor + subCategory;
         }
 
-        Map<String, List<String>> counterToCategories;      
+        Map<String, List<String>> counterToCategories;
         if (layeredCategories.containsKey(layer)) {
             counterToCategories = layeredCategories.get(layer);
         } else {
@@ -526,69 +536,9 @@ public class CounterStore implements IFloodlightModule, ICounterStoreService {
         return fullCounterName;
     }
 
-    @Override
-    public List<String> getAllCategories(String counterName, NetworkLayer layer) {
-        if (layeredCategories.containsKey(layer)) {
-            Map<String, List<String>> counterToCategories = layeredCategories.get(layer);
-            if (counterToCategories.containsKey(counterName)) {
-                return counterToCategories.get(counterName);
-            }
-        }
-        return null;
-    }
-    
-    @Override
-    public ICounter createCounter(String key, CounterValue.CounterType type) {
-        CounterEntry ce;
-        ICounter c;
-
-        c = SimpleCounter.createCounter(new Date(), type);
-        ce = new CounterEntry();
-        ce.counter = c;
-        ce.title = key;
-        nameToCEIndex.putIfAbsent(key, ce);
-        
-        return nameToCEIndex.get(key).counter;
-    }
-
-    /**
-     * Post construction init method to kick off the health check and random (test) counter threads
-     */
-    @PostConstruct
-    public void startUp() {
-        this.heartbeatCounter = this.createCounter("CounterStore heartbeat", CounterValue.CounterType.LONG);
-        this.randomCounter = this.createCounter("CounterStore random", CounterValue.CounterType.LONG);
-        //Set a background thread to flush any liveCounters every 100 milliseconds
-        Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {
-            public void run() {
-                heartbeatCounter.increment();
-                randomCounter.increment(new Date(), (long) (Math.random() * 100)); //TODO - pull this in to random timing
-            }}, 100, 100, TimeUnit.MILLISECONDS);
-    }
-    
-    @Override
-    public ICounter getCounter(String key) {
-        CounterEntry counter = nameToCEIndex.get(key);
-        if (counter != null) {
-            return counter.counter;
-        } else {
-            return null;
-        }
-    }
-
-    /* (non-Javadoc)
-     * @see net.floodlightcontroller.counter.ICounterStoreService#getAll()
-     */
-    @Override
-    public Map<String, ICounter> getAll() {
-        Map<String, ICounter> ret = new ConcurrentHashMap<String, ICounter>();
-        for(Map.Entry<String, CounterEntry> counterEntry : this.nameToCEIndex.entrySet()) {
-            String key = counterEntry.getKey();
-            ICounter counter = counterEntry.getValue().counter;
-            ret.put(key, counter);
-        }
-        return ret;
-    }
+    //*******************************
+    //   IFloodlightProvider
+    //*******************************
 
     @Override
     public Collection<Class<? extends IFloodlightService>> getModuleServices() {
@@ -602,7 +552,7 @@ public class CounterStore implements IFloodlightModule, ICounterStoreService {
     public Map<Class<? extends IFloodlightService>, IFloodlightService>
             getServiceImpls() {
         Map<Class<? extends IFloodlightService>,
-            IFloodlightService> m = 
+            IFloodlightService> m =
                 new HashMap<Class<? extends IFloodlightService>,
                     IFloodlightService>();
         m.put(ICounterStoreService.class, this);
@@ -625,4 +575,5 @@ public class CounterStore implements IFloodlightModule, ICounterStoreService {
     public void startUp(FloodlightModuleContext context) {
         // no-op for now
     }
+
 }
diff --git a/src/main/java/net/floodlightcontroller/counter/ICounter.java b/src/main/java/net/floodlightcontroller/counter/ICounter.java
index b7fb73630de0a85321f575963c9b6224bc2afbe0..0e31fdecd6a75419b9ccab92cd4a94e33f6f8cda 100644
--- a/src/main/java/net/floodlightcontroller/counter/ICounter.java
+++ b/src/main/java/net/floodlightcontroller/counter/ICounter.java
@@ -1,7 +1,7 @@
 /**
-*    Copyright 2011, Big Switch Networks, Inc. 
+*    Copyright 2011, Big Switch Networks, Inc.
 *    Originally created by David Erickson, Stanford University
-* 
+*
 *    Licensed under the Apache License, Version 2.0 (the "License"); you may
 *    not use this file except in compliance with the License. You may obtain
 *    a copy of the License at
@@ -28,46 +28,37 @@ import java.util.Date;
  *
  */
 public interface ICounter {
-  
+
   /**
    * Most commonly used method
    */
   public void increment();
-  
+
   /**
    * Used primarily for flushing thread local updates
    */
   public void increment(Date d, long delta);
-  
+
   /**
    * Counter value setter
    */
   public void setCounter(Date d, CounterValue value);
-  
+
   /**
    * Return the most current value
    */
   public Date getCounterDate();
-  
+
   /**
    * Return the most current value
    */
   public CounterValue getCounterValue();
-  
+
   /**
    * Reset the value
    */
   public void reset(Date d);
-  
-  /**
-   * Returns a CountSeries that is a snapshot of the counter's values for the given dateSpan.  (Further changes
-   * to this counter won't be reflected in the CountSeries that comes  back.)
-   * 
-   * @param dateSpan
-   * @return
-   */
-  public CountSeries snapshot(DateSpan dateSpan);
-  
+
 
   public static enum DateSpan {
     REALTIME,
diff --git a/src/main/java/net/floodlightcontroller/counter/ICounterStoreService.java b/src/main/java/net/floodlightcontroller/counter/ICounterStoreService.java
index c516d8f858e4c7a6efd71dcb1fa5bef97a5cc4f6..c0cbd55916086103bb4df820ca1b33974ed3dcca 100644
--- a/src/main/java/net/floodlightcontroller/counter/ICounterStoreService.java
+++ b/src/main/java/net/floodlightcontroller/counter/ICounterStoreService.java
@@ -35,27 +35,25 @@ public interface ICounterStoreService extends IFloodlightService {
     public final static String BROADCAST = "broadcast";
     public final static String MULTICAST = "multicast";
     public final static String UNICAST = "unicast";
-    
+
     /** L2 EtherType subCategories */
     public final static String L3ET_IPV4 = "L3_IPv4";
 
     /**
      * Update packetIn counters
-     * 
+     *
      * @param sw
      * @param m
      * @param eth
      */
-    public void updatePacketInCounters(IOFSwitch sw, OFMessage m, Ethernet eth);
     public void updatePacketInCountersLocal(IOFSwitch sw, OFMessage m, Ethernet eth);
-    
+
     /**
      * This method can only be used to update packetOut and flowmod counters
-     * 
+     *
      * @param sw
      * @param ofMsg
      */
-    public void updatePktOutFMCounterStore(IOFSwitch sw, OFMessage ofMsg);
     public void updatePktOutFMCounterStoreLocal(IOFSwitch sw, OFMessage ofMsg);
 
     /**
@@ -63,7 +61,7 @@ public interface ICounterStoreService extends IFloodlightService {
      *
      */
     public void updateFlush();
-    
+
     /**
      * Retrieve a list of subCategories by counterName.
      * null if nothing.
@@ -72,9 +70,9 @@ public interface ICounterStoreService extends IFloodlightService {
                                          NetworkLayer layer);
 
     /**
-     * Create a new ICounter and set the title.  Note that the title must be 
+     * Create a new ICounter and set the title.  Note that the title must be
      * unique, otherwise this will throw an IllegalArgumentException.
-     * 
+     *
      * @param key
      * @param type
      * @return
@@ -88,7 +86,7 @@ public interface ICounterStoreService extends IFloodlightService {
 
     /**
      * Returns an immutable map of title:counter with all of the counters in the store.
-     * 
+     *
      * (Note - this method may be slow - primarily for debugging/UI)
      */
     public Map<String, ICounter> getAll();
diff --git a/src/main/java/net/floodlightcontroller/counter/NullCounterStore.java b/src/main/java/net/floodlightcontroller/counter/NullCounterStore.java
index 167b4ed54e4f2b1a070c56ba99b4ee35731ee3c3..bdcc690b349c4497d8ca7b645b23a03d3af2ce85 100644
--- a/src/main/java/net/floodlightcontroller/counter/NullCounterStore.java
+++ b/src/main/java/net/floodlightcontroller/counter/NullCounterStore.java
@@ -47,22 +47,12 @@ public class NullCounterStore implements IFloodlightModule,
     private ICounter emptyCounter;
     private List<String> emptyList;
     private Map<String, ICounter> emptyMap;
-    
-    @Override
-    public void updatePacketInCounters(IOFSwitch sw, OFMessage m, Ethernet eth) {
-        // no-op
-    }
 
     @Override
     public void updatePacketInCountersLocal(IOFSwitch sw, OFMessage m, Ethernet eth) {
         // no-op
     }
 
-    @Override
-    public void updatePktOutFMCounterStore(IOFSwitch sw, OFMessage ofMsg) {
-        // no-op
-    }
-
     @Override
     public void updatePktOutFMCounterStoreLocal(IOFSwitch sw, OFMessage ofMsg) {
         // no-op
@@ -106,7 +96,7 @@ public class NullCounterStore implements IFloodlightModule,
     public Map<Class<? extends IFloodlightService>, IFloodlightService>
             getServiceImpls() {
         Map<Class<? extends IFloodlightService>,
-            IFloodlightService> m = 
+            IFloodlightService> m =
                 new HashMap<Class<? extends IFloodlightService>,
                         IFloodlightService>();
         m.put(ICounterStoreService.class, this);
diff --git a/src/main/java/net/floodlightcontroller/counter/SimpleCounter.java b/src/main/java/net/floodlightcontroller/counter/SimpleCounter.java
index 01a042845f85b1607776c709f7a94726a0ba1796..dd0daf31797ace63ad0d1c8004ec8b016cb19dc9 100644
--- a/src/main/java/net/floodlightcontroller/counter/SimpleCounter.java
+++ b/src/main/java/net/floodlightcontroller/counter/SimpleCounter.java
@@ -1,7 +1,7 @@
 /**
-*    Copyright 2011, Big Switch Networks, Inc. 
+*    Copyright 2011, Big Switch Networks, Inc.
 *    Originally created by David Erickson, Stanford University
-* 
+*
 *    Licensed under the Apache License, Version 2.0 (the "License"); you may
 *    not use this file except in compliance with the License. You may obtain
 *    a copy of the License at
@@ -16,7 +16,7 @@
 **/
 
 /**
- * 
+ *
  */
 package net.floodlightcontroller.counter;
 
@@ -28,7 +28,7 @@ import java.util.Date;
  * This is a simple counter implementation that doesn't support data series.
  * The idea is that floodlight only keeps the realtime value for each counter,
  * statd, a statistics collection daemon, samples counters at a user-defined interval
- * and pushes the values to a database, which keeps time-based data series. 
+ * and pushes the values to a database, which keeps time-based data series.
  * @author Kanzhe
  *
  */
@@ -37,10 +37,10 @@ public class SimpleCounter implements ICounter {
   protected CounterValue counter;
   protected Date samplingTime;
   protected Date startDate;
-  
+
   /**
-   * Factory method to create a new counter instance.  
-   * 
+   * Factory method to create a new counter instance.
+   *
    * @param startDate
    * @return
    */
@@ -48,10 +48,10 @@ public class SimpleCounter implements ICounter {
     SimpleCounter cc = new SimpleCounter(startDate, type);
     return cc;
   }
-  
+
   /**
-   * Factory method to create a copy of a counter instance.  
-   * 
+   * Factory method to create a copy of a counter instance.
+   *
    * @param startDate
    * @return
    */
@@ -67,7 +67,7 @@ public class SimpleCounter implements ICounter {
      cc.setCounter(copy.getCounterDate(), copy.getCounterValue());
      return cc;
   }
-  
+
   /**
    * Protected constructor - use createCounter factory method instead
    * @param startDate
@@ -75,32 +75,33 @@ public class SimpleCounter implements ICounter {
   protected SimpleCounter(Date startDate, CounterValue.CounterType type) {
     init(startDate, type);
   }
-  
+
   protected void init(Date startDate, CounterValue.CounterType type) {
     this.startDate = startDate;
     this.samplingTime = new Date();
     this.counter = new CounterValue(type);
   }
-  
+
   /**
    * This is the key method that has to be both fast and very thread-safe.
    */
   @Override
   synchronized public void increment() {
-    this.increment(new Date(), (long)1);
+    this.increment(new Date(), 1);
   }
-  
+
   @Override
   synchronized public void increment(Date d, long delta) {
     this.samplingTime = d;
     this.counter.increment(delta);
   }
-  
-  synchronized public void setCounter(Date d, CounterValue value) {
+
+  @Override
+synchronized public void setCounter(Date d, CounterValue value) {
       this.samplingTime = d;
       this.counter = value;
   }
-  
+
   /**
    * This is the method to retrieve the current value.
    */
@@ -116,7 +117,7 @@ public class SimpleCounter implements ICounter {
   synchronized public Date getCounterDate() {
     return this.samplingTime;
   }
-  
+
   /**
    * Reset value.
    */
@@ -124,14 +125,5 @@ public class SimpleCounter implements ICounter {
   synchronized public void reset(Date startDate) {
     init(startDate, this.counter.getType());
   }
-  
-  @Override
-  /**
-   * This method only returns the real-time value.
-   */
-  synchronized public CountSeries snapshot(DateSpan dateSpan) {
-    long[] values = new long[1];
-    values[0] = this.counter.getLong();
-    return new CountSeries(this.samplingTime, DateSpan.DAYS, values);
-  }
+
 }
diff --git a/src/main/java/net/floodlightcontroller/debugcounter/DebugCounter.java b/src/main/java/net/floodlightcontroller/debugcounter/DebugCounter.java
new file mode 100644
index 0000000000000000000000000000000000000000..7aed59a8f30fa7385b3d8ab7e766392b921b2c85
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/debugcounter/DebugCounter.java
@@ -0,0 +1,380 @@
+package net.floodlightcontroller.debugcounter;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.core.module.FloodlightModuleException;
+import net.floodlightcontroller.core.module.IFloodlightModule;
+import net.floodlightcontroller.core.module.IFloodlightService;
+
+/**
+ * This class implements a central store for all counters used for debugging the
+ * system. For counters based on traffic-type, see ICounterStoreService.
+ *
+ * @author Saurav
+ */
+public class DebugCounter implements IFloodlightModule, IDebugCounterService {
+    protected static Logger log = LoggerFactory.getLogger(DebugCounter.class);
+
+    /**
+     * The counter value
+     */
+    protected class MutableLong {
+        long value = 0;
+        public void increment() { value += 1; }
+        public long get() { return value; }
+        public void set(long val) { value = val; }
+      }
+
+    /**
+     * Global debug-counter storage across all threads. These are
+     * updated from the local per thread counters by the flush counters method.
+     */
+    protected ConcurrentHashMap<String, AtomicLong> debugCounters =
+            new ConcurrentHashMap<String, AtomicLong>();
+
+    /**
+     * Thread local debug counters used for maintaining counters local to a thread.
+     */
+    protected final ThreadLocal<Map<String, MutableLong>> threadlocalCounters =
+            new ThreadLocal<Map<String, MutableLong>>() {
+        @Override
+        protected Map<String, MutableLong> initialValue() {
+            return new HashMap<String, MutableLong>();
+        }
+    };
+
+    /**
+     * protected class to store counter information
+     */
+    protected class CounterInfo {
+        String moduleCounterName;
+        String counterDesc;
+        CounterType ctype;
+        String moduleName;
+        String counterName;
+
+        public CounterInfo(String name, String desc, CounterType ctype) {
+            this.moduleCounterName = name;
+            String[] temp = name.split("-");
+            this.moduleName = temp[0];
+            this.counterName = temp[1];
+            this.counterDesc = desc;
+            this.ctype = ctype;
+        }
+
+        public String getModuleCounterName() { return moduleCounterName; }
+        public String getCounterDesc() { return counterDesc; }
+        public CounterType getCtype() { return ctype; }
+        public String getModuleName() { return moduleName; }
+        public String getCounterName() { return counterName; }
+    }
+
+    /**
+     * per module counters, indexed by the module name and storing Counter information.
+     */
+    protected ConcurrentHashMap<String, List<CounterInfo>> moduleCounters =
+            new ConcurrentHashMap<String, List<CounterInfo>>();
+
+    /**
+     * fast global cache for counter names that are currently active
+     */
+    Set<String> currentCounters = Collections.newSetFromMap(
+                                      new ConcurrentHashMap<String,Boolean>());
+
+    /**
+     * Thread local cache for counter names that are currently active.
+     */
+    protected final ThreadLocal<Set<String>> threadlocalCurrentCounters =
+            new ThreadLocal<Set<String>>() {
+        @Override
+        protected Set<String> initialValue() {
+            return new HashSet<String>();
+        }
+    };
+
+   //*******************************
+   //   IDebugCounterService
+   //*******************************
+
+   @Override
+   public boolean registerCounter(String moduleCounterName, String counterDescription,
+                               CounterType counterType) {
+       if (debugCounters.containsKey(moduleCounterName)) {
+           log.error("Cannot register counter: {}. Counter already exists",
+                     moduleCounterName);
+           return false;
+       }
+       String[] temp = moduleCounterName.split("-");
+       if (temp.length < 2) {
+           log.error("Cannot register counter: {}. Name not of type " +
+                     " <module name>-<counter name>", moduleCounterName);
+           return false;
+       }
+
+       // store counter information on a per module basis
+       String moduleName = temp[0];
+       List<CounterInfo> a;
+       if (moduleCounters.containsKey(moduleName)) {
+           a = moduleCounters.get(moduleName);
+       } else {
+           a = new ArrayList<CounterInfo>();
+           moduleCounters.put(moduleName, a);
+       }
+       a.add(new CounterInfo(moduleCounterName, counterDescription, counterType));
+
+       // create counter in global map
+       // and add to counter name cache if it is meant to be always counted
+       if (counterType == CounterType.ALWAYS_COUNT) {
+           currentCounters.add(moduleCounterName);
+           debugCounters.put(moduleCounterName, new AtomicLong());
+       }
+       return true;
+   }
+
+   @Override
+   public void updateCounter(String moduleCounterName) {
+       Map<String, MutableLong> thismap =  this.threadlocalCounters.get();
+       MutableLong ml = thismap.get(moduleCounterName);
+       if (ml == null) {
+           // check locally to see if this counter should be created or not
+           Set<String> thisset = this.threadlocalCurrentCounters.get();
+           if (thisset.contains(moduleCounterName)) {
+               ml = new MutableLong();
+               ml.increment();
+               thismap.put(moduleCounterName, ml);
+           }
+       } else {
+           ml.increment();
+       }
+   }
+
+   @Override
+   public void flushCounters() {
+       Map<String, MutableLong> thismap =  this.threadlocalCounters.get();
+       ArrayList<String> deleteKeys = new ArrayList<String>();
+       for (String key : thismap.keySet()) {
+           MutableLong curval = thismap.get(key);
+           long delta = curval.get();
+           if (delta > 0) {
+               AtomicLong ctr = debugCounters.get(key);
+               if (ctr == null) {
+                   // The global counter does not exist possibly because it has been
+                   // disabled. It should thus be removed from the thread-local
+                   // map (the counter) and set (the counter name). Removing it
+                   // from the threadlocal set ensures that the counter will not be
+                   // recreated (see updateCounter)
+                   Set<String> thisset = this.threadlocalCurrentCounters.get();
+                   thisset.remove(key);
+                   deleteKeys.add(key);
+               } else {
+                   ctr.addAndGet(delta);
+                   curval.set(0);
+               }
+           }
+       }
+       for (String dkey : deleteKeys)
+           thismap.remove(dkey);
+
+       // At this point it is also possible that the threadlocal map/set does not
+       // include a counter that has been enabled and is present in the global
+       // currentCounters set. If so we need to sync such state so that the
+       // thread local counter can be created (in the updateCounter method)
+       Set<String> thisset = this.threadlocalCurrentCounters.get();
+       if (thisset.size() != currentCounters.size()) {
+           thisset.addAll(currentCounters);
+       }
+   }
+
+   @Override
+   public void resetCounter(String moduleCounterName) {
+       if (debugCounters.containsKey(moduleCounterName)) {
+           debugCounters.get(moduleCounterName).set(0);
+       }
+   }
+
+   @Override
+   public void resetAllCounters() {
+       for (AtomicLong v : debugCounters.values()) {
+           v.set(0);
+       }
+   }
+
+   @Override
+   public void resetAllModuleCounters(String moduleName) {
+       List<CounterInfo> cil = moduleCounters.get(moduleName);
+       if (cil != null) {
+           for (CounterInfo ci : cil) {
+               if (debugCounters.containsKey(ci.moduleCounterName)) {
+                   debugCounters.get(ci.moduleCounterName).set(0);
+               }
+           }
+       } else {
+           if (log.isDebugEnabled())
+               log.debug("No module found with name {}", moduleName);
+       }
+   }
+
+   @Override
+   public void enableCtrOnDemand(String moduleCounterName) {
+       currentCounters.add(moduleCounterName);
+       debugCounters.putIfAbsent(moduleCounterName, new AtomicLong());
+   }
+
+   @Override
+   public void disableCtrOnDemand(String moduleCounterName) {
+       String[] temp = moduleCounterName.split("-");
+       if (temp.length < 2) {
+           log.error("moduleCounterName {} not recognized", moduleCounterName);
+           return;
+       }
+       String moduleName = temp[0];
+       List<CounterInfo> cil = moduleCounters.get(moduleName);
+       for (CounterInfo ci : cil) {
+           if (ci.moduleCounterName.equals(moduleCounterName) &&
+               ci.ctype == CounterType.COUNT_ON_DEMAND) {
+               currentCounters.remove(moduleCounterName);
+               debugCounters.remove(moduleCounterName);
+               return;
+           }
+       }
+   }
+
+   @Override
+   public DebugCounterInfo getCounterValue(String moduleCounterName) {
+       if (!debugCounters.containsKey(moduleCounterName)) return null;
+       long counterValue = debugCounters.get(moduleCounterName).longValue();
+
+       String[] temp = moduleCounterName.split("-");
+       if (temp.length < 2) {
+           log.error("moduleCounterName {} not recognized", moduleCounterName);
+           return null;
+       }
+       String moduleName = temp[0];
+       List<CounterInfo> cil = moduleCounters.get(moduleName);
+       for (CounterInfo ci : cil) {
+           if (ci.moduleCounterName.equals(moduleCounterName)) {
+               DebugCounterInfo dci = new DebugCounterInfo();
+               dci.counterInfo = ci;
+               dci.counterValue = counterValue;
+               return dci;
+           }
+       }
+       return null;
+   }
+
+   @Override
+   public List<DebugCounterInfo> getAllCounterValues() {
+       List<DebugCounterInfo> dcilist = new ArrayList<DebugCounterInfo>();
+       for (List<CounterInfo> cil : moduleCounters.values()) {
+           for (CounterInfo ci : cil) {
+               AtomicLong ctr = debugCounters.get(ci.moduleCounterName);
+               if (ctr != null) {
+                   DebugCounterInfo dci = new DebugCounterInfo();
+                   dci.counterInfo = ci;
+                   dci.counterValue = ctr.longValue();
+                   dcilist.add(dci);
+               }
+           }
+       }
+       return dcilist;
+   }
+
+   @Override
+   public List<DebugCounterInfo> getModuleCounterValues(String moduleName) {
+       List<DebugCounterInfo> dcilist = new ArrayList<DebugCounterInfo>();
+       if (moduleCounters.containsKey(moduleName)) {
+           List<CounterInfo> cil = moduleCounters.get(moduleName);
+           for (CounterInfo ci : cil) {
+               AtomicLong ctr = debugCounters.get(ci.moduleCounterName);
+               if (ctr != null) {
+                   DebugCounterInfo dci = new DebugCounterInfo();
+                   dci.counterInfo = ci;
+                   dci.counterValue = ctr.longValue();
+                   dcilist.add(dci);
+               }
+           }
+       }
+       return dcilist;
+   }
+
+   @Override
+   public boolean containsMCName(String moduleCounterName) {
+       if (debugCounters.containsKey(moduleCounterName)) return true;
+       // it is possible that the counter may be disabled
+       for (List<CounterInfo> cil : moduleCounters.values()) {
+           for (CounterInfo ci : cil) {
+               if (ci.moduleCounterName.equals(moduleCounterName))
+                   return true;
+           }
+       }
+       return false;
+   }
+
+   @Override
+   public boolean containsModName(String moduleName) {
+       return  (moduleCounters.containsKey(moduleName)) ? true : false;
+   }
+
+   //*******************************
+   //   Internal Methods
+   //*******************************
+
+   protected void printAllCounters() {
+       for (List<CounterInfo> cilist : moduleCounters.values()) {
+           for (CounterInfo ci : cilist) {
+               log.info("Countername {} Countervalue {}", new Object[] {
+                    ci.moduleCounterName, debugCounters.get(ci.moduleCounterName)
+               });
+           }
+       }
+   }
+
+   //*******************************
+   //   IFloodlightModule
+   //*******************************
+
+   @Override
+   public Collection<Class<? extends IFloodlightService>> getModuleServices() {
+       Collection<Class<? extends IFloodlightService>> l =
+               new ArrayList<Class<? extends IFloodlightService>>();
+       l.add(IDebugCounterService.class);
+       return l;
+   }
+
+   @Override
+   public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
+       Map<Class<? extends IFloodlightService>, IFloodlightService> m =
+               new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
+       m.put(IDebugCounterService.class, this);
+       return m;
+   }
+
+   @Override
+   public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
+       return null;
+   }
+
+   @Override
+   public void init(FloodlightModuleContext context) throws FloodlightModuleException {
+
+   }
+
+   @Override
+   public void startUp(FloodlightModuleContext context) {
+
+   }
+
+}
diff --git a/src/main/java/net/floodlightcontroller/debugcounter/DebugCounterGetResource.java b/src/main/java/net/floodlightcontroller/debugcounter/DebugCounterGetResource.java
new file mode 100644
index 0000000000000000000000000000000000000000..395e00c102201f4eb49f8ddea69c76a3297cd2a3
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/debugcounter/DebugCounterGetResource.java
@@ -0,0 +1,130 @@
+package net.floodlightcontroller.debugcounter;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import net.floodlightcontroller.debugcounter.IDebugCounterService.DebugCounterInfo;
+
+import org.restlet.resource.Get;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Return the debug counter data for the get rest-api call
+ *
+ * URI must be in one of the following forms:
+ * "http://{controller-hostname}:8080/wm/core/debugcounter/{param}/json
+ *
+ *  where {param} must be one of (no quotes):
+ *       "all"                  returns value/info on all active counters.
+ *       "{moduleName}"         returns value/info on all active counters for the specified module.
+ *       "{moduleCounterName}"  returns value/info for specific counter if it is enabled.
+ *
+ * @author Saurav
+ */
+public class DebugCounterGetResource extends DebugCounterResourceBase {
+    protected static Logger logger =
+            LoggerFactory.getLogger(DebugCounterGetResource.class);
+
+    /**
+     * The output JSON model that contains the counter information
+     */
+    public static class DebugCounterInfoOutput {
+        public Map<String, DebugCounterInfo> counterMap;
+        public String error;
+
+        DebugCounterInfoOutput() {
+            counterMap = new HashMap<String, DebugCounterInfo>();
+            error = null;
+        }
+        public Map<String, DebugCounterInfo> getCounterMap() {
+            return counterMap;
+        }
+
+        public String getError() {
+            return error;
+        }
+
+    }
+
+    public enum Option {
+        ALL, ONE_MODULE, ONE_MODULE_COUNTER, ERROR_BAD_MODULE_NAME, ERROR_BAD_PARAM,
+        ERROR_BAD_MODULE_COUNTER_NAME
+    }
+
+    @Get("json")
+    public DebugCounterInfoOutput handleCounterInfoQuery() {
+        DebugCounterInfoOutput output = new DebugCounterInfoOutput();
+        Option choice = Option.ERROR_BAD_PARAM;
+
+        String param = (String)getRequestAttributes().get("param");
+        if (param == null) {
+            param = "all";
+            choice = Option.ALL;
+        } else if (param.equals("all")) {
+            choice = Option.ALL;
+        } else if (param.contains("-")) {
+            // differentiate between disabled and non-existing counters
+            boolean isRegistered = debugCounter.containsMCName(param);
+            if (isRegistered) {
+                choice = Option.ONE_MODULE_COUNTER;
+            } else {
+                choice = Option.ERROR_BAD_MODULE_COUNTER_NAME;
+            }
+        } else {
+            boolean isRegistered = debugCounter.containsModName(param);
+            if (isRegistered) {
+                choice = Option.ONE_MODULE;
+            } else {
+                choice = Option.ERROR_BAD_MODULE_NAME;
+            }
+        }
+
+        switch (choice) {
+            case ALL:
+                poplulateAllCounters(debugCounter.getAllCounterValues(), output);
+                break;
+            case ONE_MODULE:
+                populateModuleCounters(debugCounter.getModuleCounterValues(param), output);
+                break;
+            case ONE_MODULE_COUNTER:
+                populateSingleCounter(debugCounter.getCounterValue(param), output);
+                break;
+            case ERROR_BAD_MODULE_NAME:
+                output.error = "Module name has no corresponding registered counters";
+                break;
+            case ERROR_BAD_MODULE_COUNTER_NAME:
+                output.error = "Counter not registered";
+                break;
+            case ERROR_BAD_PARAM:
+                output.error = "Bad param";
+        }
+
+        return output;
+    }
+
+    private void populateSingleCounter(DebugCounterInfo debugCounterInfo,
+                                       DebugCounterInfoOutput output) {
+        if (debugCounterInfo != null)
+            output.counterMap.put(debugCounterInfo.counterInfo.moduleCounterName,
+                                  debugCounterInfo);
+    }
+
+    private void populateModuleCounters(List<DebugCounterInfo> moduleCounterValues,
+                                        DebugCounterInfoOutput output) {
+        for (DebugCounterInfo dci : moduleCounterValues) {
+            populateSingleCounter(dci, output);
+        }
+    }
+
+    private void poplulateAllCounters(List<DebugCounterInfo> allCounterValues,
+                                      DebugCounterInfoOutput output) {
+        for (DebugCounterInfo dci : allCounterValues) {
+            populateSingleCounter(dci, output);
+        }
+    }
+
+
+
+}
diff --git a/src/main/java/net/floodlightcontroller/debugcounter/DebugCounterResetResource.java b/src/main/java/net/floodlightcontroller/debugcounter/DebugCounterResetResource.java
new file mode 100644
index 0000000000000000000000000000000000000000..2833f487766683eb3cbb7dbdf3ccdc5ed05ade4e
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/debugcounter/DebugCounterResetResource.java
@@ -0,0 +1,98 @@
+package net.floodlightcontroller.debugcounter;
+
+import org.restlet.resource.Get;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Reset debug counter values
+ *
+ * URI must be in one of the following forms:
+ * "http://{controller-hostname}:8080/wm/core/debugcounter/reset/{param}/json
+ *
+ *  where {param} must be one of (no quotes):
+ *       "all"                  resets all active counters.
+ *       "{moduleName}"         resets all active counters for the specified module.
+ *       "{moduleCounterName}"  resets specific counter if it is enabled.
+ *
+ * @author Saurav
+ */
+public class DebugCounterResetResource extends DebugCounterResourceBase {
+    protected static Logger logger =
+            LoggerFactory.getLogger(DebugCounterGetResource.class);
+
+    public enum Option {
+        ALL, ONE_MODULE, ONE_MODULE_COUNTER, ERROR_BAD_MODULE_NAME, ERROR_BAD_PARAM,
+        ERROR_BAD_MODULE_COUNTER_NAME
+    }
+
+    public static class ResetOutput {
+        String error;
+
+        public ResetOutput() {
+            error = null;
+        }
+
+        public String getError() {
+            return error;
+        }
+
+    }
+
+    @Get("json")
+    public ResetOutput handleCounterResetCmd() {
+        Option choice = Option.ERROR_BAD_PARAM;
+        ResetOutput output = new ResetOutput();
+
+        String param = (String)getRequestAttributes().get("param");
+        if (param == null) {
+            param = "all";
+            choice = Option.ALL;
+        } else if (param.equals("all")) {
+            choice = Option.ALL;
+        } else if (param.contains("-")) {
+            // differentiate between disabled and non-existing counters
+            boolean isRegistered = debugCounter.containsMCName(param);
+            if (isRegistered) {
+                choice = Option.ONE_MODULE_COUNTER;
+            } else {
+                choice = Option.ERROR_BAD_MODULE_COUNTER_NAME;
+            }
+        } else {
+            boolean isRegistered = debugCounter.containsModName(param);
+            if (isRegistered) {
+                choice = Option.ONE_MODULE;
+            } else {
+                choice = Option.ERROR_BAD_MODULE_NAME;
+            }
+        }
+
+        switch (choice) {
+            case ALL:
+                debugCounter.resetAllCounters();
+                output.error = "None";
+                break;
+            case ONE_MODULE:
+                debugCounter.resetAllModuleCounters(param);
+                output.error = "None";
+                break;
+            case ONE_MODULE_COUNTER:
+                debugCounter.resetCounter(param);
+                output.error = "None";
+                break;
+            case ERROR_BAD_MODULE_NAME:
+                output.error = "Module name has no corresponding registered counters";
+                break;
+            case ERROR_BAD_MODULE_COUNTER_NAME:
+                output.error = "Counter not registered";
+                break;
+            case ERROR_BAD_PARAM:
+                output.error = "Bad param";
+        }
+
+        return output;
+    }
+
+
+
+}
diff --git a/src/main/java/net/floodlightcontroller/debugcounter/DebugCounterResourceBase.java b/src/main/java/net/floodlightcontroller/debugcounter/DebugCounterResourceBase.java
new file mode 100644
index 0000000000000000000000000000000000000000..9edd47473a75564334c217b240002612d31e6219
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/debugcounter/DebugCounterResourceBase.java
@@ -0,0 +1,16 @@
+package net.floodlightcontroller.debugcounter;
+
+import org.restlet.resource.ResourceException;
+import org.restlet.resource.ServerResource;
+
+public class DebugCounterResourceBase extends ServerResource {
+
+    protected IDebugCounterService debugCounter;
+
+    @Override
+    protected void doInit() throws ResourceException {
+        super.doInit();
+        debugCounter = (IDebugCounterService)getContext().getAttributes().
+                get(IDebugCounterService.class.getCanonicalName());
+    }
+}
diff --git a/src/main/java/net/floodlightcontroller/debugcounter/DebugCounterStateResource.java b/src/main/java/net/floodlightcontroller/debugcounter/DebugCounterStateResource.java
new file mode 100644
index 0000000000000000000000000000000000000000..40f56d1f2d14bcf94ff2b7ec1fa30d825beea1cf
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/debugcounter/DebugCounterStateResource.java
@@ -0,0 +1,63 @@
+package net.floodlightcontroller.debugcounter;
+
+import org.restlet.resource.Get;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Enable/disable on-demand counters
+ *
+ * URI must be in one of the following forms:
+ * "http://{controller-hostname}:8080/wm/core/debugcounter/{moduleCounterName}/{state}/json
+ *
+ *  where {state} must be one of (no quotes):
+ *       "enable"        enables counter {moduleCounterName} if it is an on-demand counter.
+ *       "disable"       disables counter {moduleCounterName} if it is an on-demand counter.
+ *
+ * @author Saurav
+ */
+public class DebugCounterStateResource extends DebugCounterResourceBase {
+
+    protected static Logger logger =
+            LoggerFactory.getLogger(DebugCounterStateResource.class);
+
+    public static class StateOutput {
+        String error;
+
+        public StateOutput() {
+            error = null;
+        }
+
+        public String getError() {
+            return error;
+        }
+
+    }
+
+    @Get("json")
+    public StateOutput handleCounterStateCmd() {
+        StateOutput output = new StateOutput();
+
+        String state = (String)getRequestAttributes().get("state");
+        String moduleCounterName = (String)getRequestAttributes().get("moduleCounterName");
+
+        if (!moduleCounterName.contains("-")) {
+            output.error = "Specified moduleCounterName is not of type " +
+                    "<moduleName>-<counterName>.";
+            return output;
+        }
+
+        if ( !(state.equals("enable") || state.equals("disable")) ) {
+            output.error = "State must be either enable or disable";
+            return output;
+        }
+
+        if (state.equals("enable")) {
+            debugCounter.enableCtrOnDemand(moduleCounterName);
+        } else {
+            debugCounter.disableCtrOnDemand(moduleCounterName);
+        }
+        output.error = "None";
+        return output;
+    }
+}
diff --git a/src/main/java/net/floodlightcontroller/debugcounter/IDebugCounterService.java b/src/main/java/net/floodlightcontroller/debugcounter/IDebugCounterService.java
new file mode 100644
index 0000000000000000000000000000000000000000..18fab72cbb7bfe43035377d720b0718b7d4e1331
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/debugcounter/IDebugCounterService.java
@@ -0,0 +1,159 @@
+package net.floodlightcontroller.debugcounter;
+
+import net.floodlightcontroller.core.module.IFloodlightService;
+import net.floodlightcontroller.debugcounter.DebugCounter.CounterInfo;
+import java.util.List;
+
+public interface IDebugCounterService extends IFloodlightService {
+
+    /**
+     * Different counter types. Counters that are meant to be counted on demand
+     * need to be separately enabled/disabled.
+     */
+    public enum CounterType {
+        ALWAYS_COUNT,
+        COUNT_ON_DEMAND
+    }
+
+    public class DebugCounterInfo {
+        CounterInfo counterInfo;
+        Long counterValue;
+
+        public CounterInfo getCounterInfo() {
+            return counterInfo;
+        }
+        public Long getCounterValue() {
+            return counterValue;
+        }
+    }
+
+    /**
+     * All modules that wish to have the DebugCounterService count for them, must
+     * register their counters by making this call (typically from that module's
+     * 'startUp' method). The counter can then be updated, displayed, reset etc.
+     * using the registered moduleCounterName.
+     *
+     * @param moduleCounterName    the counter name which MUST be have the following
+     *                             syntax:  <module name>-<counter name>
+     *                             eg.: linkdiscovery-incoming
+     *                             There should be only a single '-' in the name
+     * @param counterDescription   a descriptive string that gives more information
+     *                             of what the counter is measuring. For example,
+     *                             "Measures the number of incoming packets seen by
+     *                             this module".
+     * @param counterType          One of CounterType. COUNT_ON_DEMAND counter types
+     *                             need to be explicitly enabled/disabled using other
+     *                             methods in this API -- i.e. registering them is
+     *                             not enough to start counting.
+     * @return                     false if the counter has already been registered
+     *                             or if the moduleCounterName is not as expected.
+     */
+    public boolean registerCounter(String moduleCounterName, String counterDescription,
+                                   CounterType counterType);
+
+    /**
+     * Increments the counter by 1, if the counter is meant to be always counted,
+     * or if the counter has been enabled for counting.
+     * @param moduleCounterName   the registered counter name.
+     */
+    public void updateCounter(String moduleCounterName);
+
+    /**
+     * Update the global counter map with values from the thread local maps. This
+     * method is not intended for use by any module. It's typical usage is from
+     * floodlight core. As far as the modules are concerned, this should happen
+     * automatically for their counters.
+     */
+    public void flushCounters();
+
+    /**
+     * Resets the value of the counter to zero if it is currently enabled. Note
+     * that with live traffic, it is not necessary that the counter will display
+     * zero with a get call as it may get updated between the reset and get calls.
+     * @param moduleCounterName the registered counter name.
+     */
+    public void resetCounter(String moduleCounterName);
+
+    /**
+     * Resets the values of all counters that are currently enabled to zero.
+     */
+    public void resetAllCounters();
+
+    /**
+     * Resets the values of all counters that are currently active and belong
+     * to a module with the given 'moduleName'. The moduleName MUST be the
+     * part of the moduleCounterName with which the counters were registered.
+     * eg. if 'linkdiscovery-incoming' and 'linkdiscovery-lldpeol' are two counters
+     * the module name is 'linkdiscovery'
+     * @param moduleName
+     */
+    public void resetAllModuleCounters(String moduleName);
+
+    /**
+     * This method applies only to CounterType.COUNT_ON_DEMAND. It is used to
+     * enable counting on the counter. Note that this step is necessary to start
+     * counting for these counter types - merely registering the counter is not
+     * enough (as is the case for CounterType.ALWAYS_COUNT). Note that newly
+     * enabled counter starts from an initial value of zero.
+     *
+     * @param moduleCounterName  the registered counter name.
+     */
+    public void enableCtrOnDemand(String moduleCounterName);
+
+    /**
+     * This method applies only to CounterType.ALWAYS_COUNT. It is used to disable
+     * counting on this counter. Note that disabling a counter results in a loss
+     * of the counter value. When re-enabled the counter will restart from zero.
+     *
+     * @param moduleCounterName the registered counter name.
+     */
+    public void disableCtrOnDemand(String moduleCounterName);
+
+    /**
+     * Get counter value and associated information for a specific counter if it
+     * is active.
+     *
+     * @param moduleCounterName
+     * @return DebugCounterInfo or null if the counter could not be found
+     */
+    public DebugCounterInfo getCounterValue(String moduleCounterName);
+
+    /**
+     * Get counter values and associated information for all active counters
+     *
+     * @return the list of values/info or an empty list
+     */
+    public  List<DebugCounterInfo> getAllCounterValues();
+
+    /**
+     * Get counter values and associated information for all active counters associated
+     * with a module.
+     *
+     * @param moduleName
+     * @return the list of values/info or an empty list
+     */
+    public  List<DebugCounterInfo> getModuleCounterValues(String moduleName);
+
+    /**
+     * Convenience method to figure out if the the given 'moduleCounterName' corresponds
+     * to a registered moduleCounterName or not. Note that the counter may or
+     * may not be enabled for counting, but if it is registered the method will
+     * return true.
+     *
+     * @param param
+     * @return false if moduleCounterName is not a registered counter
+     */
+    public boolean containsMCName(String moduleCounterName);
+
+    /**
+     * Convenience method to figure out if the the given 'moduleName' corresponds
+     * to a registered moduleName or not. Note that the module may or may not have
+     * a counter enabled for counting, but if it is registered the method will
+     * return true.
+     *
+     * @param param
+     * @return false if moduleName is not a registered counter
+     */
+    public boolean containsModName(String moduleName);
+
+}
diff --git a/src/main/java/net/floodlightcontroller/debugcounter/NullDebugCounter.java b/src/main/java/net/floodlightcontroller/debugcounter/NullDebugCounter.java
new file mode 100644
index 0000000000000000000000000000000000000000..5e5ffbba2f3de68af207d63c08909451bd032186
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/debugcounter/NullDebugCounter.java
@@ -0,0 +1,112 @@
+package net.floodlightcontroller.debugcounter;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.core.module.FloodlightModuleException;
+import net.floodlightcontroller.core.module.IFloodlightModule;
+import net.floodlightcontroller.core.module.IFloodlightService;
+
+public class NullDebugCounter implements IFloodlightModule, IDebugCounterService {
+
+    @Override
+    public boolean registerCounter(String moduleCounterName,
+                                   String counterDescription,
+                                   CounterType counterType) {
+        return false;
+    }
+
+    @Override
+    public Collection<Class<? extends IFloodlightService>>
+            getModuleServices() {
+        return null;
+    }
+
+    @Override
+    public Map<Class<? extends IFloodlightService>, IFloodlightService>
+            getServiceImpls() {
+        return null;
+    }
+
+    @Override
+    public Collection<Class<? extends IFloodlightService>>
+            getModuleDependencies() {
+        return null;
+    }
+
+    @Override
+    public
+            void
+            init(FloodlightModuleContext context)
+                                                 throws FloodlightModuleException {
+
+    }
+
+    @Override
+    public void startUp(FloodlightModuleContext context) {
+
+    }
+
+    @Override
+    public void updateCounter(String moduleCounterName) {
+
+    }
+
+    @Override
+    public void flushCounters() {
+
+    }
+
+    @Override
+    public void resetCounter(String moduleCounterName) {
+
+    }
+
+    @Override
+    public void resetAllCounters() {
+
+    }
+
+    @Override
+    public void resetAllModuleCounters(String moduleName) {
+
+    }
+
+    @Override
+    public void enableCtrOnDemand(String moduleCounterName) {
+
+    }
+
+    @Override
+    public void disableCtrOnDemand(String moduleCounterName) {
+
+    }
+
+    @Override
+    public DebugCounterInfo getCounterValue(String moduleCounterName) {
+        return null;
+    }
+
+    @Override
+    public List<DebugCounterInfo> getAllCounterValues() {
+        return null;
+    }
+
+    @Override
+    public List<DebugCounterInfo> getModuleCounterValues(String moduleName) {
+        return null;
+    }
+
+    @Override
+    public boolean containsMCName(String moduleCounterName) {
+        return false;
+    }
+
+    @Override
+    public boolean containsModName(String moduleName) {
+        return false;
+    }
+
+}
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/IDeviceService.java b/src/main/java/net/floodlightcontroller/devicemanager/IDeviceService.java
index 69fac694665f14e6df08ada226d0a5496e2b9884..5e8f221a9829bdcf25d0f37a41fd33047db3affe 100755
--- a/src/main/java/net/floodlightcontroller/devicemanager/IDeviceService.java
+++ b/src/main/java/net/floodlightcontroller/devicemanager/IDeviceService.java
@@ -51,6 +51,12 @@ public interface IDeviceService extends IFloodlightService {
     public static final String CONTEXT_DST_DEVICE = 
             "net.floodlightcontroller.devicemanager.dstDevice"; 
 
+    /**
+     * The original destination device for the current packet-in
+     */
+    public static final String CONTEXT_ORIG_DST_DEVICE =
+            "net.floodlightcontroller.devicemanager.origDstDevice";
+
     /**
      * A FloodlightContextStore object that can be used to interact with the 
      * FloodlightContext information created by BVS manager.
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/IEntityClassListener.java b/src/main/java/net/floodlightcontroller/devicemanager/IEntityClassListener.java
index 22402ced28f3bb79f57629220a40ed8576c790a2..1b53550f6fe5f047db8160e4399e005c85e08dda 100644
--- a/src/main/java/net/floodlightcontroller/devicemanager/IEntityClassListener.java
+++ b/src/main/java/net/floodlightcontroller/devicemanager/IEntityClassListener.java
@@ -20,7 +20,7 @@ package net.floodlightcontroller.devicemanager;
 import java.util.Set;
 
 /**
- * Implementors of this interface can receive updates from DeviceManager about
+ * Implementors of this interface can receive updates from the Entity Classifier about
  * the changes to entity Classes.
  *
  * @author Ananth Suryanarayana (Ananth.Suryanarayana@bigswitch.com)
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/Device.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/Device.java
index 9fea72297ea0f4c779c45305d435f27ea6af811e..bbbccee7831c20d868ee12ba2678beec9c758486 100755
--- a/src/main/java/net/floodlightcontroller/devicemanager/internal/Device.java
+++ b/src/main/java/net/floodlightcontroller/devicemanager/internal/Device.java
@@ -417,9 +417,11 @@ public class Device implements IDevice {
         if (apMap == null || apMap.isEmpty()) {
             apList.add(newAP);
             attachmentPoints = apList;
-            // there are no old attachment points - we should not treat this
-            // as a device moved.
-            return false;
+            // there are no old attachment points - since the device exists, this
+            // may be because the host really moved (so the old AP port went down);
+            // or it may be because the switch restarted (so old APs were nullified).
+            // For now we will treat both cases as host moved.
+            return true;
         }
 
         long id = topology.getL2DomainId(sw);
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
index 09a46152b41ad25dbc51d057c4ab1c3c23e8a2ef..7a8b5155d3a6ec5c45fef3101f75c0f06b7ac04b 100755
--- a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
+++ b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
@@ -49,6 +49,9 @@ import net.floodlightcontroller.core.module.IFloodlightModule;
 import net.floodlightcontroller.core.module.IFloodlightService;
 import net.floodlightcontroller.core.util.ListenerDispatcher;
 import net.floodlightcontroller.core.util.SingletonTask;
+import net.floodlightcontroller.debugcounter.IDebugCounterService;
+import net.floodlightcontroller.debugcounter.NullDebugCounter;
+import net.floodlightcontroller.debugcounter.IDebugCounterService.CounterType;
 import net.floodlightcontroller.devicemanager.IDevice;
 import net.floodlightcontroller.devicemanager.IDeviceService;
 import net.floodlightcontroller.devicemanager.IEntityClass;
@@ -104,6 +107,7 @@ IFlowReconcileListener, IInfoProvider, IHAListener {
     protected IRestApiService restApi;
     protected IThreadPoolService threadPool;
     protected IFlowReconcileService flowReconcileMgr;
+    protected IDebugCounterService debugCounters;
 
     /**
      * Time in milliseconds before entities will expire
@@ -595,6 +599,7 @@ IFlowReconcileListener, IInfoProvider, IHAListener {
                            FloodlightContext cntx) {
         switch (msg.getType()) {
             case PACKET_IN:
+                debugCounters.updateCounter("devicemanager-incoming");
                 return this.processPacketInMessage(sw,
                                                    (OFPacketIn) msg, cntx);
             default:
@@ -716,6 +721,7 @@ IFlowReconcileListener, IInfoProvider, IHAListener {
         this.threadPool = fmc.getServiceImpl(IThreadPoolService.class);
         this.flowReconcileMgr = fmc.getServiceImpl(IFlowReconcileService.class);
         this.entityClassifier = fmc.getServiceImpl(IEntityClassifierService.class);
+        this.debugCounters = fmc.getServiceImpl(IDebugCounterService.class);
     }
 
     @Override
@@ -753,6 +759,18 @@ IFlowReconcileListener, IInfoProvider, IHAListener {
         } else {
             logger.debug("Could not instantiate REST API");
         }
+
+        registerDeviceManagerDebugCounters();
+    }
+
+    private void registerDeviceManagerDebugCounters() {
+        if (debugCounters == null) {
+            logger.error("Debug Counter Service not found.");
+            debugCounters = new NullDebugCounter();
+            return;
+        }
+        debugCounters.registerCounter(getName() + "-" + "incoming",
+            "All incoming packets seen by this module", CounterType.ALWAYS_COUNT);
     }
 
     // ***************
@@ -840,10 +858,10 @@ IFlowReconcileListener, IInfoProvider, IHAListener {
      * @param srcDevice
      */
     private void snoopDHCPClientName(Ethernet eth, Device srcDevice) {
-        if (eth.getEtherType() != Ethernet.TYPE_IPv4)
+        if (! (eth.getPayload() instanceof IPv4) )
             return;
         IPv4 ipv4 = (IPv4) eth.getPayload();
-        if (ipv4.getProtocol() != IPv4.PROTOCOL_UDP)
+        if (! (ipv4.getPayload() instanceof UDP) )
             return;
         UDP udp = (UDP) ipv4.getPayload();
         if (!(udp.getPayload() instanceof DHCP))
@@ -1243,9 +1261,9 @@ IFlowReconcileListener, IInfoProvider, IHAListener {
                             device.getEntityClass().getName(), entity);
                 return null;
             }
-            // If this is an internal port we don't learn the new entity
-            // and don't update indexes. We only learn on attachment point
-            // ports.
+            // If this is not an attachment point port we don't learn the new entity
+            // and don't update indexes. But we do allow the device to continue up
+            // the chain.
             if (entity.hasSwitchPort() &&
                     !topology.isAttachmentPointPort(entity.getSwitchDPID(),
                                                  entity.getSwitchPort().shortValue())) {
diff --git a/src/main/java/net/floodlightcontroller/firewall/Firewall.java b/src/main/java/net/floodlightcontroller/firewall/Firewall.java
index c6a4fd763df1df46babb4b92fef411070365d7c8..21dc8aed6ca937f3123e9a00971ee8b0fc13fd80 100644
--- a/src/main/java/net/floodlightcontroller/firewall/Firewall.java
+++ b/src/main/java/net/floodlightcontroller/firewall/Firewall.java
@@ -595,7 +595,7 @@ public class Firewall implements IFirewallService, IOFMessageListener,
             // the case to determine if we have L2 broadcast + L3 unicast
             // don't allow this broadcast packet if such is the case (malformed
             // packet)
-            if (eth.getEtherType() == Ethernet.TYPE_IPv4
+            if ((eth.getPayload() instanceof IPv4)
                     && this.IPIsBroadcast(((IPv4) eth.getPayload())
                             .getDestinationAddress()) == false) {
                 allowBroadcast = false;
diff --git a/src/main/java/net/floodlightcontroller/hub/Hub.java b/src/main/java/net/floodlightcontroller/hub/Hub.java
index 3618351d75cf7fe899400fad41280452600f8a09..70b920345051bb51669ba15df09e787096b3fc3f 100644
--- a/src/main/java/net/floodlightcontroller/hub/Hub.java
+++ b/src/main/java/net/floodlightcontroller/hub/Hub.java
@@ -78,7 +78,7 @@ public class Hub implements IFloodlightModule, IOFMessageListener {
         po.setActionsLength((short) OFActionOutput.MINIMUM_LENGTH);
 
         // set data if is is included in the packetin
-        if (pi.getBufferId() == 0xffffffff) {
+        if (pi.getBufferId() == OFPacketOut.BUFFER_ID_NONE) {
             byte[] packetData = pi.getPacketData();
             po.setLength(U16.t(OFPacketOut.MINIMUM_LENGTH
                     + po.getActionsLength() + packetData.length));
diff --git a/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitch.java b/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitch.java
index 4a9ffa35c4e41980e3b7651094b00182156cd87d..2e8ce6f1baf678771543273e80e0f3dad0277054 100644
--- a/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitch.java
+++ b/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitch.java
@@ -1,7 +1,7 @@
 /**
-*    Copyright 2011, Big Switch Networks, Inc. 
+*    Copyright 2011, Big Switch Networks, Inc.
 *    Originally created by David Erickson, Stanford University
-* 
+*
 *    Licensed under the Apache License, Version 2.0 (the "License"); you may
 *    not use this file except in compliance with the License. You may obtain
 *    a copy of the License at
@@ -52,7 +52,6 @@ import net.floodlightcontroller.counter.ICounterStoreService;
 import net.floodlightcontroller.packet.Ethernet;
 import net.floodlightcontroller.restserver.IRestApiService;
 
-import org.openflow.protocol.OFError;
 import org.openflow.protocol.OFFlowMod;
 import org.openflow.protocol.OFFlowRemoved;
 import org.openflow.protocol.OFMatch;
@@ -68,15 +67,15 @@ import org.openflow.util.LRULinkedHashMap;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class LearningSwitch 
+public class LearningSwitch
     implements IFloodlightModule, ILearningSwitchService, IOFMessageListener {
     protected static Logger log = LoggerFactory.getLogger(LearningSwitch.class);
-    
+
     // Module dependencies
     protected IFloodlightProviderService floodlightProvider;
     protected ICounterStoreService counterStore;
     protected IRestApiService restApi;
-    
+
     // Stores the learned state for each switch
     protected Map<IOFSwitch, Map<MacVlanPair,Short>> macVlanToSwitchPortMap;
 
@@ -87,25 +86,25 @@ public class LearningSwitch
     public static final int APP_ID_BITS = 12;
     public static final int APP_ID_SHIFT = (64 - APP_ID_BITS);
     public static final long LEARNING_SWITCH_COOKIE = (long) (LEARNING_SWITCH_APP_ID & ((1 << APP_ID_BITS) - 1)) << APP_ID_SHIFT;
-    
-    // more flow-mod defaults 
+
+    // more flow-mod defaults
     protected static short FLOWMOD_DEFAULT_IDLE_TIMEOUT = 5; // in seconds
     protected static short FLOWMOD_DEFAULT_HARD_TIMEOUT = 0; // infinite
     protected static short FLOWMOD_PRIORITY = 100;
-    
+
     // for managing our map sizes
-    protected static final int MAX_MACS_PER_SWITCH  = 1000;    
+    protected static final int MAX_MACS_PER_SWITCH  = 1000;
 
     // normally, setup reverse flow as well. Disable only for using cbench for comparison with NOX etc.
     protected static final boolean LEARNING_SWITCH_REVERSE_FLOW = true;
-    
+
     /**
      * @param floodlightProvider the floodlightProvider to set
      */
     public void setFloodlightProvider(IFloodlightProviderService floodlightProvider) {
         this.floodlightProvider = floodlightProvider;
     }
-    
+
     @Override
     public String getName() {
         return "learningswitch";
@@ -120,13 +119,13 @@ public class LearningSwitch
      */
     protected void addToPortMap(IOFSwitch sw, long mac, short vlan, short portVal) {
         Map<MacVlanPair,Short> swMap = macVlanToSwitchPortMap.get(sw);
-        
+
         if (vlan == (short) 0xffff) {
             // OFMatch.loadFromPacket sets VLAN ID to 0xffff if the packet contains no VLAN tag;
             // for our purposes that is equivalent to the default VLAN ID 0
             vlan = 0;
         }
-        
+
         if (swMap == null) {
             // May be accessed by REST API so we need to make it thread safe
             swMap = Collections.synchronizedMap(new LRULinkedHashMap<MacVlanPair,Short>(MAX_MACS_PER_SWITCH));
@@ -134,7 +133,7 @@ public class LearningSwitch
         }
         swMap.put(new MacVlanPair(mac, vlan), portVal);
     }
-    
+
     /**
      * Removes a host from the MAC/VLAN->SwitchPort mapping
      * @param sw The switch to remove the mapping from
@@ -164,18 +163,18 @@ public class LearningSwitch
         Map<MacVlanPair,Short> swMap = macVlanToSwitchPortMap.get(sw);
         if (swMap != null)
             return swMap.get(new MacVlanPair(mac, vlan));
-        
+
         // if none found
         return null;
     }
-    
+
     /**
      * Clears the MAC/VLAN -> SwitchPort map for all switches
      */
     public void clearLearnedTable() {
         macVlanToSwitchPortMap.clear();
     }
-    
+
     /**
      * Clears the MAC/VLAN -> SwitchPort map for a single switch
      * @param sw The switch to clear the mapping for
@@ -185,12 +184,12 @@ public class LearningSwitch
         if (swMap != null)
             swMap.clear();
     }
-    
+
     @Override
     public synchronized Map<IOFSwitch, Map<MacVlanPair,Short>> getTable() {
         return macVlanToSwitchPortMap;
     }
-    
+
     /**
      * Writes a OFFlowMod to a switch.
      * @param sw The switch tow rite the flowmod to.
@@ -223,7 +222,7 @@ public class LearningSwitch
         //                                            from the length field in the
         //                                            header. */
         //    };
-           
+
         OFFlowMod flowMod = (OFFlowMod) floodlightProvider.getOFMessageFactory().getMessage(OFType.FLOW_MOD);
         flowMod.setMatch(match);
         flowMod.setCookie(LearningSwitch.LEARNING_SWITCH_COOKIE);
@@ -247,12 +246,12 @@ public class LearningSwitch
         flowMod.setLength((short) (OFFlowMod.MINIMUM_LENGTH + OFActionOutput.MINIMUM_LENGTH));
 
         if (log.isTraceEnabled()) {
-            log.trace("{} {} flow mod {}", 
+            log.trace("{} {} flow mod {}",
                       new Object[]{ sw, (command == OFFlowMod.OFPFC_DELETE) ? "deleting" : "adding", flowMod });
         }
 
-        counterStore.updatePktOutFMCounterStore(sw, flowMod);
-        
+        counterStore.updatePktOutFMCounterStoreLocal(sw, flowMod);
+
         // and write it out
         try {
             sw.write(flowMod, null);
@@ -260,11 +259,11 @@ public class LearningSwitch
             log.error("Failed to write {} to switch {}", new Object[]{ flowMod, sw }, e);
         }
     }
-    
+
     /**
      * Pushes a packet-out to a switch.  The assumption here is that
      * the packet-in was also generated from the same switch.  Thus, if the input
-     * port of the packet-in and the outport are the same, the function will not 
+     * port of the packet-in and the outport are the same, the function will not
      * push the packet-out.
      * @param sw        switch that generated the packet-in, and from which packet-out is sent
      * @param match     OFmatch
@@ -276,21 +275,21 @@ public class LearningSwitch
             return;
         }
 
-        // The assumption here is (sw) is the switch that generated the 
+        // The assumption here is (sw) is the switch that generated the
         // packet-in. If the input port is the same as output port, then
         // the packet-out should be ignored.
         if (pi.getInPort() == outport) {
             if (log.isDebugEnabled()) {
-                log.debug("Attempting to do packet-out to the same " + 
-                          "interface as packet-in. Dropping packet. " + 
-                          " SrcSwitch={}, match = {}, pi={}", 
+                log.debug("Attempting to do packet-out to the same " +
+                          "interface as packet-in. Dropping packet. " +
+                          " SrcSwitch={}, match = {}, pi={}",
                           new Object[]{sw, match, pi});
                 return;
             }
         }
 
         if (log.isTraceEnabled()) {
-            log.trace("PacketOut srcSwitch={} match={} pi={}", 
+            log.trace("PacketOut srcSwitch={} match={} pi={}",
                       new Object[] {sw, match, pi});
         }
 
@@ -336,15 +335,15 @@ public class LearningSwitch
             log.error("Failure writing packet out", e);
         }
     }
-    
+
     /**
      * Writes an OFPacketOut message to a switch.
      * @param sw The switch to write the PacketOut to.
      * @param packetInMessage The corresponding PacketIn.
      * @param egressPort The switchport to output the PacketOut.
      */
-    private void writePacketOutForPacketIn(IOFSwitch sw, 
-                                          OFPacketIn packetInMessage, 
+    private void writePacketOutForPacketIn(IOFSwitch sw,
+                                          OFPacketIn packetInMessage,
                                           short egressPort) {
         // from openflow 1.0 spec - need to set these on a struct ofp_packet_out:
         // uint32_t buffer_id; /* ID assigned by datapath (-1 if none). */
@@ -354,7 +353,7 @@ public class LearningSwitch
         /* uint8_t data[0]; */ /* Packet data. The length is inferred
                                   from the length field in the header.
                                   (Only meaningful if buffer_id == -1.) */
-        
+
         OFPacketOut packetOutMessage = (OFPacketOut) floodlightProvider.getOFMessageFactory().getMessage(OFType.PACKET_OUT);
         short packetOutLength = (short)OFPacketOut.MINIMUM_LENGTH; // starting length
 
@@ -363,34 +362,34 @@ public class LearningSwitch
         packetOutMessage.setInPort(packetInMessage.getInPort());
         packetOutMessage.setActionsLength((short)OFActionOutput.MINIMUM_LENGTH);
         packetOutLength += OFActionOutput.MINIMUM_LENGTH;
-        
+
         // set actions
-        List<OFAction> actions = new ArrayList<OFAction>(1);      
+        List<OFAction> actions = new ArrayList<OFAction>(1);
         actions.add(new OFActionOutput(egressPort, (short) 0));
         packetOutMessage.setActions(actions);
 
         // set data - only if buffer_id == -1
         if (packetInMessage.getBufferId() == OFPacketOut.BUFFER_ID_NONE) {
             byte[] packetData = packetInMessage.getPacketData();
-            packetOutMessage.setPacketData(packetData); 
+            packetOutMessage.setPacketData(packetData);
             packetOutLength += (short)packetData.length;
         }
-        
+
         // finally, set the total length
-        packetOutMessage.setLength(packetOutLength);              
-            
+        packetOutMessage.setLength(packetOutLength);
+
         // and write it out
         try {
-        	counterStore.updatePktOutFMCounterStore(sw, packetOutMessage);
+            counterStore.updatePktOutFMCounterStoreLocal(sw, packetOutMessage);
             sw.write(packetOutMessage, null);
         } catch (IOException e) {
             log.error("Failed to write {} to switch {}: {}", new Object[]{ packetOutMessage, sw, e });
         }
     }
-    
+
     /**
      * Processes a OFPacketIn message. If the switch has learned the MAC/VLAN to port mapping
-     * for the pair it will write a FlowMod for. If the mapping has not been learned the 
+     * for the pair it will write a FlowMod for. If the mapping has not been learned the
      * we will flood the packet.
      * @param sw
      * @param pi
@@ -415,7 +414,7 @@ public class LearningSwitch
             // If source MAC is a unicast address, learn the port for this MAC/VLAN
             this.addToPortMap(sw, sourceMac, vlan, pi.getInPort());
         }
-        
+
         // Now output flow-mod and/or packet
         Short outPort = getFromPortMap(sw, destMac, vlan);
         if (outPort == null) {
@@ -483,7 +482,7 @@ public class LearningSwitch
         // it from the macVlanToPortMap to revert to flooding packets to this device.
         this.removeFromPortMap(sw, Ethernet.toLong(match.getDataLayerSource()),
             match.getDataLayerVirtualLan());
-        
+
         // Also, if packets keep coming from another device (e.g. from ping), the
         // corresponding reverse flow entry will never expire on its own and will
         // send the packets to the wrong port (the matching input port of the
@@ -501,9 +500,9 @@ public class LearningSwitch
                 match.getInputPort());
         return Command.CONTINUE;
     }
-    
+
     // IOFMessageListener
-    
+
     @Override
     public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
         switch (msg.getType()) {
@@ -512,10 +511,10 @@ public class LearningSwitch
             case FLOW_REMOVED:
                 return this.processFlowRemovedMessage(sw, (OFFlowRemoved) msg);
             case ERROR:
-                log.info("received an error {} from switch {}", (OFError) msg, sw);
+                log.info("received an error {} from switch {}", msg, sw);
                 return Command.CONTINUE;
             default:
-            	break;
+                break;
         }
         log.error("received an unexpected message {} from switch {}", msg, sw);
         return Command.CONTINUE;
@@ -532,10 +531,10 @@ public class LearningSwitch
     }
 
     // IFloodlightModule
-    
+
     @Override
     public Collection<Class<? extends IFloodlightService>> getModuleServices() {
-        Collection<Class<? extends IFloodlightService>> l = 
+        Collection<Class<? extends IFloodlightService>> l =
                 new ArrayList<Class<? extends IFloodlightService>>();
         l.add(ILearningSwitchService.class);
         return l;
@@ -545,7 +544,7 @@ public class LearningSwitch
     public Map<Class<? extends IFloodlightService>, IFloodlightService>
             getServiceImpls() {
         Map<Class<? extends IFloodlightService>,
-            IFloodlightService> m = 
+            IFloodlightService> m =
                 new HashMap<Class<? extends IFloodlightService>,
                     IFloodlightService>();
         m.put(ILearningSwitchService.class, this);
@@ -555,7 +554,7 @@ public class LearningSwitch
     @Override
     public Collection<Class<? extends IFloodlightService>>
             getModuleDependencies() {
-        Collection<Class<? extends IFloodlightService>> l = 
+        Collection<Class<? extends IFloodlightService>> l =
                 new ArrayList<Class<? extends IFloodlightService>>();
         l.add(IFloodlightProviderService.class);
         l.add(ICounterStoreService.class);
@@ -566,7 +565,7 @@ public class LearningSwitch
     @Override
     public void init(FloodlightModuleContext context)
             throws FloodlightModuleException {
-        macVlanToSwitchPortMap = 
+        macVlanToSwitchPortMap =
                 new ConcurrentHashMap<IOFSwitch, Map<MacVlanPair,Short>>();
         floodlightProvider =
                 context.getServiceImpl(IFloodlightProviderService.class);
@@ -582,7 +581,7 @@ public class LearningSwitch
         floodlightProvider.addOFMessageListener(OFType.FLOW_REMOVED, this);
         floodlightProvider.addOFMessageListener(OFType.ERROR, this);
         restApi.addRestletRoutable(new LearningSwitchWebRoutable());
-        
+
         // read our config options
         Map<String, String> configOptions = context.getConfigParams(this);
         try {
@@ -615,11 +614,11 @@ public class LearningSwitch
                      "using default of {}",
                      FLOWMOD_PRIORITY);
         }
-        log.debug("FlowMod idle timeout set to {} seconds", 
+        log.debug("FlowMod idle timeout set to {} seconds",
                   FLOWMOD_DEFAULT_IDLE_TIMEOUT);
-        log.debug("FlowMod hard timeout set to {} seconds", 
+        log.debug("FlowMod hard timeout set to {} seconds",
                   FLOWMOD_DEFAULT_HARD_TIMEOUT);
-        log.debug("FlowMod priority set to {}", 
+        log.debug("FlowMod priority set to {}",
                 FLOWMOD_PRIORITY);
     }
 }
diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java
index 53cbb3ac89b95e7cad3457c3b3fed67622afcaf5..3e991c514227aa46cce1d2135a8b8edb27ac55f5 100644
--- a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java
+++ b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java
@@ -57,6 +57,9 @@ import net.floodlightcontroller.core.module.FloodlightModuleException;
 import net.floodlightcontroller.core.module.IFloodlightModule;
 import net.floodlightcontroller.core.module.IFloodlightService;
 import net.floodlightcontroller.core.util.SingletonTask;
+import net.floodlightcontroller.debugcounter.IDebugCounterService;
+import net.floodlightcontroller.debugcounter.IDebugCounterService.CounterType;
+import net.floodlightcontroller.debugcounter.NullDebugCounter;
 import net.floodlightcontroller.linkdiscovery.ILinkDiscovery;
 import net.floodlightcontroller.linkdiscovery.ILinkDiscovery.LinkType;
 import net.floodlightcontroller.linkdiscovery.ILinkDiscovery.SwitchType;
@@ -118,7 +121,7 @@ import org.slf4j.LoggerFactory;
 public class LinkDiscoveryManager implements IOFMessageListener,
     IOFSwitchListener, IStorageSourceListener, ILinkDiscoveryService,
     IFloodlightModule, IInfoProvider, IHAListener {
-    protected static Logger log = LoggerFactory.getLogger(LinkDiscoveryManager.class);
+    protected static final Logger log = LoggerFactory.getLogger(LinkDiscoveryManager.class);
 
     // Names of table/fields for links in the storage API
     private static final String TOPOLOGY_TABLE_NAME = "controller_topologyconfig";
@@ -142,6 +145,7 @@ public class LinkDiscoveryManager implements IOFMessageListener,
     protected IStorageSourceService storageSource;
     protected IThreadPoolService threadPool;
     protected IRestApiService restApi;
+    protected IDebugCounterService debugCounters;
 
     // LLDP and BDDP fields
     private static final byte[] LLDP_STANDARD_DST_MAC_STRING =
@@ -510,6 +514,7 @@ public class LinkDiscoveryManager implements IOFMessageListener,
                            FloodlightContext cntx) {
         switch (msg.getType()) {
             case PACKET_IN:
+                debugCounters.updateCounter("linkdiscovery-incoming");
                 return this.handlePacketIn(sw.getId(), (OFPacketIn) msg,
                                            cntx);
             case PORT_STATUS:
@@ -539,7 +544,7 @@ public class LinkDiscoveryManager implements IOFMessageListener,
         Ethernet eth = IFloodlightProviderService.bcStore.get(cntx,
                            IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
 
-        if (eth.getEtherType() == Ethernet.TYPE_BSN) {
+        if (eth.getPayload() instanceof BSN) {
             BSN bsn = (BSN) eth.getPayload();
             if (bsn == null) return Command.STOP;
             if (bsn.getPayload() == null) return Command.STOP;
@@ -548,7 +553,7 @@ public class LinkDiscoveryManager implements IOFMessageListener,
             if (bsn.getPayload() instanceof LLDP == false)
                 return Command.CONTINUE;
             return handleLldp((LLDP) bsn.getPayload(), sw, pi.getInPort(), false, cntx);
-        } else if (eth.getEtherType() == Ethernet.TYPE_LLDP) {
+        } else if (eth.getPayload() instanceof LLDP) {
             return handleLldp((LLDP) eth.getPayload(), sw, pi.getInPort(), true, cntx);
         } else if (eth.getEtherType() < 1500) {
             long destMac = eth.getDestinationMAC().toLong();
@@ -639,7 +644,8 @@ public class LinkDiscoveryManager implements IOFMessageListener,
             // broadcast the packet as a regular packet (after checking IDs)
             if (isStandard) {
                 if (log.isTraceEnabled()) {
-                    log.trace("Got a standard LLDP=[{}]. Not fowarding it.", lldp.toString());
+                    log.trace("Got a standard LLDP=[{}] that was not sent by" +
+                              " this controller. Not fowarding it.", lldp.toString());
                 }
                 return Command.STOP;
             } else if (myId < otherId) {
@@ -764,6 +770,7 @@ public class LinkDiscoveryManager implements IOFMessageListener,
         removeFromMaintenanceQueue(nptDst);
 
         // Consume this message
+        debugCounters.updateCounter("linkdiscovery-lldpeol");
         return Command.STOP;
     }
 
@@ -990,7 +997,8 @@ public class LinkDiscoveryManager implements IOFMessageListener,
         lldpClock = (lldpClock + 1) % LLDP_TO_ALL_INTERVAL;
 
         if (lldpClock == 0) {
-            log.debug("Sending LLDP out on all ports.");
+            if (log.isTraceEnabled())
+                log.trace("Sending LLDP out on all ports.");
             discoverOnAllPorts();
         }
     }
@@ -1344,6 +1352,14 @@ public class LinkDiscoveryManager implements IOFMessageListener,
                                     long dst, short dstPort) {
         return true;
     }
+    @LogMessageDocs({
+        @LogMessageDoc(message="Inter-switch link detected:",
+                explanation="Detected a new link between two openflow switches," +
+                            "use show link to find current status"),
+        @LogMessageDoc(message="Inter-switch link updated:",
+                explanation="Detected a link change between two openflow switches, " +
+                            "use show link to find current status")
+    })
     protected boolean addOrUpdateLink(Link lt, LinkInfo newInfo) {
 
         NodePortTuple srcNpt, dstNpt;
@@ -1398,11 +1414,16 @@ public class LinkDiscoveryManager implements IOFMessageListener,
                 updateOperation = UpdateOperation.LINK_UPDATED;
                 linkChanged = true;
 
-                // Add to event history
+                // Log direct links only. Multi-hop links may be numerous
+                // Add all to event history
+                LinkType linkType = getLinkType(lt, newInfo);
+                if (linkType == ILinkDiscovery.LinkType.DIRECT_LINK) {
+                    log.info("Inter-switch link detected: {}", lt);
+                }
                 evHistTopoLink(lt.getSrc(), lt.getDst(), lt.getSrcPort(),
                                lt.getDstPort(), newInfo.getSrcPortState(),
                                newInfo.getDstPortState(),
-                               getLinkType(lt, newInfo),
+                               linkType,
                                EvAction.LINK_ADDED, "LLDP Recvd");
             } else {
                 // Since the link info is already there, we need to
@@ -1453,15 +1474,16 @@ public class LinkDiscoveryManager implements IOFMessageListener,
                 if (linkChanged) {
                     updateOperation = getUpdateOperation(newInfo.getSrcPortState(),
                                                          newInfo.getDstPortState());
-                    if (log.isTraceEnabled()) {
-                        log.trace("Updated link {}", lt);
+                    LinkType linkType = getLinkType(lt, newInfo);
+                    if (linkType == ILinkDiscovery.LinkType.DIRECT_LINK) {
+                        log.info("Inter-switch link updated: {}", lt);
                     }
                     // Add to event history
                     evHistTopoLink(lt.getSrc(), lt.getDst(),
                                    lt.getSrcPort(), lt.getDstPort(),
                                    newInfo.getSrcPortState(),
                                    newInfo.getDstPortState(),
-                                   getLinkType(lt, newInfo),
+                                   linkType,
                                    EvAction.LINK_PORT_STATE_UPDATED,
                                    "LLDP Recvd");
                 }
@@ -1497,6 +1519,9 @@ public class LinkDiscoveryManager implements IOFMessageListener,
      * @param links
      *            The List of @LinkTuple to delete.
      */
+    @LogMessageDoc(message="Inter-switch link removed:",
+            explanation="A previously detected link between two openflow switches no longer exists, " +
+                        "use show link to find current status")
     protected void deleteLinks(List<Link> links, String reason,
                                List<LDUpdate> updateList) {
 
@@ -1529,11 +1554,12 @@ public class LinkDiscoveryManager implements IOFMessageListener,
                 }
 
                 LinkInfo info = this.links.remove(lt);
+                LinkType linkType = getLinkType(lt, info);
                 linkUpdateList.add(new LDUpdate(lt.getSrc(),
                                                 lt.getSrcPort(),
                                                 lt.getDst(),
                                                 lt.getDstPort(),
-                                                getLinkType(lt, info),
+                                                linkType,
                                                 UpdateOperation.LINK_REMOVED));
 
                 // Update Event History
@@ -1549,7 +1575,9 @@ public class LinkDiscoveryManager implements IOFMessageListener,
                 // TODO Whenever link is removed, it has to checked if
                 // the switchports must be added to quarantine.
 
-                if (log.isTraceEnabled()) {
+                if (linkType == ILinkDiscovery.LinkType.DIRECT_LINK) {
+                    log.info("Inter-switch link removed: {}", lt);
+                } else if (log.isTraceEnabled()) {
                     log.trace("Deleted link {}", lt);
                 }
             }
@@ -2094,6 +2122,7 @@ public class LinkDiscoveryManager implements IOFMessageListener,
         storageSource = context.getServiceImpl(IStorageSourceService.class);
         threadPool = context.getServiceImpl(IThreadPoolService.class);
         restApi = context.getServiceImpl(IRestApiService.class);
+        debugCounters = context.getServiceImpl(IDebugCounterService.class);
 
         // read our config options
         Map<String, String> configOptions = context.getConfigParams(this);
@@ -2176,6 +2205,8 @@ public class LinkDiscoveryManager implements IOFMessageListener,
                       + "switch table {}", SWITCH_CONFIG_TABLE_NAME);
         }
 
+        registerLinkDiscoveryDebugCounters();
+
         ScheduledExecutorService ses = threadPool.getScheduledExecutor();
 
         // To be started by the first switch connection
@@ -2249,6 +2280,18 @@ public class LinkDiscoveryManager implements IOFMessageListener,
         setControllerTLV();
     }
 
+    private void registerLinkDiscoveryDebugCounters() {
+        if (debugCounters == null) {
+            log.error("Debug Counter Service not found.");
+            debugCounters = new NullDebugCounter();
+            return;
+        }
+        debugCounters.registerCounter(getName() + "-" + "incoming",
+            "All incoming packets seen by this module", CounterType.ALWAYS_COUNT);
+        debugCounters.registerCounter(getName() + "-" + "lldpeol",
+            "End of Life for LLDP packets", CounterType.COUNT_ON_DEMAND);
+    }
+
     // ****************************************************
     // Topology Manager's Event History members and methods
     // ****************************************************
diff --git a/src/main/java/net/floodlightcontroller/loadbalancer/LoadBalancer.java b/src/main/java/net/floodlightcontroller/loadbalancer/LoadBalancer.java
index 83b9eaf573ea92e41603eb8bacd706bcf16e32eb..b2a35c2b7ae4a2a3339aa0358510309f8cfbeaa3 100644
--- a/src/main/java/net/floodlightcontroller/loadbalancer/LoadBalancer.java
+++ b/src/main/java/net/floodlightcontroller/loadbalancer/LoadBalancer.java
@@ -69,6 +69,7 @@ import net.floodlightcontroller.devicemanager.IDeviceService;
 import net.floodlightcontroller.devicemanager.SwitchPort;
 import net.floodlightcontroller.packet.ARP;
 import net.floodlightcontroller.packet.Ethernet;
+import net.floodlightcontroller.packet.ICMP;
 import net.floodlightcontroller.packet.IPacket;
 import net.floodlightcontroller.packet.IPv4;
 import net.floodlightcontroller.packet.TCP;
@@ -194,7 +195,7 @@ public class LoadBalancer implements IFloodlightModule,
  
         if (eth.isBroadcast() || eth.isMulticast()) {
             // handle ARP for VIP
-            if (eth.getEtherType() == Ethernet.TYPE_ARP) {
+            if (pkt instanceof ARP) {
                 // retrieve arp to determine target IP address                                                       
                 ARP arpRequest = (ARP) eth.getPayload();
 
@@ -219,17 +220,17 @@ public class LoadBalancer implements IFloodlightModule,
                     IPClient client = new IPClient();
                     client.ipAddress = ip_pkt.getSourceAddress();
                     client.nw_proto = ip_pkt.getProtocol();
-                    if (client.nw_proto == IPv4.PROTOCOL_TCP) {
+                    if (ip_pkt.getPayload() instanceof TCP) {
                         TCP tcp_pkt = (TCP) ip_pkt.getPayload();
                         client.srcPort = tcp_pkt.getSourcePort();
                         client.targetPort = tcp_pkt.getDestinationPort();
                     }
-                    if (client.nw_proto == IPv4.PROTOCOL_UDP) {
+                    if (ip_pkt.getPayload() instanceof UDP) {
                         UDP udp_pkt = (UDP) ip_pkt.getPayload();
                         client.srcPort = udp_pkt.getSourcePort();
                         client.targetPort = udp_pkt.getDestinationPort();
                     }
-                    if (client.nw_proto == IPv4.PROTOCOL_ICMP) {
+                    if (ip_pkt.getPayload() instanceof ICMP) {
                         client.srcPort = 8; 
                         client.targetPort = 0; 
                     }
@@ -268,6 +269,8 @@ public class LoadBalancer implements IFloodlightModule,
                                                               IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
 
         // retrieve original arp to determine host configured gw IP address                                          
+        if (! (eth.getPayload() instanceof ARP))
+            return;
         ARP arpRequest = (ARP) eth.getPayload();
         
         // have to do proxy arp reply since at this point we cannot determine the requesting application type
diff --git a/src/main/java/net/floodlightcontroller/packet/BasePacket.java b/src/main/java/net/floodlightcontroller/packet/BasePacket.java
index 4ecfdedddd813b1fbd42a3ad1a2dbc48eafc45ed..eed530c03d2e8047774697bc70032d58eee63981 100644
--- a/src/main/java/net/floodlightcontroller/packet/BasePacket.java
+++ b/src/main/java/net/floodlightcontroller/packet/BasePacket.java
@@ -17,12 +17,16 @@
 
 package net.floodlightcontroller.packet;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 
 /**
 *
 * @author David Erickson (daviderickson@cs.stanford.edu)
 */
 public abstract class BasePacket implements IPacket {
+    public static final Logger log = LoggerFactory.getLogger(BasePacket.class);
     protected IPacket parent;
     protected IPacket payload;
 
@@ -113,4 +117,4 @@ public abstract class BasePacket implements IPacket {
         pkt.setParent(this.parent);
         return pkt;
     }
-}
\ No newline at end of file
+}
diff --git a/src/main/java/net/floodlightcontroller/packet/Ethernet.java b/src/main/java/net/floodlightcontroller/packet/Ethernet.java
index 44a908118d9e649ec0421f5620684a9d967f6519..4fc2380762a5c71e019886cb6c0da82e6b84fc19 100644
--- a/src/main/java/net/floodlightcontroller/packet/Ethernet.java
+++ b/src/main/java/net/floodlightcontroller/packet/Ethernet.java
@@ -230,7 +230,7 @@ public class Ethernet extends BasePacket {
 
     @Override
     public IPacket deserialize(byte[] data, int offset, int length) {
-        if (length <= 0)
+        if (length <= 16)  // Ethernet packet minium should be 60, this is reasonable
             return null;
         ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
         if (this.destinationMACAddress == null)
@@ -261,13 +261,23 @@ public class Ethernet extends BasePacket {
             Class<? extends IPacket> clazz = Ethernet.etherTypeClassMap.get(this.etherType);
             try {
                 payload = clazz.newInstance();
+                this.payload = payload.deserialize(data, bb.position(), bb.limit()-bb.position());
             } catch (Exception e) {
-                throw new RuntimeException("Error parsing payload for Ethernet packet", e);
+                if (log.isTraceEnabled()) {
+                    log.trace("Failed to parse ethernet packet {}->{}" +
+                            " payload as {}, treat as plain ethernet packet",
+                            new Object[] {this.sourceMACAddress,
+                                          this.destinationMACAddress,
+                                          clazz.getClass().getName()});
+                    log.trace("Exception from parsing {}", e);
+                }
+                payload = new Data();
+                this.payload = payload.deserialize(data, bb.position(), bb.limit()-bb.position());
             }
         } else {
             payload = new Data();
+            this.payload = payload.deserialize(data, bb.position(), bb.limit()-bb.position());
         }
-        this.payload = payload.deserialize(data, bb.position(), bb.limit()-bb.position());
         this.payload.setParent(this);
         return this;
     }
diff --git a/src/main/java/net/floodlightcontroller/packet/IPv4.java b/src/main/java/net/floodlightcontroller/packet/IPv4.java
index 76a140ed002bad4ab93db3488a771b2141223376..afc31425dc5106b9587d03088bfe0135e0b2331d 100644
--- a/src/main/java/net/floodlightcontroller/packet/IPv4.java
+++ b/src/main/java/net/floodlightcontroller/packet/IPv4.java
@@ -43,6 +43,12 @@ public class IPv4 extends BasePacket {
         protocolClassMap.put(PROTOCOL_UDP, UDP.class);
     }
 
+    public static final byte IPV4_FLAGS_MOREFRAG = 0x1;
+    public static final byte IPV4_FLAGS_DONTFRAG = 0x2;
+    public static final byte IPV4_FLAGS_MASK = 0x7;
+    public static final byte IPV4_FLAGS_SHIFT = 13;
+    public static final short IPV4_OFFSET_MASK = (1 << IPV4_FLAGS_SHIFT) - 1;
+
     protected byte version;
     protected byte headerLength;
     protected byte diffServ;
@@ -58,6 +64,7 @@ public class IPv4 extends BasePacket {
     protected byte[] options;
 
     protected boolean isTruncated;
+    protected boolean isFragment;
 
     /**
      * Default constructor that sets the version to 4.
@@ -66,6 +73,7 @@ public class IPv4 extends BasePacket {
         super();
         this.version = 4;
         isTruncated = false;
+        isFragment = false;
     }
 
     /**
@@ -127,6 +135,14 @@ public class IPv4 extends BasePacket {
         this.isTruncated = isTruncated;
     }
 
+    public boolean isFragment() {
+        return isFragment;
+    }
+
+    public void setFragment(boolean isFrag) {
+        this.isFragment = isFrag;
+    }
+
     /**
      * @param identification the identification to set
      */
@@ -308,7 +324,8 @@ public class IPv4 extends BasePacket {
         bb.put(this.diffServ);
         bb.putShort(this.totalLength);
         bb.putShort(this.identification);
-        bb.putShort((short) (((this.flags & 0x7) << 13) | (this.fragmentOffset & 0x1fff)));
+        bb.putShort((short)(((this.flags & IPV4_FLAGS_MASK) << IPV4_FLAGS_SHIFT)
+                | (this.fragmentOffset & IPV4_OFFSET_MASK)));
         bb.put(this.ttl);
         bb.put(this.protocol);
         bb.putShort(this.checksum);
@@ -346,8 +363,8 @@ public class IPv4 extends BasePacket {
         this.totalLength = bb.getShort();
         this.identification = bb.getShort();
         sscratch = bb.getShort();
-        this.flags = (byte) ((sscratch >> 13) & 0x7);
-        this.fragmentOffset = (short) (sscratch & 0x1fff);
+        this.flags = (byte) ((sscratch >> IPV4_FLAGS_SHIFT) & IPV4_FLAGS_MASK);
+        this.fragmentOffset = (short) (sscratch & IPV4_OFFSET_MASK);
         this.ttl = bb.get();
         this.protocol = bb.get();
         this.checksum = bb.getShort();
@@ -361,7 +378,9 @@ public class IPv4 extends BasePacket {
         }
 
         IPacket payload;
-        if (IPv4.protocolClassMap.containsKey(this.protocol)) {
+        isFragment = ((this.flags & IPV4_FLAGS_MOREFRAG) != 0) ||
+                (this.fragmentOffset != 0);
+        if (!isFragment && IPv4.protocolClassMap.containsKey(this.protocol)) {
             Class<? extends IPacket> clazz = IPv4.protocolClassMap.get(this.protocol);
             try {
                 payload = clazz.newInstance();
@@ -369,6 +388,11 @@ public class IPv4 extends BasePacket {
                 throw new RuntimeException("Error parsing payload for IPv4 packet", e);
             }
         } else {
+            if (log.isTraceEnabled() && isFragment) {
+                log.trace("IPv4 fragment detected {}->{}, forward using IP header only",
+                        fromIPv4Address(this.sourceAddress),
+                        fromIPv4Address(this.destinationAddress));
+            }
             payload = new Data();
         }
         int payloadLength = this.totalLength - this.headerLength * 4;
@@ -493,7 +517,7 @@ public class IPv4 extends BasePacket {
      * @return The IP address separated into bytes.
      */
     public static byte[] toIPv4AddressBytes(int ipAddress) {
-    	return new byte[] {
+        return new byte[] {
                 (byte)(ipAddress >>> 24),
                 (byte)(ipAddress >>> 16),
                 (byte)(ipAddress >>> 8),
diff --git a/src/main/java/net/floodlightcontroller/routing/IRoutingDecision.java b/src/main/java/net/floodlightcontroller/routing/IRoutingDecision.java
index 81c3c138f60a59d4eedce92173f2595682347a76..ab09375486b9f61b2cfa98b83a5e9eeb483bd20b 100644
--- a/src/main/java/net/floodlightcontroller/routing/IRoutingDecision.java
+++ b/src/main/java/net/floodlightcontroller/routing/IRoutingDecision.java
@@ -1,7 +1,7 @@
 /**
-*    Copyright 2011, Big Switch Networks, Inc. 
+*    Copyright 2011, Big Switch Networks, Inc.
 *    Originally created by David Erickson, Stanford University
-* 
+*
 *    Licensed under the Apache License, Version 2.0 (the "License"); you may
 *    not use this file except in compliance with the License. You may obtain
 *    a copy of the License at
@@ -29,18 +29,23 @@ public interface IRoutingDecision {
         /*
          * NONE:                    NO-OP, continue with the packet processing chain
          * DROP:                    Drop this packet and this flow
-         * FORWARD:                 Forward this packet, and this flow, to the first (and only device) in getDestinationDevices(),
-         *                          if the destination is not known at this time, initiate a discovery action for it (e.g. ARP)
-         * FORWARD_OR_FLOOD:        Forward this packet, and this flow, to the first (and only device) in getDestinationDevices(),
-         *                          if the destination is not known at this time, flood this packet on the source switch
-         * MULTICAST:               Multicast this packet to all the interfaces and devices attached
+         * FORWARD:                 Forward this packet, and this flow, to the first
+         *                          (and only device) in getDestinationDevices(),
+         *                          if the destination is not known at this time,
+         *                          initiate a discovery action for it (e.g. ARP)
+         * FORWARD_OR_FLOOD:        Forward this packet, and this flow, to the first
+         *                          (and only device) in getDestinationDevices(),
+         *                          if the destination is not known at this time,
+         *                          flood this packet on the source switch
+         * MULTICAST:               Multicast this packet to all the interfaces
+         *                          and devices attached
          */
         NONE, DROP, FORWARD, FORWARD_OR_FLOOD, MULTICAST
     }
-    
+
     public static final FloodlightContextStore<IRoutingDecision> rtStore =
         new FloodlightContextStore<IRoutingDecision>();
-    public static final String CONTEXT_DECISION = 
+    public static final String CONTEXT_DECISION =
             "net.floodlightcontroller.routing.decision";
 
     public void addToContext(FloodlightContext cntx);
diff --git a/src/main/java/net/floodlightcontroller/topology/TopologyInstance.java b/src/main/java/net/floodlightcontroller/topology/TopologyInstance.java
index 84052dbee2baf1136a15c981a2ca839cad80a958..af49de70bbb6ca8f29426bc370d5b343fdc30442 100644
--- a/src/main/java/net/floodlightcontroller/topology/TopologyInstance.java
+++ b/src/main/java/net/floodlightcontroller/topology/TopologyInstance.java
@@ -36,7 +36,7 @@ import net.floodlightcontroller.routing.BroadcastTree;
 import net.floodlightcontroller.routing.Link;
 import net.floodlightcontroller.routing.Route;
 import net.floodlightcontroller.routing.RouteId;
-import net.floodlightcontroller.util.LRUHashMap;
+import com.google.common.cache.*;
 
 /**
  * A representation of a network topology.  Used internally by
@@ -76,7 +76,23 @@ public class TopologyInstance {
     protected Map<Long, BroadcastTree> destinationRootedTrees;
     protected Map<Long, Set<NodePortTuple>> clusterBroadcastNodePorts;
     protected Map<Long, BroadcastTree> clusterBroadcastTrees;
-    protected LRUHashMap<RouteId, Route> pathcache;
+
+    protected class PathCacheLoader extends CacheLoader<RouteId, Route> {
+        TopologyInstance ti;
+        PathCacheLoader(TopologyInstance ti) {
+            this.ti = ti;
+        }
+
+        @Override
+        public Route load(RouteId rid) {
+            return ti.buildroute(rid);
+        }
+    }
+
+    // Path cache loader is defined for loading a path when it not present
+    // in the cache.
+    private final PathCacheLoader pathCacheLoader = new PathCacheLoader(this);
+    protected LoadingCache<RouteId, Route> pathcache;
 
     public TopologyInstance() {
         this.switches = new HashSet<Long>();
@@ -132,7 +148,15 @@ public class TopologyInstance {
         destinationRootedTrees = new HashMap<Long, BroadcastTree>();
         clusterBroadcastTrees = new HashMap<Long, BroadcastTree>();
         clusterBroadcastNodePorts = new HashMap<Long, Set<NodePortTuple>>();
-        pathcache = new LRUHashMap<RouteId, Route>(PATH_CACHE_SIZE);
+
+        pathcache = CacheBuilder.newBuilder().concurrencyLevel(4)
+                    .maximumSize(1000L)
+                    .build(
+                            new CacheLoader<RouteId, Route>() {
+                                public Route load(RouteId rid) {
+                                    return pathCacheLoader.load(rid);
+                                }
+                            });
     }
 
     public void compute() {
@@ -511,7 +535,7 @@ public class TopologyInstance {
     }
 
     protected void calculateShortestPathTreeInClusters() {
-        pathcache.clear();
+        pathcache.invalidateAll();
         destinationRootedTrees.clear();
 
         Map<Link, Integer> linkCost = new HashMap<Link, Integer>();
@@ -664,15 +688,23 @@ public class TopologyInstance {
         return r;
     }
 
+    // NOTE: Return a null route if srcId equals dstId.  The null route
+    // need not be stored in the cache.  Moreover, the LoadingCache will
+    // throw an exception if null route is returned.
     protected Route getRoute(long srcId, long dstId, long cookie) {
+        // Return null route if srcId equals dstId
+        if (srcId == dstId) return null;
+
+
         RouteId id = new RouteId(srcId, dstId);
         Route result = null;
-        if (pathcache.containsKey(id)) {
+
+        try {
             result = pathcache.get(id);
-        } else {
-            result = buildroute(id);
-            pathcache.put(id, result);
+        } catch (Exception e) {
+            log.error("{}", e);
         }
+
         if (log.isTraceEnabled()) {
             log.trace("getRoute: {} -> {}", id, result);
         }
diff --git a/src/main/java/net/floodlightcontroller/topology/TopologyManager.java b/src/main/java/net/floodlightcontroller/topology/TopologyManager.java
index cd445b9cec59234775a48d1e32e1376c131aa3c8..e0e39729874fa23024b89050c670ed7b68ef8825 100644
--- a/src/main/java/net/floodlightcontroller/topology/TopologyManager.java
+++ b/src/main/java/net/floodlightcontroller/topology/TopologyManager.java
@@ -44,6 +44,9 @@ import net.floodlightcontroller.core.module.IFloodlightModule;
 import net.floodlightcontroller.core.module.IFloodlightService;
 import net.floodlightcontroller.core.util.SingletonTask;
 import net.floodlightcontroller.counter.ICounterStoreService;
+import net.floodlightcontroller.debugcounter.IDebugCounterService;
+import net.floodlightcontroller.debugcounter.NullDebugCounter;
+import net.floodlightcontroller.debugcounter.IDebugCounterService.CounterType;
 import net.floodlightcontroller.linkdiscovery.ILinkDiscoveryListener;
 import net.floodlightcontroller.linkdiscovery.ILinkDiscoveryService;
 import net.floodlightcontroller.packet.BSN;
@@ -111,6 +114,7 @@ public class TopologyManager implements
     protected IThreadPoolService threadPool;
     protected IFloodlightProviderService floodlightProvider;
     protected IRestApiService restApi;
+    protected IDebugCounterService debugCounters;
 
     // Modules that listen to our updates
     protected ArrayList<ITopologyListener> topologyAware;
@@ -250,7 +254,7 @@ public class TopologyManager implements
     public boolean isAttachmentPointPort(long switchid, short port,
                                          boolean tunnelEnabled) {
 
-        // If the switch port is a tunnel endpoint, it is not
+        // If the switch port is 'tun-bsn' port, it is not
         // an attachment point port, irrespective of whether
         // a link is found through it or not.
         if (linkDiscovery.isTunnelPort(switchid, port))
@@ -645,6 +649,7 @@ public class TopologyManager implements
                            FloodlightContext cntx) {
         switch (msg.getType()) {
             case PACKET_IN:
+                debugCounters.updateCounter("topology-incoming");
                 return this.processPacketInMessage(sw,
                                                    (OFPacketIn) msg, cntx);
             default:
@@ -735,6 +740,7 @@ public class TopologyManager implements
         floodlightProvider =
                 context.getServiceImpl(IFloodlightProviderService.class);
         restApi = context.getServiceImpl(IRestApiService.class);
+        debugCounters = context.getServiceImpl(IDebugCounterService.class);
 
         switchPorts = new HashMap<Long,Set<Short>>();
         switchPortLinks = new HashMap<NodePortTuple, Set<Link>>();
@@ -760,6 +766,17 @@ public class TopologyManager implements
         floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
         floodlightProvider.addHAListener(this);
         addRestletRoutable();
+        registerTopologyDebugCounters();
+    }
+
+    private void registerTopologyDebugCounters() {
+        if (debugCounters == null) {
+            log.error("Debug Counter Service not found.");
+            debugCounters = new NullDebugCounter();
+            return;
+        }
+        debugCounters.registerCounter(getName() + "-" + "incoming",
+            "All incoming packets seen by this module", CounterType.ALWAYS_COUNT);
     }
 
     protected void addRestletRoutable() {
@@ -951,7 +968,7 @@ public class TopologyManager implements
                 IFloodlightProviderService.bcStore.
                 get(cntx,IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
 
-        if (eth.getEtherType() == Ethernet.TYPE_BSN) {
+        if (eth.getPayload() instanceof BSN) {
             BSN bsn = (BSN) eth.getPayload();
             if (bsn == null) return Command.STOP;
             if (bsn.getPayload() == null) return Command.STOP;
diff --git a/src/main/java/net/floodlightcontroller/util/OFMessageDamper.java b/src/main/java/net/floodlightcontroller/util/OFMessageDamper.java
index 5de554f273b5badb6137fe8e5221326e37b2090a..75b0b00d3a9fb082e14a18e3da34712fcdee4e36 100644
--- a/src/main/java/net/floodlightcontroller/util/OFMessageDamper.java
+++ b/src/main/java/net/floodlightcontroller/util/OFMessageDamper.java
@@ -134,7 +134,7 @@ public class OFMessageDamper {
                         FloodlightContext cntx, boolean flush) 
             throws IOException {
         if (! msgTypesToCache.contains(msg.getType())) {
-            sw.write(msg, cntx);
+            sw.writeThrottled(msg, cntx);
             if (flush) {
                 sw.flush();
             }
@@ -146,7 +146,7 @@ public class OFMessageDamper {
             // entry exists in cache. Dampening.
             return false; 
         } else {
-            sw.write(msg, cntx);
+            sw.writeThrottled(msg, cntx);
             if (flush) {
                 sw.flush();
             }
diff --git a/src/main/java/net/floodlightcontroller/virtualnetwork/NetworkResource.java b/src/main/java/net/floodlightcontroller/virtualnetwork/NetworkResource.java
index 4c5ddaf6b14aa2eb8456299674930c0953283ef9..746490bc6b2897a560c8d654f20c4cd8e93ce115 100644
--- a/src/main/java/net/floodlightcontroller/virtualnetwork/NetworkResource.java
+++ b/src/main/java/net/floodlightcontroller/virtualnetwork/NetworkResource.java
@@ -70,6 +70,7 @@ public class NetworkResource extends ServerResource {
             else if (n.equals("network")) {
                 while (jp.nextToken() != JsonToken.END_OBJECT) {
                     String field = jp.getCurrentName();
+                    if (field == null) continue;
                     if (field.equals("name")) {
                         network.name = jp.getText();
                     } else if (field.equals("gateway")) {
diff --git a/src/main/java/net/floodlightcontroller/virtualnetwork/NoOp.java b/src/main/java/net/floodlightcontroller/virtualnetwork/NoOp.java
index 66d560e7f9738d1a89943578bd99bcfe60fb5112..9533056297b1b5ac0d10120040b27356b3808283 100644
--- a/src/main/java/net/floodlightcontroller/virtualnetwork/NoOp.java
+++ b/src/main/java/net/floodlightcontroller/virtualnetwork/NoOp.java
@@ -17,21 +17,24 @@
 package net.floodlightcontroller.virtualnetwork;
 
 import org.restlet.data.Status;
+import org.restlet.resource.Delete;
 import org.restlet.resource.Get;
 import org.restlet.resource.Post;
 import org.restlet.resource.Put;
 import org.restlet.resource.ServerResource;
 
 public class NoOp extends ServerResource {
-	/**
-	 * Does nothing and returns 200 OK with a status message
-	 * @return status: ok
-	 */
-	@Get
-	@Put
-	@Post
-	public String noOp(String postdata) {
-		setStatus(Status.SUCCESS_OK);
+    /**
+     * Does nothing and returns 200 OK with a status message
+     * 
+     * @return status: ok
+     */
+    @Get
+    @Put
+    @Post
+    @Delete
+    public String noOp(String postdata) {
+        setStatus(Status.SUCCESS_OK);
         return "{\"status\":\"ok\"}";
-	}
+    }
 }
diff --git a/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkWebRoutable.java b/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkWebRoutable.java
index 0d5d6a5ba5e03e9ee4ecc18308c29e04cb85090e..8e857095004242997ff5ba12b33f1bdb7446f808 100644
--- a/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkWebRoutable.java
+++ b/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkWebRoutable.java
@@ -37,6 +37,6 @@ public class VirtualNetworkWebRoutable implements RestletRoutable {
 
     @Override
     public String basePath() {
-        return "/quantum/v1.0";
+        return "/networkService/v1.1";
     }
 }
\ No newline at end of file
diff --git a/src/main/java/org/openflow/protocol/OFFlowRemoved.java b/src/main/java/org/openflow/protocol/OFFlowRemoved.java
index 4f4e0c7ff92acbd9a716c5301bdcd93a06335ae4..33570063c73850cf995606890ac0c3e9e97f67f5 100644
--- a/src/main/java/org/openflow/protocol/OFFlowRemoved.java
+++ b/src/main/java/org/openflow/protocol/OFFlowRemoved.java
@@ -194,7 +194,11 @@ public class OFFlowRemoved extends OFMessage {
         this.match.readFrom(data);
         this.cookie = data.readLong();
         this.priority = data.readShort();
-        this.reason = OFFlowRemovedReason.values()[(0xff & data.readByte())];
+        int reasonIndex = (int)(0xff & data.readByte());
+        if (reasonIndex >= OFFlowRemovedReason.values().length) {
+            reasonIndex = OFFlowRemovedReason.values().length - 1;
+        }
+        this.reason = OFFlowRemovedReason.values()[reasonIndex];
         data.readByte(); // pad
         this.durationSeconds = data.readInt();
         this.durationNanoseconds = data.readInt();
diff --git a/src/main/java/org/openflow/protocol/OFPhysicalPort.java b/src/main/java/org/openflow/protocol/OFPhysicalPort.java
index 58fdae59f56de9df28358e65f1b9cab038ab676e..c8c9a6b9e3a05801b14995b566bc618977e4716d 100644
--- a/src/main/java/org/openflow/protocol/OFPhysicalPort.java
+++ b/src/main/java/org/openflow/protocol/OFPhysicalPort.java
@@ -26,14 +26,15 @@ import net.floodlightcontroller.core.web.serializers.UShortSerializer;
 
 import org.codehaus.jackson.map.annotate.JsonSerialize;
 import org.jboss.netty.buffer.ChannelBuffer;
+import org.openflow.util.HexString;
 
 /**
  * Represents ofp_phy_port
  * @author David Erickson (daviderickson@cs.stanford.edu) - Mar 25, 2010
  */
 public class OFPhysicalPort {
-    public static int MINIMUM_LENGTH = 48;
-    public static int OFP_ETH_ALEN = 6;
+    public final static int MINIMUM_LENGTH = 48;
+    public final static int OFP_ETH_ALEN = 6;
 
     public enum OFPortConfig {
         OFPPC_PORT_DOWN    (1 << 0) {
@@ -467,4 +468,35 @@ public class OFPhysicalPort {
         }
         return true;
     }
+
+    @Override
+    public String toString() {
+        String linkState, linkSpeed;
+        if ((state & OFPortState.OFPPS_LINK_DOWN.getValue()) != 0) {
+            linkState = "down";
+        } else {
+            linkState = "up";
+        }
+        if ((currentFeatures & OFPortFeatures.OFPPF_10GB_FD.getValue()) != 0) {
+            linkSpeed = "10G";
+        } else if ((currentFeatures & OFPortFeatures.OFPPF_1GB_FD.getValue()) != 0) {
+            linkSpeed = "1G";
+        } else if ((currentFeatures & OFPortFeatures.OFPPF_1GB_HD.getValue()) != 0) {
+            linkSpeed = "1G(half-duplex)";
+        } else if ((currentFeatures & OFPortFeatures.OFPPF_100MB_FD.getValue()) != 0) {
+            linkSpeed = "100M";
+        } else if ((currentFeatures & OFPortFeatures.OFPPF_100MB_HD.getValue()) != 0) {
+            linkSpeed = "100M(half-duplex)";
+        } else if ((currentFeatures & OFPortFeatures.OFPPF_10MB_FD.getValue()) != 0) {
+            linkSpeed = "10M";
+        } else if ((currentFeatures & OFPortFeatures.OFPPF_10MB_HD.getValue()) != 0) {
+            linkSpeed = "10M(half-duplex)";
+        } else {
+            linkSpeed = "unknown";
+        }
+        return "port " + name + " (" +  portNumber + ")" +
+               ", mac " + HexString.toHexString(hardwareAddress) +
+               ", state " + linkState +
+               ", speed " + linkSpeed;
+    }
 }
diff --git a/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule b/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
index 935fe105c9f6a40b0415d21ef18816bc084042bf..dc38c05b97eed015c76e1f6ea56ae3b1099130be 100644
--- a/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
+++ b/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
@@ -16,6 +16,8 @@ net.floodlightcontroller.hub.Hub
 net.floodlightcontroller.jython.JythonDebugInterface
 net.floodlightcontroller.counter.CounterStore
 net.floodlightcontroller.counter.NullCounterStore
+net.floodlightcontroller.debugcounter.DebugCounter
+net.floodlightcontroller.debugcounter.NullDebugCounter
 net.floodlightcontroller.threadpool.ThreadPool
 net.floodlightcontroller.ui.web.StaticWebRoutable
 net.floodlightcontroller.virtualnetwork.VirtualNetworkFilter
diff --git a/src/main/resources/floodlightdefault.properties b/src/main/resources/floodlightdefault.properties
index 30dfdcaaa06d8e73d98a80a0fc9cb43b827ef347..2d384d3a1b6e39accfcd56839588cbfc1fb9bdbe 100644
--- a/src/main/resources/floodlightdefault.properties
+++ b/src/main/resources/floodlightdefault.properties
@@ -12,6 +12,7 @@ net.floodlightcontroller.flowcache.FlowCache, \
 net.floodlightcontroller.flowcache.FlowReconcileManager, \
 net.floodlightcontroller.jython.JythonDebugInterface,\
 net.floodlightcontroller.counter.CounterStore,\
+net.floodlightcontroller.debugcounter.DebugCounter,\
 net.floodlightcontroller.perfmon.PktInProcessingTime,\
 net.floodlightcontroller.ui.web.StaticWebRoutable,\
 net.floodlightcontroller.loadbalancer.LoadBalancer
diff --git a/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java b/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java
index 5daf3461bb72bfdc4119754ccd72efb7b71db79a..e21239ab92dfe01a36bcf349a620ae10a97cec56 100644
--- a/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java
+++ b/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java
@@ -1,7 +1,7 @@
 /**
-*    Copyright 2011, Big Switch Networks, Inc. 
+*    Copyright 2011, Big Switch Networks, Inc.
 *    Originally created by David Erickson, Stanford University
-* 
+*
 *    Licensed under the Apache License, Version 2.0 (the "License"); you may
 *    not use this file except in compliance with the License. You may obtain
 *    a copy of the License at
@@ -18,9 +18,6 @@
 package net.floodlightcontroller.core.internal;
 
 import static org.easymock.EasyMock.*;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
@@ -29,6 +26,7 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.DelayQueue;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.locks.Lock;
@@ -50,6 +48,7 @@ import net.floodlightcontroller.core.internal.Controller.SwitchUpdate;
 import net.floodlightcontroller.core.internal.Controller.SwitchUpdateType;
 import net.floodlightcontroller.core.internal.OFChannelState.HandshakeState;
 import net.floodlightcontroller.core.internal.RoleChanger.PendingRoleRequestEntry;
+import net.floodlightcontroller.core.internal.RoleChanger.RoleChangeTask;
 import net.floodlightcontroller.core.module.FloodlightModuleContext;
 import net.floodlightcontroller.core.test.MockFloodlightProvider;
 import net.floodlightcontroller.core.test.MockThreadPoolService;
@@ -95,11 +94,9 @@ import org.openflow.protocol.statistics.OFDescriptionStatistics;
 import org.openflow.protocol.statistics.OFFlowStatisticsReply;
 import org.openflow.protocol.statistics.OFStatistics;
 import org.openflow.protocol.statistics.OFStatisticsType;
-import org.openflow.protocol.vendor.OFVendorData;
 import org.openflow.util.HexString;
 import org.openflow.vendor.nicira.OFNiciraVendorData;
 import org.openflow.vendor.nicira.OFRoleReplyVendorData;
-import org.openflow.vendor.nicira.OFRoleRequestVendorData;
 
 /**
  *
@@ -107,7 +104,7 @@ import org.openflow.vendor.nicira.OFRoleRequestVendorData;
  */
 public class ControllerTest extends FloodlightTestCase
         implements IOFSwitchDriver {
-   
+
     private Controller controller;
     private MockThreadPoolService tp;
     private boolean test_bind_order = false;
@@ -117,26 +114,26 @@ public class ControllerTest extends FloodlightTestCase
     public void setUp() throws Exception {
         super.setUp();
         FloodlightModuleContext fmc = new FloodlightModuleContext();
-        
+
         FloodlightProvider cm = new FloodlightProvider();
         controller = (Controller)cm.getServiceImpls().get(IFloodlightProviderService.class);
         fmc.addService(IFloodlightProviderService.class, controller);
-        
+
         MemoryStorageSource memstorage = new MemoryStorageSource();
         fmc.addService(IStorageSourceService.class, memstorage);
-        
+
         RestApiServer restApi = new RestApiServer();
         fmc.addService(IRestApiService.class, restApi);
-        
+
         CounterStore cs = new CounterStore();
         fmc.addService(ICounterStoreService.class, cs);
-        
+
         PktInProcessingTime ppt = new PktInProcessingTime();
         fmc.addService(IPktInProcessingTimeService.class, ppt);
-        
+
         tp = new MockThreadPoolService();
         fmc.addService(IThreadPoolService.class, tp);
-        
+
         ppt.init(fmc);
         restApi.init(fmc);
         memstorage.init(fmc);
@@ -167,15 +164,15 @@ public class ControllerTest extends FloodlightTestCase
             sr.setFlags((short) 1);
         return sr;
     }
-    
+
     /* Set the mock expectations for sw when sw is passed to addSwitch */
     protected void setupSwitchForAddSwitch(IOFSwitch sw, long dpid) {
         String dpidString = HexString.toHexString(dpid);
-                
+
         expect(sw.getId()).andReturn(dpid).anyTimes();
         expect(sw.getStringId()).andReturn(dpidString).anyTimes();
     }
-    
+
     /**
      * Run the controller's main loop so that updates are processed
      */
@@ -219,7 +216,7 @@ public class ControllerTest extends FloodlightTestCase
                 .setTargetProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.2")));
         byte[] testPacketSerialized = testPacket.serialize();
 
-        // Build the PacketIn        
+        // Build the PacketIn
         OFPacketIn pi = ((OFPacketIn) new BasicFactory().getMessage(OFType.PACKET_IN))
                 .setBufferId(-1)
                 .setInPort((short) 1)
@@ -250,7 +247,7 @@ public class ControllerTest extends FloodlightTestCase
 
         // verify STOP works
         reset(test1, test2, sw);
-        expect(test1.receive(eq(sw), eq(pi), isA(FloodlightContext.class))).andReturn(Command.STOP);       
+        expect(test1.receive(eq(sw), eq(pi), isA(FloodlightContext.class))).andReturn(Command.STOP);
         expect(sw.getId()).andReturn(0L).anyTimes();
         expect(sw.getStringId()).andReturn("00:00:00:00:00:00:00").anyTimes();
         replay(test1, test2, sw);
@@ -291,7 +288,7 @@ public class ControllerTest extends FloodlightTestCase
     }
 
     /**
-     * 
+     *
      * @throws Exception
      */
     @Test
@@ -379,7 +376,7 @@ public class ControllerTest extends FloodlightTestCase
         fmCntx.addService(IFloodlightProviderService.class, mfp);
         fmCntx.addService(IThreadPoolService.class, mtp);
         String sid = null;
-        
+
         mfm.init(fmCntx);
         mfm.startUp(fmCntx);
 
@@ -402,14 +399,14 @@ public class ControllerTest extends FloodlightTestCase
         assertTrue(mfm.getNumberOfFilters() == mfm.getMaxFilterSize());
 
         // Deleting the filter works.
-        mfm.setupFilter(sid, null, -1);        
+        mfm.setupFilter(sid, null, -1);
         assertTrue(mfm.getNumberOfFilters() == mfm.getMaxFilterSize()-1);
 
-        // Creating mock switch to which we will send packet out and 
+        // Creating mock switch to which we will send packet out and
         IOFSwitch sw = createMock(IOFSwitch.class);
         expect(sw.getId()).andReturn(new Long(0));
 
-        // Mock Packet-in   
+        // Mock Packet-in
         IPacket testPacket = new Ethernet()
         .setSourceMACAddress("00:44:33:22:11:00")
         .setDestinationMACAddress("00:11:22:33:44:55")
@@ -427,7 +424,7 @@ public class ControllerTest extends FloodlightTestCase
                 .setTargetProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.2")));
         byte[] testPacketSerialized = testPacket.serialize();
 
-        // Build the PacketIn        
+        // Build the PacketIn
         OFPacketIn pi = ((OFPacketIn) new BasicFactory().getMessage(OFType.PACKET_IN))
                 .setBufferId(-1)
                 .setInPort((short) 1)
@@ -452,7 +449,7 @@ public class ControllerTest extends FloodlightTestCase
 
 
         // Let's check the listeners.
-        List <IOFMessageListener> lm; 
+        List <IOFMessageListener> lm;
 
         // Check to see if all the listeners are active.
         lm = mfp.getListeners().get(OFType.PACKET_OUT);
@@ -467,7 +464,7 @@ public class ControllerTest extends FloodlightTestCase
         assertTrue(lm.size() == 1);
         assertTrue(lm.get(0).equals(mfm));
 
-        HashSet<String> matchedFilters;        
+        HashSet<String> matchedFilters;
 
         // Send a packet in and check if it matches a filter.
         matchedFilters = mfm.getMatchedFilters(pi, cntx);
@@ -501,14 +498,14 @@ public class ControllerTest extends FloodlightTestCase
         expect(newsw.getId()).andReturn(0L).anyTimes();
         expect(newsw.getStringId()).andReturn("00:00:00:00:00:00:00").anyTimes();
         controller.activeSwitches.put(0L, oldsw);
-        
+
         replay(newsw, channel);
 
         controller.addSwitch(newsw, false);
 
         verify(newsw, channel);
     }
-    
+
     @Test
     public void testAddSwitchClearFM() throws Exception {
         controller.activeSwitches = new ConcurrentHashMap<Long, IOFSwitch>();
@@ -530,14 +527,14 @@ public class ControllerTest extends FloodlightTestCase
         newsw.clearAllFlowMods();
         expectLastCall().once();
         controller.activeSwitches.put(0L, oldsw);
-        
+
         replay(newsw, channel);
 
         controller.addSwitch(newsw, true);
 
         verify(newsw, channel);
     }
-    
+
     @Test
     public void testUpdateQueue() throws Exception {
         class DummySwitchListener implements IOFSwitchListener {
@@ -573,29 +570,29 @@ public class ControllerTest extends FloodlightTestCase
         IOFSwitch sw = createMock(IOFSwitch.class);
         ControllerRunThread t = new ControllerRunThread();
         t.start();
-        
+
         controller.addOFSwitchListener(switchListener);
         synchronized(switchListener) {
             controller.updates.put(controller.new SwitchUpdate(sw,
                                       Controller.SwitchUpdateType.ADDED));
             switchListener.wait(500);
-            assertTrue("IOFSwitchListener.addedSwitch() was not called", 
+            assertTrue("IOFSwitchListener.addedSwitch() was not called",
                     switchListener.nAdded == 1);
-            controller.updates.put(controller.new SwitchUpdate(sw, 
+            controller.updates.put(controller.new SwitchUpdate(sw,
                                       Controller.SwitchUpdateType.REMOVED));
             switchListener.wait(500);
-            assertTrue("IOFSwitchListener.removedSwitch() was not called", 
+            assertTrue("IOFSwitchListener.removedSwitch() was not called",
                     switchListener.nRemoved == 1);
-            controller.updates.put(controller.new SwitchUpdate(sw, 
+            controller.updates.put(controller.new SwitchUpdate(sw,
                                       Controller.SwitchUpdateType.PORTCHANGED));
             switchListener.wait(500);
-            assertTrue("IOFSwitchListener.switchPortChanged() was not called", 
+            assertTrue("IOFSwitchListener.switchPortChanged() was not called",
                     switchListener.nPortChanged == 1);
         }
     }
-    
 
-    private Map<String,Object> getFakeControllerIPRow(String id, String controllerId, 
+
+    private Map<String,Object> getFakeControllerIPRow(String id, String controllerId,
             String type, int number, String discoveredIP ) {
         HashMap<String, Object> row = new HashMap<String,Object>();
         row.put(Controller.CONTROLLER_INTERFACE_ID, id);
@@ -608,14 +605,14 @@ public class ControllerTest extends FloodlightTestCase
 
     /**
      * Test notifications for controller node IP changes. This requires
-     * synchronization between the main test thread and another thread 
+     * synchronization between the main test thread and another thread
      * that runs Controller's main loop and takes / handles updates. We
-     * synchronize with wait(timeout) / notifyAll(). We check for the 
+     * synchronize with wait(timeout) / notifyAll(). We check for the
      * expected condition after the wait returns. However, if wait returns
      * due to the timeout (or due to spurious awaking) and the check fails we
      * might just not have waited long enough. Using a long enough timeout
-     * mitigates this but we cannot get rid of the fundamental "issue". 
-     * 
+     * mitigates this but we cannot get rid of the fundamental "issue".
+     *
      * @throws Exception
      */
     @Test
@@ -625,16 +622,16 @@ public class ControllerTest extends FloodlightTestCase
             public Map<String, String> addedControllerNodeIPs;
             public Map<String, String> removedControllerNodeIPs;
             public int nCalled;
-            
+
             public DummyHAListener() {
                 this.nCalled = 0;
             }
-                
+
             @Override
             public void roleChanged(Role oldRole, Role newRole) {
                 // ignore
             }
-    
+
             @Override
             public synchronized void controllerNodeIPsChanged(
                     Map<String, String> curControllerNodeIPs,
@@ -646,19 +643,19 @@ public class ControllerTest extends FloodlightTestCase
                 this.nCalled++;
                 notifyAll();
             }
-            
+
             public void do_assert(int nCalled,
                     Map<String, String> curControllerNodeIPs,
                     Map<String, String> addedControllerNodeIPs,
                     Map<String, String> removedControllerNodeIPs) {
                 assertEquals("nCalled is not as expected", nCalled, this.nCalled);
-                assertEquals("curControllerNodeIPs is not as expected", 
+                assertEquals("curControllerNodeIPs is not as expected",
                         curControllerNodeIPs, this.curControllerNodeIPs);
-                assertEquals("addedControllerNodeIPs is not as expected", 
+                assertEquals("addedControllerNodeIPs is not as expected",
                         addedControllerNodeIPs, this.addedControllerNodeIPs);
-                assertEquals("removedControllerNodeIPs is not as expected", 
+                assertEquals("removedControllerNodeIPs is not as expected",
                         removedControllerNodeIPs, this.removedControllerNodeIPs);
-                
+
             }
         }
         long waitTimeout = 250; // ms
@@ -666,11 +663,11 @@ public class ControllerTest extends FloodlightTestCase
         HashMap<String,String> expectedCurMap = new HashMap<String, String>();
         HashMap<String,String> expectedAddedMap = new HashMap<String, String>();
         HashMap<String,String> expectedRemovedMap = new HashMap<String, String>();
-        
+
         controller.addHAListener(listener);
         ControllerRunThread t = new ControllerRunThread();
         t.start();
-        
+
         synchronized(listener) {
             // Insert a first entry
             controller.storageSource.insertRow(Controller.CONTROLLER_INTERFACE_TABLE_NAME,
@@ -682,12 +679,12 @@ public class ControllerTest extends FloodlightTestCase
             expectedAddedMap.put("c1", "1.1.1.1");
             listener.wait(waitTimeout);
             listener.do_assert(1, expectedCurMap, expectedAddedMap, expectedRemovedMap);
-            
-            // Add an interface that we want to ignore. 
+
+            // Add an interface that we want to ignore.
             controller.storageSource.insertRow(Controller.CONTROLLER_INTERFACE_TABLE_NAME,
                     getFakeControllerIPRow("row2", "c1", "Ethernet", 1, "1.1.1.2"));
             listener.wait(waitTimeout); // TODO: do a different check. This call will have to wait for the timeout
-            assertTrue("controllerNodeIPsChanged() should not have been called here", 
+            assertTrue("controllerNodeIPsChanged() should not have been called here",
                     listener.nCalled == 1);
 
             // Add another entry
@@ -717,7 +714,7 @@ public class ControllerTest extends FloodlightTestCase
             listener.do_assert(3, expectedCurMap, expectedAddedMap, expectedRemovedMap);
 
             // Delete an entry
-            controller.storageSource.deleteRow(Controller.CONTROLLER_INTERFACE_TABLE_NAME, 
+            controller.storageSource.deleteRow(Controller.CONTROLLER_INTERFACE_TABLE_NAME,
                     "row3");
             expectedCurMap.clear();
             expectedAddedMap.clear();
@@ -728,11 +725,11 @@ public class ControllerTest extends FloodlightTestCase
             listener.do_assert(4, expectedCurMap, expectedAddedMap, expectedRemovedMap);
         }
     }
-    
+
     @Test
     public void testGetControllerNodeIPs() {
         HashMap<String,String> expectedCurMap = new HashMap<String, String>();
-        
+
         controller.storageSource.insertRow(Controller.CONTROLLER_INTERFACE_TABLE_NAME,
                 getFakeControllerIPRow("row1", "c1", "Ethernet", 0, "1.1.1.1"));
         controller.storageSource.insertRow(Controller.CONTROLLER_INTERFACE_TABLE_NAME,
@@ -740,11 +737,11 @@ public class ControllerTest extends FloodlightTestCase
         controller.storageSource.insertRow(Controller.CONTROLLER_INTERFACE_TABLE_NAME,
                 getFakeControllerIPRow("row3", "c2", "Ethernet", 0, "2.2.2.2"));
         expectedCurMap.put("c1", "1.1.1.1");
-        expectedCurMap.put("c2", "2.2.2.2");    
-        assertEquals("expectedControllerNodeIPs is not as expected", 
+        expectedCurMap.put("c2", "2.2.2.2");
+        assertEquals("expectedControllerNodeIPs is not as expected",
                 expectedCurMap, controller.getControllerNodeIPs());
     }
-    
+
     @Test
     public void testSetRoleNull() {
         try {
@@ -755,31 +752,31 @@ public class ControllerTest extends FloodlightTestCase
             //exptected
         }
     }
-    
-    @Test 
+
+    @Test
     public void testSetRole() {
         controller.connectedSwitches.add(new OFSwitchImpl());
-        RoleChanger roleChanger = createMock(RoleChanger.class); 
+        RoleChanger roleChanger = createMock(RoleChanger.class);
         roleChanger.submitRequest(controller.connectedSwitches, Role.SLAVE);
         controller.roleChanger = roleChanger;
-        
-        assertEquals("Check that update queue is empty", 0, 
+
+        assertEquals("Check that update queue is empty", 0,
                     controller.updates.size());
-        
+
         replay(roleChanger);
         controller.setRole(Role.SLAVE, "Testing");
         controller.doSetRole(); // avoid wait
         verify(roleChanger);
-        
+
         Controller.IUpdate upd = controller.updates.poll();
         assertNotNull("Check that update queue has an update", upd);
-        assertTrue("Check that update is HARoleUpdate", 
+        assertTrue("Check that update is HARoleUpdate",
                    upd instanceof Controller.HARoleUpdate);
         Controller.HARoleUpdate roleUpd = (Controller.HARoleUpdate)upd;
         assertSame(Role.MASTER, roleUpd.oldRole);
         assertSame(Role.SLAVE, roleUpd.newRole);
     }
-    
+
     @SuppressWarnings("unchecked")
     @Test
     public void testCheckSwitchReady() {
@@ -790,8 +787,8 @@ public class ControllerTest extends FloodlightTestCase
         OFDescriptionStatistics desc = new OFDescriptionStatistics();
         OFFeaturesReply featuresReply = new OFFeaturesReply();
         featuresReply.setPorts(new ArrayList<OFPhysicalPort>());
-        
-        // Wrong current state 
+
+        // Wrong current state
         // Should not go to READY
         state.hsState = OFChannelState.HandshakeState.HELLO;
         state.hasDescription = false;
@@ -802,7 +799,7 @@ public class ControllerTest extends FloodlightTestCase
         replay(channel);
         chdlr.checkSwitchReady();
         assertSame(OFChannelState.HandshakeState.HELLO, state.hsState);
-        
+
         // Have only config reply
         state.hsState = OFChannelState.HandshakeState.FEATURES_REPLY;
         state.hasDescription = false;
@@ -813,7 +810,7 @@ public class ControllerTest extends FloodlightTestCase
         assertSame(OFChannelState.HandshakeState.FEATURES_REPLY, state.hsState);
         assertTrue(controller.connectedSwitches.isEmpty());
         assertTrue(controller.activeSwitches.isEmpty());
-        
+
         // Have only desc reply
         state.hsState = OFChannelState.HandshakeState.FEATURES_REPLY;
         state.hasDescription = true;
@@ -824,7 +821,7 @@ public class ControllerTest extends FloodlightTestCase
         assertSame(OFChannelState.HandshakeState.FEATURES_REPLY, state.hsState);
         assertTrue(controller.connectedSwitches.isEmpty());
         assertTrue(controller.activeSwitches.isEmpty());
-        
+
         //////////////////////////////////////////
         // Finally, everything is right. Should advance to READY
         //////////////////////////////////////////
@@ -836,7 +833,7 @@ public class ControllerTest extends FloodlightTestCase
         state.featuresReply = featuresReply;
         state.switchBindingDone = false;
         // Role support disabled. Switch should be promoted to active switch
-        // list. 
+        // list.
         // setupSwitchForAddSwitch(chdlr.sw, 0L);
         // chdlr.sw.clearAllFlowMods();
         desc.setManufacturerDescription("test vendor");
@@ -850,14 +847,14 @@ public class ControllerTest extends FloodlightTestCase
         reset(controller.roleChanger);
         controller.connectedSwitches.clear();
         controller.activeSwitches.clear();
-        
-        
-        // Role support enabled. 
+
+
+        // Role support enabled.
         state.hsState = OFChannelState.HandshakeState.FEATURES_REPLY;
         controller.role = Role.MASTER;
-        Capture<Collection<IOFSwitch>> swListCapture = 
+        Capture<Collection<IOFSwitch>> swListCapture =
                     new Capture<Collection<IOFSwitch>>();
-        controller.roleChanger.submitRequest(capture(swListCapture), 
+        controller.roleChanger.submitRequest(capture(swListCapture),
                     same(Role.MASTER));
         replay(controller.roleChanger);
         chdlr.checkSwitchReady();
@@ -868,7 +865,7 @@ public class ControllerTest extends FloodlightTestCase
         Collection<IOFSwitch> swList = swListCapture.getValue();
         assertEquals(1, swList.size());
     }
-    
+
     public class TestSwitchClass extends OFSwitchImpl {
     }
 
@@ -878,11 +875,11 @@ public class ControllerTest extends FloodlightTestCase
     @Test
     public void testBindSwitchToDriver() {
         controller.addOFSwitchDriver("test", this);
-        
+
         OFChannelState state = new OFChannelState();
         Controller.OFChannelHandler chdlr =
                 controller.new OFChannelHandler(state);
-        
+
         // Swith should be bound of OFSwitchImpl (default)
         state.hsState = OFChannelState.HandshakeState.HELLO;
         state.hasDescription = true;
@@ -899,7 +896,7 @@ public class ControllerTest extends FloodlightTestCase
         chdlr.bindSwitchToDriver();
         assertTrue(chdlr.sw instanceof OFSwitchImpl);
         assertTrue(!(chdlr.sw instanceof TestSwitchClass));
-        
+
         // Switch should be bound to TestSwitchImpl
         state.switchBindingDone = false;
         desc.setManufacturerDescription("test1 switch");
@@ -920,7 +917,7 @@ public class ControllerTest extends FloodlightTestCase
         chdlr.bindSwitchToDriver();
         assertTrue(chdlr.sw instanceof Test11SwitchClass);
     }
-    
+
     @Test
     public void testBindSwitchOrder() {
         List<String> order = new ArrayList<String>(3);
@@ -931,12 +928,12 @@ public class ControllerTest extends FloodlightTestCase
         order.add("test");
         order.add("");
         test_bind_order = true;
-        
+
         OFChannelState state = new OFChannelState();
         Controller.OFChannelHandler chdlr =
                 controller.new OFChannelHandler(state);
         chdlr.sw = null;
-        
+
         // Swith should be bound of OFSwitchImpl (default)
         state.hsState = OFChannelState.HandshakeState.HELLO;
         state.hasDescription = true;
@@ -958,29 +955,29 @@ public class ControllerTest extends FloodlightTestCase
         test_bind_order = false;
         bind_order = null;
    }
-    
+
     @Test
     public void testChannelDisconnected() throws Exception {
         OFChannelState state = new OFChannelState();
         state.hsState = OFChannelState.HandshakeState.READY;
         Controller.OFChannelHandler chdlr = controller.new OFChannelHandler(state);
         chdlr.sw = createMock(IOFSwitch.class);
-        
-        // Switch is active 
+
+        // Switch is active
         expect(chdlr.sw.getId()).andReturn(0L).anyTimes();
         expect(chdlr.sw.getStringId()).andReturn("00:00:00:00:00:00:00:00")
                     .anyTimes();
         chdlr.sw.cancelAllStatisticsReplies();
         chdlr.sw.setConnected(false);
         expect(chdlr.sw.isConnected()).andReturn(true);
-        
+
         controller.connectedSwitches.add(chdlr.sw);
         controller.activeSwitches.put(0L, chdlr.sw);
-        
+
         replay(chdlr.sw);
         chdlr.channelDisconnected(null, null);
         verify(chdlr.sw);
-        
+
         // Switch is connected but not active
         reset(chdlr.sw);
         expect(chdlr.sw.getId()).andReturn(0L).anyTimes();
@@ -988,20 +985,20 @@ public class ControllerTest extends FloodlightTestCase
         replay(chdlr.sw);
         chdlr.channelDisconnected(null, null);
         verify(chdlr.sw);
-        
+
         // Not in ready state
         state.hsState = HandshakeState.START;
         reset(chdlr.sw);
         replay(chdlr.sw);
         chdlr.channelDisconnected(null, null);
         verify(chdlr.sw);
-        
+
         // Switch is null
         state.hsState = HandshakeState.READY;
         chdlr.sw = null;
         chdlr.channelDisconnected(null, null);
     }
-    
+
     /*
     @Test
     public void testRoleChangeForSerialFailoverSwitch() throws Exception {
@@ -1010,12 +1007,12 @@ public class ControllerTest extends FloodlightTestCase
         expect(newsw.getStringId()).andReturn("00:00:00:00:00:00:00").anyTimes();
         Channel channel2 = createMock(Channel.class);
         expect(newsw.getChannel()).andReturn(channel2);
-        
+
         // newsw.role is null because the switch does not support
         // role request messages
         expect(newsw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE))
                         .andReturn(false);
-        // switch is connected 
+        // switch is connected
         controller.connectedSwitches.add(newsw);
 
         // the switch should get disconnected when role is changed to SLAVE
@@ -1035,40 +1032,40 @@ public class ControllerTest extends FloodlightTestCase
         Controller.OFChannelHandler chdlr = controller.new OFChannelHandler(state);
         chdlr.sw = createMock(IOFSwitch.class);
         Channel ch = createMock(Channel.class);
-        
+
         // the error returned when role request message is not supported by sw
         OFError msg = new OFError();
         msg.setType(OFType.ERROR);
         msg.setXid(xid);
         msg.setErrorType(OFErrorType.OFPET_BAD_REQUEST);
-        
+
         // the switch connection should get disconnected when the controller is
         // in SLAVE mode and the switch does not support role-request messages
         controller.role = Role.SLAVE;
-        setupPendingRoleRequest(chdlr.sw, xid, controller.role, 123456);                
+        setupPendingRoleRequest(chdlr.sw, xid, controller.role, 123456);
         expect(chdlr.sw.getHARole()).andReturn(null);
         chdlr.sw.setHARole(Role.SLAVE, false);
         expect(chdlr.sw.getHARole()).andReturn(Role.SLAVE);
         chdlr.sw.disconnectOutputStream();
-        
+
         replay(ch, chdlr.sw);
         chdlr.processOFMessage(msg);
         verify(ch, chdlr.sw);
         assertTrue("activeSwitches must be empty",
                    controller.activeSwitches.isEmpty());
         reset(ch, chdlr.sw);
-              
+
         // We are MASTER, the switch should be added to the list of active
         // switches.
         controller.role = Role.MASTER;
-        setupPendingRoleRequest(chdlr.sw, xid, controller.role, 123456);                
+        setupPendingRoleRequest(chdlr.sw, xid, controller.role, 123456);
         expect(chdlr.sw.getHARole()).andReturn(null);
         chdlr.sw.setHARole(controller.role, false);
         setupSwitchForAddSwitch(chdlr.sw, 0L);
         chdlr.sw.clearAllFlowMods();
         expect(chdlr.sw.getHARole()).andReturn(null).anyTimes();
         replay(ch, chdlr.sw);
-        
+
         chdlr.processOFMessage(msg);
         verify(ch, chdlr.sw);
         assertSame("activeSwitches must contain this switch",
@@ -1076,12 +1073,12 @@ public class ControllerTest extends FloodlightTestCase
         reset(ch, chdlr.sw);
 
     }
-    
-    
-    @Test 
+
+
+    @Test
     public void testVendorMessageUnknown() throws Exception {
         // Check behavior with an unknown vendor id
-        // Ensure that vendor message listeners get called, even for Vendors 
+        // Ensure that vendor message listeners get called, even for Vendors
         // unknown to floodlight. It is the responsibility of the listener to
         // discard unknown vendors.
         OFChannelState state = new OFChannelState();
@@ -1092,15 +1089,15 @@ public class ControllerTest extends FloodlightTestCase
         IOFSwitch sw = createMock(IOFSwitch.class);
         chdlr.sw = sw;
         controller.activeSwitches.put(1L, sw);
-        
+
         // prepare the Vendor Message Listener expectations
-        ListenerDispatcher<OFType, IOFMessageListener> ld = 
+        ListenerDispatcher<OFType, IOFMessageListener> ld =
                 new ListenerDispatcher<OFType, IOFMessageListener>();
         IOFMessageListener ml = createMock(IOFMessageListener.class);
         expect(ml.getName()).andReturn("Dummy").anyTimes();
-        expect(ml.isCallbackOrderingPrereq((OFType)anyObject(), 
+        expect(ml.isCallbackOrderingPrereq((OFType)anyObject(),
                 (String)anyObject())).andReturn(false).anyTimes();
-        expect(ml.isCallbackOrderingPostreq((OFType)anyObject(), 
+        expect(ml.isCallbackOrderingPostreq((OFType)anyObject(),
                 (String)anyObject())).andReturn(false).anyTimes();
         expect(ml.receive(eq(sw), eq(msg), isA(FloodlightContext.class))).
                 andReturn(Command.CONTINUE).once();
@@ -1112,7 +1109,7 @@ public class ControllerTest extends FloodlightTestCase
         expect(sw.isConnected()).andReturn(true).anyTimes();
         expect(sw.getHARole()).andReturn(Role.MASTER).anyTimes();
         expect(sw.getId()).andReturn(1L).anyTimes();
-        
+
         // test
         replay(chdlr.sw, lock, ml);
         ld.addListener(OFType.VENDOR, ml);
@@ -1143,12 +1140,23 @@ public class ControllerTest extends FloodlightTestCase
         // Make sure controller attempts to reset switch master
         expect(sw.getAttribute("supportsNxRole")).andReturn(true).anyTimes();
         expect(sw.getNextTransactionId()).andReturn(0).anyTimes();
+        sw.write(EasyMock.<List<OFMessage>> anyObject(),
+                 (FloodlightContext)anyObject());
 
         // test
         replay(sw, lock);
         chdlr.processOFMessage(error);
-        // Verify there is a pending role change request
-        assertTrue(controller.roleChanger.pendingTasks.poll() != null);
+        DelayQueue<RoleChangeTask> pendingTasks =
+                controller.roleChanger.pendingTasks;
+        synchronized (pendingTasks) {
+            RoleChangeTask t;
+            while ((t = pendingTasks.peek()) == null ||
+                    RoleChanger.RoleChangeTask.Type.TIMEOUT != t.type) {
+                pendingTasks.wait();
+            }
+        }
+        // Now there should be exactly one timeout task pending
+        assertEquals(1, pendingTasks.size());
    }
 
     // Helper function.
@@ -1159,19 +1167,19 @@ public class ControllerTest extends FloodlightTestCase
         chdlr.sw = createMock(IOFSwitch.class);
         return chdlr;
     }
-    
+
     // Helper function
     protected OFVendor getRoleReplyMsgForRoleReplyTest(int xid, int nicira_role) {
         OFVendor msg = new OFVendor();
         msg.setXid(xid);
         msg.setVendor(OFNiciraVendorData.NX_VENDOR_ID);
-        OFRoleReplyVendorData roleReplyVendorData = 
+        OFRoleReplyVendorData roleReplyVendorData =
                 new OFRoleReplyVendorData(OFRoleReplyVendorData.NXT_ROLE_REPLY);
         msg.setVendorData(roleReplyVendorData);
         roleReplyVendorData.setRole(nicira_role);
         return msg;
     }
-    
+
     // Helper function
     protected void setupPendingRoleRequest(IOFSwitch sw, int xid, Role role,
             long cookie) {
@@ -1182,10 +1190,10 @@ public class ControllerTest extends FloodlightTestCase
                 new PendingRoleRequestEntry(xid, role, cookie);
         pendingList.add(entry);
     }
-    
+
     /** invalid role in role reply */
-    @Test 
-    public void testNiciraRoleReplyInvalidRole() 
+    @Test
+    public void testNiciraRoleReplyInvalidRole()
                     throws Exception {
         int xid = 424242;
         Controller.OFChannelHandler chdlr = getChannelHandlerForRoleReplyTest();
@@ -1196,17 +1204,17 @@ public class ControllerTest extends FloodlightTestCase
         chdlr.processOFMessage(msg);
         verify(chdlr.sw, ch);
     }
-    
+
     /** First role reply message received: transition from slave to master */
-    @Test 
-    public void testNiciraRoleReplySlave2MasterFristTime() 
+    @Test
+    public void testNiciraRoleReplySlave2MasterFristTime()
                     throws Exception {
         int xid = 424242;
         Controller.OFChannelHandler chdlr = getChannelHandlerForRoleReplyTest();
         OFVendor msg = getRoleReplyMsgForRoleReplyTest(xid,
                                        OFRoleReplyVendorData.NX_ROLE_MASTER);
 
-        setupPendingRoleRequest(chdlr.sw, xid, Role.MASTER, 123456);                
+        setupPendingRoleRequest(chdlr.sw, xid, Role.MASTER, 123456);
         expect(chdlr.sw.getHARole()).andReturn(null);
         chdlr.sw.setHARole(Role.MASTER, true);
         setupSwitchForAddSwitch(chdlr.sw, 1L);
@@ -1217,18 +1225,18 @@ public class ControllerTest extends FloodlightTestCase
         assertSame("activeSwitches must contain this switch",
                    chdlr.sw, controller.activeSwitches.get(1L));
     }
-    
-    
+
+
     /** Not first role reply message received: transition from slave to master */
-    @Test 
-    public void testNiciraRoleReplySlave2MasterNotFristTime() 
+    @Test
+    public void testNiciraRoleReplySlave2MasterNotFristTime()
                     throws Exception {
         int xid = 424242;
         Controller.OFChannelHandler chdlr = getChannelHandlerForRoleReplyTest();
         OFVendor msg = getRoleReplyMsgForRoleReplyTest(xid,
                                        OFRoleReplyVendorData.NX_ROLE_MASTER);
 
-        setupPendingRoleRequest(chdlr.sw, xid, Role.MASTER, 123456);        
+        setupPendingRoleRequest(chdlr.sw, xid, Role.MASTER, 123456);
         expect(chdlr.sw.getHARole()).andReturn(Role.SLAVE);
         chdlr.sw.setHARole(Role.MASTER, true);
         setupSwitchForAddSwitch(chdlr.sw, 1L);
@@ -1239,17 +1247,17 @@ public class ControllerTest extends FloodlightTestCase
         assertSame("activeSwitches must contain this switch",
                    chdlr.sw, controller.activeSwitches.get(1L));
     }
-    
+
     /** transition from slave to equal */
-    @Test 
-    public void testNiciraRoleReplySlave2Equal() 
+    @Test
+    public void testNiciraRoleReplySlave2Equal()
                     throws Exception {
         int xid = 424242;
         Controller.OFChannelHandler chdlr = getChannelHandlerForRoleReplyTest();
         OFVendor msg = getRoleReplyMsgForRoleReplyTest(xid,
                                        OFRoleReplyVendorData.NX_ROLE_OTHER);
-        
-        setupPendingRoleRequest(chdlr.sw, xid, Role.EQUAL, 123456);                
+
+        setupPendingRoleRequest(chdlr.sw, xid, Role.EQUAL, 123456);
         expect(chdlr.sw.getHARole()).andReturn(null);
         chdlr.sw.setHARole(Role.EQUAL, true);
         setupSwitchForAddSwitch(chdlr.sw, 1L);
@@ -1260,16 +1268,16 @@ public class ControllerTest extends FloodlightTestCase
         assertSame("activeSwitches must contain this switch",
                    chdlr.sw, controller.activeSwitches.get(1L));
     };
-    
+
     @Test
     /** Slave2Slave transition ==> no change */
     public void testNiciraRoleReplySlave2Slave() throws Exception{
         int xid = 424242;
         Controller.OFChannelHandler chdlr = getChannelHandlerForRoleReplyTest();
-        OFVendor msg = getRoleReplyMsgForRoleReplyTest(xid, 
+        OFVendor msg = getRoleReplyMsgForRoleReplyTest(xid,
                                        OFRoleReplyVendorData.NX_ROLE_SLAVE);
-        
-        setupPendingRoleRequest(chdlr.sw, xid, Role.SLAVE, 123456);                
+
+        setupPendingRoleRequest(chdlr.sw, xid, Role.SLAVE, 123456);
         expect(chdlr.sw.getHARole()).andReturn(null);
         chdlr.sw.setHARole(Role.SLAVE, true);
         expect(chdlr.sw.getId()).andReturn(1L).anyTimes();
@@ -1279,19 +1287,19 @@ public class ControllerTest extends FloodlightTestCase
         replay(chdlr.sw);
         chdlr.processOFMessage(msg);
         verify(chdlr.sw);
-        assertTrue("activeSwitches must be empty", 
+        assertTrue("activeSwitches must be empty",
                    controller.activeSwitches.isEmpty());
     }
-    
+
     @Test
     /** Equal2Master transition ==> no change */
     public void testNiciraRoleReplyEqual2Master() throws Exception{
         int xid = 424242;
         Controller.OFChannelHandler chdlr = getChannelHandlerForRoleReplyTest();
-        OFVendor msg = getRoleReplyMsgForRoleReplyTest(xid, 
+        OFVendor msg = getRoleReplyMsgForRoleReplyTest(xid,
                                        OFRoleReplyVendorData.NX_ROLE_MASTER);
-        
-        setupPendingRoleRequest(chdlr.sw, xid, Role.MASTER, 123456);                
+
+        setupPendingRoleRequest(chdlr.sw, xid, Role.MASTER, 123456);
         expect(chdlr.sw.getHARole()).andReturn(null);
         chdlr.sw.setHARole(Role.MASTER, true);
         expect(chdlr.sw.getId()).andReturn(1L).anyTimes();
@@ -1305,16 +1313,16 @@ public class ControllerTest extends FloodlightTestCase
         assertSame("activeSwitches must contain this switch",
                    chdlr.sw, controller.activeSwitches.get(1L));
     }
-    
-    @Test 
-    public void testNiciraRoleReplyMaster2Slave() 
+
+    @Test
+    public void testNiciraRoleReplyMaster2Slave()
                     throws Exception {
         int xid = 424242;
         Controller.OFChannelHandler chdlr = getChannelHandlerForRoleReplyTest();
-        OFVendor msg = getRoleReplyMsgForRoleReplyTest(xid, 
+        OFVendor msg = getRoleReplyMsgForRoleReplyTest(xid,
                                        OFRoleReplyVendorData.NX_ROLE_SLAVE);
-        
-        setupPendingRoleRequest(chdlr.sw, xid, Role.SLAVE, 123456);                
+
+        setupPendingRoleRequest(chdlr.sw, xid, Role.SLAVE, 123456);
         expect(chdlr.sw.getHARole()).andReturn(null);
         chdlr.sw.setHARole(Role.SLAVE, true);
         expect(chdlr.sw.getId()).andReturn(1L).anyTimes();
@@ -1327,10 +1335,10 @@ public class ControllerTest extends FloodlightTestCase
         replay(chdlr.sw);
         chdlr.processOFMessage(msg);
         verify(chdlr.sw);
-        assertTrue("activeSwitches must be empty", 
+        assertTrue("activeSwitches must be empty",
                    controller.activeSwitches.isEmpty());
     }
-    
+
     /**
      * Tests that you can't remove a switch from the active
      * switch list.
@@ -1351,7 +1359,7 @@ public class ControllerTest extends FloodlightTestCase
         assertTrue(exceptionThrown);
         verify(sw);
     }
-    
+
     public void verifyPortChangedUpdateInQueue(IOFSwitch sw) throws Exception {
         assertEquals(1, controller.updates.size());
         IUpdate update = controller.updates.take();
@@ -1360,21 +1368,21 @@ public class ControllerTest extends FloodlightTestCase
         assertEquals(sw, swUpdate.sw);
         assertEquals(SwitchUpdateType.PORTCHANGED, swUpdate.switchUpdateType);
     }
-    
+
     /*
      * Test handlePortStatus()
      * TODO: test correct updateStorage behavior!
      */
-    @Test 
+    @Test
     public void testHandlePortStatus() throws Exception {
         IOFSwitch sw = createMock(IOFSwitch.class);
         OFPhysicalPort port = new OFPhysicalPort();
         port.setName("myPortName1");
         port.setPortNumber((short)42);
-        
+
         OFPortStatus ofps = new OFPortStatus();
         ofps.setDesc(port);
-        
+
         ofps.setReason((byte)OFPortReason.OFPPR_ADD.ordinal());
         sw.setPort(port);
         expectLastCall().once();
@@ -1383,7 +1391,7 @@ public class ControllerTest extends FloodlightTestCase
         verify(sw);
         verifyPortChangedUpdateInQueue(sw);
         reset(sw);
-        
+
         ofps.setReason((byte)OFPortReason.OFPPR_MODIFY.ordinal());
         sw.setPort(port);
         expectLastCall().once();
@@ -1392,7 +1400,7 @@ public class ControllerTest extends FloodlightTestCase
         verify(sw);
         verifyPortChangedUpdateInQueue(sw);
         reset(sw);
-        
+
         ofps.setReason((byte)OFPortReason.OFPPR_DELETE.ordinal());
         sw.deletePort(port.getPortNumber());
         expectLastCall().once();
@@ -1423,8 +1431,8 @@ public class ControllerTest extends FloodlightTestCase
         }
         return null;
     }
-    
-    private void setupSwitchForDispatchTest(IOFSwitch sw, 
+
+    private void setupSwitchForDispatchTest(IOFSwitch sw,
                                             boolean isConnected,
                                             Role role) {
         Lock lock = createNiceMock(Lock.class);
@@ -1434,10 +1442,10 @@ public class ControllerTest extends FloodlightTestCase
         expect(sw.isConnected()).andReturn(isConnected).anyTimes();
         expect(sw.getHARole()).andReturn(role).anyTimes();
         replay(lock);
-        
+
     }
-    
-    @Test 
+
+    @Test
     public void testMessageDispatch() throws Exception {
         // Mock a dummy packet in
         // Build our test packet
@@ -1458,7 +1466,7 @@ public class ControllerTest extends FloodlightTestCase
                 .setTargetProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.2")));
         byte[] testPacketSerialized = testPacket.serialize();
 
-        // Build the PacketIn        
+        // Build the PacketIn
         OFPacketIn pi = ((OFPacketIn) new BasicFactory().getMessage(OFType.PACKET_IN))
                 .setBufferId(-1)
                 .setInPort((short) 1)
@@ -1466,60 +1474,60 @@ public class ControllerTest extends FloodlightTestCase
                 .setReason(OFPacketInReason.NO_MATCH)
                 .setTotalLength((short) testPacketSerialized.length);
 
-        
-        // Mock switch and add to data structures 
+
+        // Mock switch and add to data structures
         IOFSwitch sw = createMock(IOFSwitch.class);
-        
+
         controller.connectedSwitches.add(sw);
-        
-        // create a channel handler 
+
+        // create a channel handler
         OFChannelState state = new OFChannelState();
         state.hsState = HandshakeState.READY;
         Controller.OFChannelHandler chdlr = controller.new OFChannelHandler(state);
         chdlr.sw = sw;
-        
-        // mock role changer 
-        RoleChanger roleChanger = createMock(RoleChanger.class); 
-        roleChanger.submitRequest(eq(controller.connectedSwitches), 
+
+        // mock role changer
+        RoleChanger roleChanger = createMock(RoleChanger.class);
+        roleChanger.submitRequest(eq(controller.connectedSwitches),
                                   anyObject(Role.class));
         expectLastCall().anyTimes();
         controller.roleChanger = roleChanger;
-        
-        
-        // Mock message listener and add 
+
+
+        // Mock message listener and add
         IOFMessageListener listener = createNiceMock(IOFMessageListener.class);
         expect(listener.getName()).andReturn("foobar").anyTimes();
         replay(listener);
         controller.addOFMessageListener(OFType.PACKET_IN, listener);
         resetToStrict(listener);
-        
-        
-        assertEquals("Check that update queue is empty", 0, 
+
+
+        assertEquals("Check that update queue is empty", 0,
                     controller.updates.size());
-        
-        
+
+
         replay(roleChanger);
-        
+
         //-------------------
         // Test 1: role is master, switch is master and in activeMap
-        // we expect the msg to be dispatched 
+        // we expect the msg to be dispatched
         reset(sw);
         resetToDefault(listener);
         controller.activeSwitches.put(1L, sw);
         setupSwitchForDispatchTest(sw, true, Role.MASTER);
-        listener.receive(same(sw), same(pi), 
+        listener.receive(same(sw), same(pi),
                          anyObject(FloodlightContext.class));
         expectLastCall().andReturn(Command.STOP).once();
         replay(sw, listener);
         chdlr.processOFMessage(pi);
         verify(sw, listener);
         assertEquals(0, controller.updates.size());
-        
-        
+
+
         //-------------------
         // Test 1b: role is master, switch is master and in activeMap
-        // but switch is not connected 
-        // no message dispatched 
+        // but switch is not connected
+        // no message dispatched
         reset(sw);
         resetToDefault(listener);
         controller.activeSwitches.put(1L, sw);
@@ -1528,11 +1536,11 @@ public class ControllerTest extends FloodlightTestCase
         chdlr.processOFMessage(pi);
         verify(sw, listener);
         assertEquals(0, controller.updates.size());
-        
-        
+
+
         //-------------------
         // Test 1c: role is master, switch is slave and in activeMap
-        // no message dispatched 
+        // no message dispatched
         reset(sw);
         resetToDefault(listener);
         controller.activeSwitches.put(1L, sw);
@@ -1541,11 +1549,11 @@ public class ControllerTest extends FloodlightTestCase
         chdlr.processOFMessage(pi);
         verify(sw, listener);
         assertEquals(0, controller.updates.size());
-        
-        
+
+
         //-------------------
         // Test 1d: role is master, switch is master but not in activeMap
-        // we expect the msg to be dispatched 
+        // we expect the msg to be dispatched
         reset(sw);
         resetToDefault(listener);
         controller.activeSwitches.remove(1L);
@@ -1553,18 +1561,18 @@ public class ControllerTest extends FloodlightTestCase
         replay(sw, listener);
         chdlr.processOFMessage(pi);
         verify(sw, listener);
-        assertEquals(0, controller.updates.size());        
-        
-        
-        
+        assertEquals(0, controller.updates.size());
+
+
+
         //-------------------
         // Test 2: check correct dispatch and HA notification behavior
-        // We set the role to slave but do not notify the clients 
+        // We set the role to slave but do not notify the clients
         reset(sw);
         resetToDefault(listener);
         controller.activeSwitches.put(1L, sw);
         setupSwitchForDispatchTest(sw, true, Role.MASTER);
-        listener.receive(same(sw), same(pi), 
+        listener.receive(same(sw), same(pi),
                          anyObject(FloodlightContext.class));
         expectLastCall().andReturn(Command.STOP).once();
         replay(sw, listener);
@@ -1573,10 +1581,10 @@ public class ControllerTest extends FloodlightTestCase
         chdlr.processOFMessage(pi);
         verify(sw, listener);
         assertEquals(1, controller.updates.size());
-        
-        // Now notify listeners 
+
+        // Now notify listeners
         Controller.IUpdate upd = controller.updates.poll(1, TimeUnit.NANOSECONDS);
-        assertTrue("Check that update is HARoleUpdate", 
+        assertTrue("Check that update is HARoleUpdate",
                    upd instanceof Controller.HARoleUpdate);
         upd.dispatch();
         resetToDefault(listener);
@@ -1584,7 +1592,7 @@ public class ControllerTest extends FloodlightTestCase
         chdlr.processOFMessage(pi);
         verify(listener);
         assertEquals(0, controller.updates.size());
-        
+
         // transition back to master but don't notify yet
         resetToDefault(listener);
         replay(listener);
@@ -1593,40 +1601,40 @@ public class ControllerTest extends FloodlightTestCase
         chdlr.processOFMessage(pi);
         verify(listener);
         assertEquals(1, controller.updates.size());
-        
-        // now notify listeners 
+
+        // now notify listeners
         upd = controller.updates.poll(1, TimeUnit.NANOSECONDS);
-        assertTrue("Check that update is HARoleUpdate", 
+        assertTrue("Check that update is HARoleUpdate",
                    upd instanceof Controller.HARoleUpdate);
         upd.dispatch();
         resetToDefault(listener);
-        listener.receive(same(sw), same(pi), 
+        listener.receive(same(sw), same(pi),
                          anyObject(FloodlightContext.class));
         expectLastCall().andReturn(Command.STOP).once();
         replay(listener);
         chdlr.processOFMessage(pi);
         verify(listener);
         assertEquals(0, controller.updates.size());
-        
+
         verify(sw);
     }
-    
-    
+
+
     /*
      * Test correct timing behavior between HA Role notification and dispatching
-     * OFMessages to listeners. 
+     * OFMessages to listeners.
      * When transitioning to SLAVE: stop dispatching message before sending
      *    notifications
      * When transitioning to MASTER: start dispatching messages after sending
      *     notifications
-     * (This implies that messages should not be dispatched while the 
-     * notifications are being sent). 
-     * 
+     * (This implies that messages should not be dispatched while the
+     * notifications are being sent).
+     *
      * We encapsulate the logic for this in a class that implements both
      * IHAListener and IOFMessageListener. Then we inject an OFMessage fom
-     * the IHAListener and check that it gets dropped correctly. 
+     * the IHAListener and check that it gets dropped correctly.
      */
-    @Test 
+    @Test
     public void testRoleNotifcationAndMessageDispatch() throws Exception {
         class TestRoleNotificationsAndDispatch implements IHAListener, IOFMessageListener {
             OFPacketIn pi;
@@ -1634,7 +1642,7 @@ public class ControllerTest extends FloodlightTestCase
             IOFSwitch sw;
             private boolean haveReceived;
             private boolean doInjectMessageFromHAListener;
-            
+
             public TestRoleNotificationsAndDispatch() {
                 IPacket testPacket = new Ethernet()
                 .setSourceMACAddress("00:44:33:22:11:00")
@@ -1652,78 +1660,78 @@ public class ControllerTest extends FloodlightTestCase
                         .setTargetHardwareAddress(Ethernet.toMACAddress("00:11:22:33:44:55"))
                         .setTargetProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.2")));
                 byte[] testPacketSerialized = testPacket.serialize();
-        
-                // Build the PacketIn        
+
+                // Build the PacketIn
                 pi = ((OFPacketIn) new BasicFactory().getMessage(OFType.PACKET_IN))
                         .setBufferId(-1)
                         .setInPort((short) 1)
                         .setPacketData(testPacketSerialized)
                         .setReason(OFPacketInReason.NO_MATCH)
                         .setTotalLength((short) testPacketSerialized.length);
-                
-                // Mock switch and add to data structures 
+
+                // Mock switch and add to data structures
                 sw = createMock(IOFSwitch.class);
                 controller.connectedSwitches.add(sw);
                 controller.activeSwitches.put(1L, sw);
                 setupSwitchForDispatchTest(sw, true, Role.MASTER);
                 replay(sw);
-                
-                // create a channel handler 
+
+                // create a channel handler
                 OFChannelState state = new OFChannelState();
                 state.hsState = HandshakeState.READY;
                 chdlr = controller.new OFChannelHandler(state);
                 chdlr.sw = this.sw;
-                
+
                 // add ourself as listeners
                 controller.addOFMessageListener(OFType.PACKET_IN, this);
                 controller.addHAListener(this);
             }
-            
-            
+
+
             private void injectMessage(boolean shouldReceive) throws Exception {
                 haveReceived = false;
                 chdlr.processOFMessage(pi);
                 assertEquals(shouldReceive, haveReceived);
             }
-            
+
             public void transitionToSlave() throws Exception {
                 IUpdate update;
-                
+
                 // Bring controller into well defined state for MASTER
-                doInjectMessageFromHAListener = false; 
+                doInjectMessageFromHAListener = false;
                 update = controller.new HARoleUpdate(Role.MASTER, Role.SLAVE);
                 update.dispatch();
                 doInjectMessageFromHAListener = true;
-                
-                
-                // inject message. Listener called 
+
+
+                // inject message. Listener called
                 injectMessage(true);
-                // Dispatch update 
+                // Dispatch update
                 update = controller.new HARoleUpdate(Role.SLAVE, Role.MASTER);
                 update.dispatch();
                 // inject message. Listener not called
                 injectMessage(false);
             }
-            
+
             public void transitionToMaster() throws Exception {
                 IUpdate update;
-                
+
                 // Bring controller into well defined state for SLAVE
-                doInjectMessageFromHAListener = false; 
+                doInjectMessageFromHAListener = false;
                 update = controller.new HARoleUpdate(Role.SLAVE, Role.MASTER);
                 update.dispatch();
                 doInjectMessageFromHAListener = true;
-                
-                
-                // inject message. Listener not called 
+
+
+                // inject message. Listener not called
                 injectMessage(false);
-                // Dispatch update 
+                // Dispatch update
                 update = controller.new HARoleUpdate(Role.MASTER, Role.SLAVE);
                 update.dispatch();
                 // inject message. Listener called
                 injectMessage(true);
             }
-            
+
             //---------------
             // IHAListener
             //---------------
@@ -1737,7 +1745,7 @@ public class ControllerTest extends FloodlightTestCase
                     e.printStackTrace();
                 }
             }
-            
+
             @Override
             public
                     void
@@ -1746,7 +1754,7 @@ public class ControllerTest extends FloodlightTestCase
                                              Map<String, String> removedControllerNodeIPs) {
                 // TODO Auto-generated method stub
             }
-            
+
             //-------------------------
             // IOFMessageListener
             //-------------------------
@@ -1763,18 +1771,18 @@ public class ControllerTest extends FloodlightTestCase
                 return false;
             }
             @Override
-            public Command receive(IOFSwitch sw, 
-                                   OFMessage msg, 
+            public Command receive(IOFSwitch sw,
+                                   OFMessage msg,
                                    FloodlightContext cntx) {
                 haveReceived = true;
                 return Command.STOP;
             }
         }
-        
+
         TestRoleNotificationsAndDispatch x = new TestRoleNotificationsAndDispatch();
         x.transitionToSlave();
         x.transitionToMaster();
-        
+
     }
 
 }
diff --git a/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java b/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java
index 40986e9f2577af119523534ac3762404bb66c6f0..2efb2cd5c684dd7a18888a9f3f8281bd7f1689aa 100644
--- a/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java
+++ b/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java
@@ -780,10 +780,9 @@ public class DeviceManagerImplTest extends FloodlightTestCase {
         verify(mockListener);
 
         reset(mockListener);
-        //mockListener.deviceMoved((isA(IDevice.class)));
+        mockListener.deviceMoved((isA(IDevice.class)));
         //mockListener.deviceIPV4AddrChanged((isA(IDevice.class)));
         replay(mockListener);
-        // there is no device moved because entity 1 was not learned due to suppression
         d = deviceManager.learnDeviceByEntity(entity2);
         assertEquals(1, deviceManager.getAllDevices().size());
         aps = d.getAttachmentPoints();
diff --git a/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java b/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java
index 78fb6112d0d08a927090f6d35cf924a328db8d69..6e894a359cc2da78bbbde3b523cb329e7f552210 100644
--- a/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java
+++ b/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java
@@ -357,9 +357,9 @@ public class ForwardingTest extends FloodlightTestCase {
         OFFlowMod fm2 = fm1.clone();
         ((OFActionOutput)fm2.getActions().get(0)).setPort((short) 3);
 
-        sw1.write(capture(wc1), capture(bc1));
+        sw1.writeThrottled(capture(wc1), capture(bc1));
         expectLastCall().anyTimes(); 
-        sw2.write(capture(wc2), capture(bc2));
+        sw2.writeThrottled(capture(wc2), capture(bc2));
         expectLastCall().anyTimes(); 
 
         reset(topology);
@@ -420,8 +420,8 @@ public class ForwardingTest extends FloodlightTestCase {
                         OFActionOutput.MINIMUM_LENGTH);
 
         // Record expected packet-outs/flow-mods
-        sw1.write(fm1, cntx);
-        sw1.write(packetOut, cntx);
+        sw1.writeThrottled(fm1, cntx);
+        sw1.writeThrottled(packetOut, cntx);
         
         reset(topology);
         expect(topology.isIncomingBroadcastAllowed(anyLong(), anyShort())).andReturn(true).anyTimes();
@@ -473,9 +473,9 @@ public class ForwardingTest extends FloodlightTestCase {
         // 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.write(fm1, cntx);
+        sw1.writeThrottled(fm1, cntx);
         expectLastCall().once();
-        sw1.write(packetOut, cntx);
+        sw1.writeThrottled(packetOut, cntx);
         expectLastCall().times(3);
         
         reset(topology);
@@ -508,7 +508,7 @@ public class ForwardingTest extends FloodlightTestCase {
                                               .anyTimes();
         expect(sw1.hasAttribute(IOFSwitch.PROP_SUPPORTS_OFPP_FLOOD))
                 .andReturn(true).anyTimes();
-        sw1.write(packetOutFlooded, cntx);
+        sw1.writeThrottled(packetOutFlooded, cntx);
         expectLastCall().once();
         replay(sw1, sw2, routingEngine, topology);
         forwarding.receive(sw1, this.packetIn, cntx);
diff --git a/src/test/java/net/floodlightcontroller/loadbalancer/LoadBalancerTest.java b/src/test/java/net/floodlightcontroller/loadbalancer/LoadBalancerTest.java
index 7311ac1aadd75dd13a19637f97a7edf7ff0e552b..2aeefa45658a1d595be5f14247bac1569fe14efe 100644
--- a/src/test/java/net/floodlightcontroller/loadbalancer/LoadBalancerTest.java
+++ b/src/test/java/net/floodlightcontroller/loadbalancer/LoadBalancerTest.java
@@ -433,7 +433,7 @@ public class LoadBalancerTest extends FloodlightTestCase {
      expect(sw1.getStringId()).andReturn("00:00:00:00:00:01").anyTimes();
      expect(sw1.getAttribute(IOFSwitch.PROP_FASTWILDCARDS)).andReturn((Integer)fastWildcards).anyTimes();
      expect(sw1.hasAttribute(IOFSwitch.PROP_SUPPORTS_OFPP_TABLE)).andReturn(true).anyTimes();
-     sw1.write(capture(wc1), capture(bc1));
+     sw1.writeThrottled(capture(wc1), capture(bc1));
      expectLastCall().anyTimes(); 
      sw1.flush();
      expectLastCall().anyTimes();
diff --git a/src/test/java/net/floodlightcontroller/packet/IPv4Test.java b/src/test/java/net/floodlightcontroller/packet/IPv4Test.java
index acea62d25f195b35f012b8714e70983adf84e8af..c62b77602b2124eb9305162ba9e0e7ccd48df6cf 100644
--- a/src/test/java/net/floodlightcontroller/packet/IPv4Test.java
+++ b/src/test/java/net/floodlightcontroller/packet/IPv4Test.java
@@ -107,6 +107,40 @@ public class IPv4Test {
         IPv4 packet = new IPv4();
         packet.deserialize(pktSerializedPadded, 0, pktSerializedPadded.length);
         byte[] pktSerialized1 = packet.serialize();
+        // Padding is ignored
         assertTrue(Arrays.equals(pktSerialized, pktSerialized1));
     }
+
+    @Test
+    public void testDeserializeFragment() {
+        // IP packet with more frag bit set
+        byte[] pktSerializedFirstFrag = new byte[] { 0x45, 0x00,
+                0x00, 0x2e, 0x41, (byte) 0xbe, 0x20, 0x00, 0x40, 0x06,
+                (byte) 0xd4, (byte) 0xf0, (byte) 0xc0, (byte) 0xa8, 0x02, (byte) 0xdb, (byte) 0xd0, 0x55,
+                (byte) 0x90, 0x42, (byte) 0xd5, 0x48, 0x01, (byte) 0xbb, (byte) 0xe3, 0x50,
+                (byte) 0xb2, 0x2f, (byte) 0xfc, (byte) 0xf8, (byte) 0xa8, 0x2c, 0x50, 0x18,
+                (byte) 0xff, (byte) 0xff, 0x24, 0x3c, 0x00, 0x00, 0x14, 0x03,
+                0x01, 0x00, 0x01, 0x01,
+        };
+        IPv4 packet1 = new IPv4();
+        packet1.deserialize(pktSerializedFirstFrag, 0, pktSerializedFirstFrag.length);
+        byte[] pktSerialized1 = packet1.serialize();
+        assertTrue(packet1.isFragment());
+        assertTrue(Arrays.equals(pktSerializedFirstFrag, pktSerialized1));
+
+        // IP packet with offset
+        byte[] pktSerializedLastFrag = new byte[] { 0x45, 0x00,
+                0x00, 0x2e, 0x41, (byte) 0xbe, 0x01, 0x00, 0x40, 0x06,
+                (byte) 0xd4, (byte) 0xf0, (byte) 0xc0, (byte) 0xa8, 0x02, (byte) 0xdb, (byte) 0xd0, 0x55,
+                (byte) 0x90, 0x42, (byte) 0xd5, 0x48, 0x01, (byte) 0xbb, (byte) 0xe3, 0x50,
+                (byte) 0xb2, 0x2f, (byte) 0xfc, (byte) 0xf8, (byte) 0xa8, 0x2c, 0x50, 0x18,
+                (byte) 0xff, (byte) 0xff, 0x24, 0x3c, 0x00, 0x00, 0x14, 0x03,
+                0x01, 0x00, 0x01, 0x01,
+        };
+        IPv4 packet2 = new IPv4();
+        packet2.deserialize(pktSerializedLastFrag, 0, pktSerializedLastFrag.length);
+        byte[] pktSerialized2 = packet2.serialize();
+        assertTrue(packet2.isFragment());
+        assertTrue(Arrays.equals(pktSerializedLastFrag, pktSerialized2));
+    }
 }
diff --git a/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java b/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java
index 5f09dc7dc8d00471f00a8ce1e2f13da01079e568..29191365cddad3344d7390f4d363cfcd0eaf8820 100644
--- a/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java
+++ b/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java
@@ -102,9 +102,22 @@ public class OFMessageDamperMockSwitch implements IOFSwitch {
         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 {
@@ -420,4 +433,4 @@ public class OFMessageDamperMockSwitch implements IOFSwitch {
         return false;
     }
 
-}
\ No newline at end of file
+}