diff --git a/logback.xml b/logback.xml
index f5163007d4c2af4ea21c0c62b023614e2689ee79..0485717cddefe39bd795685712cce3e4c0af18ad 100644
--- a/logback.xml
+++ b/logback.xml
@@ -7,9 +7,8 @@
   <root level="DEBUG">
     <appender-ref ref="STDOUT" />
   </root>
-  <logger name="org" level="DEBUG"/>
+  <logger name="io" level="INFO"></logger> <!-- Netty logging -->
   <logger name="LogService" level="DEBUG"/> <!-- Restlet access logging -->
-  <logger name="net.floodlightcontroller" level="DEBUG"/>
-  <logger name="net.floodlightcontroller.logging" level="DEBUG"/>
+  <logger name="net.floodlightcontroller" level="INFO"/>
   <logger name="org.sdnplatform" level="INFO"/>
 </configuration>
diff --git a/src/main/java/net/floodlightcontroller/core/IOFConnection.java b/src/main/java/net/floodlightcontroller/core/IOFConnection.java
index 21855fd33aeb96714451ae38d5dee1b88dc16383..2537d40a7984c6843ed8b4b206e4cdce53034711 100644
--- a/src/main/java/net/floodlightcontroller/core/IOFConnection.java
+++ b/src/main/java/net/floodlightcontroller/core/IOFConnection.java
@@ -22,12 +22,6 @@ public interface IOFConnection extends IOFMessageWriter {
      */
     Date getConnectedSince();
 
-    /**
-     * Flush all flows queued for this switch in the current thread.
-     * NOTE: The contract is limited to the current thread
-     */
-    void flush();
-
     /** @return the DatapathId of the switch associated with the connection */
     DatapathId getDatapathId();
 
diff --git a/src/main/java/net/floodlightcontroller/core/IOFSwitch.java b/src/main/java/net/floodlightcontroller/core/IOFSwitch.java
index 9e51dd1f46124c8e8633c31df8d737c654f51054..cc138ecc6207be57b387c89c630faeb92b224aad 100644
--- a/src/main/java/net/floodlightcontroller/core/IOFSwitch.java
+++ b/src/main/java/net/floodlightcontroller/core/IOFSwitch.java
@@ -290,13 +290,6 @@ public interface IOFSwitch extends IOFMessageWriter {
      */
     OFFactory getOFFactory();
 
-    /**
-     * Flush all flows queued for this switch on all connections that were written by the current thread.
-     *
-     *
-     */
-    void flush();
-
     /**
      * Gets the OF connections for this switch instance
      * @return Collection of IOFConnection
diff --git a/src/main/java/net/floodlightcontroller/core/internal/Controller.java b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
index fa8194649cc4fdc862fe584361592d3a94ff9aca..3a15697b68a5cfb0524716d5b8211ea2a7681157 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/Controller.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
@@ -133,7 +133,8 @@ public class Controller implements IFloodlightProviderService, IStorageSourceLis
     // Configuration options
     private static TransportPort openFlowPort = TransportPort.of(6653); // new registered OF port number
 	private static Set<IPv4Address> openFlowAddresses = new HashSet<IPv4Address>();
-    protected int workerThreads = 0;
+	public static final int SEND_BUFFER_SIZE = 4 * 1024 * 1024;
+    protected int workerThreads = 16;
     
     // The id for this controller node. Should be unique for each controller
     // node in a controller cluster.
@@ -143,8 +144,7 @@ public class Controller implements IFloodlightProviderService, IStorageSourceLis
     // if they should operate in ACTIVE / STANDBY
     protected volatile HARole notifiedRole;
 
-    private static final String
-            INITIAL_ROLE_CHANGE_DESCRIPTION = "Controller startup.";
+    private static final String INITIAL_ROLE_CHANGE_DESCRIPTION = "Controller startup.";
     /**
      * NOTE: roleManager is not 'final' because it's initialized at run time
      * based on parameters that are only available in init()
@@ -176,10 +176,6 @@ public class Controller implements IFloodlightProviderService, IStorageSourceLis
             FLOW_COLUMN_ACCESS_PRIORITY,
             FLOW_COLUMN_CORE_PRIORITY
     };
-    
-    // Perf. related configuration
-    protected static final int SEND_BUFFER_SIZE = 128 * 1024;
-    public static final int BATCH_MAX_SIZE = 1; //TODO @Ryan this was 100. Causes packet_out messages to stall until 100 accumulated...
     protected static final boolean ALWAYS_DECODE_ETH = true;
 
     // Set of port name prefixes that will be classified as uplink ports,
@@ -590,7 +586,6 @@ public class Controller implements IFloodlightProviderService, IStorageSourceLis
         if (m == null)
             throw new NullPointerException("OFMessage must not be null");
 
-        // FIXME floodlight context not supported any more
         FloodlightContext bc = new FloodlightContext();
 
         List<IOFMessageListener> listeners = null;
diff --git a/src/main/java/net/floodlightcontroller/core/internal/NullConnection.java b/src/main/java/net/floodlightcontroller/core/internal/NullConnection.java
index 2db236e45f64a6e475e4729d3e0653604f6d918a..75ce28049cc4b086d5bf1c5ac3a6d3872b48d0c9 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/NullConnection.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/NullConnection.java
@@ -77,11 +77,6 @@ public class NullConnection implements IOFConnectionBackend, IOFMessageWriter {
         // noop
     }
 
-    @Override
-    public void flush() {
-        // noop
-    }
-
     @Override
     public <R extends OFMessage> ListenableFuture<R> writeRequest(OFRequest<R> request) {
         return Futures.immediateFailedFuture(new SwitchDisconnectedException(getDatapathId()));
diff --git a/src/main/java/net/floodlightcontroller/core/internal/OFConnection.java b/src/main/java/net/floodlightcontroller/core/internal/OFConnection.java
index 791ced36bf710eb2a59f2d2def57a1f68f5539a7..1039a0e933926577efeb5b26f229c66431146cf4 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/OFConnection.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/OFConnection.java
@@ -50,7 +50,6 @@ import org.projectfloodlight.openflow.protocol.OFRequest;
 import org.projectfloodlight.openflow.protocol.OFStatsReply;
 import org.projectfloodlight.openflow.protocol.OFStatsReplyFlags;
 import org.projectfloodlight.openflow.protocol.OFStatsRequest;
-import org.projectfloodlight.openflow.protocol.OFType;
 import org.projectfloodlight.openflow.types.DatapathId;
 import org.projectfloodlight.openflow.types.OFAuxId;
 import org.projectfloodlight.openflow.types.U64;
@@ -71,323 +70,329 @@ import com.google.common.util.concurrent.ListenableFuture;
  * @author Andreas Wundsam <andreas.wundsam@bigswitch.com>
  */
 public class OFConnection implements IOFConnection, IOFConnectionBackend{
-    private static final Logger logger = LoggerFactory.getLogger(OFConnection.class);
-    private final DatapathId dpid;
-    private final OFFactory factory;
-    private final Channel channel;
-    private final OFAuxId auxId;
-    private final Timer timer;
-
-    private final Date connectedSince;
-
-    private final Map<Long, Deliverable<?>> xidDeliverableMap;
-
-    protected final static ThreadLocal<List<OFMessage>> localMsgBuffer =
-            new ThreadLocal<List<OFMessage>>();
-
-    private static final long DELIVERABLE_TIME_OUT = 60;
-    private static final TimeUnit DELIVERABLE_TIME_OUT_UNIT = TimeUnit.SECONDS;
-
-    private final OFConnectionCounters counters;
-    private IOFConnectionListener listener;
-    
-    private volatile U64 latency;
-
-    public OFConnection(@Nonnull DatapathId dpid,
-                        @Nonnull OFFactory factory,
-                        @Nonnull Channel channel,
-                        @Nonnull OFAuxId auxId,
-                        @Nonnull IDebugCounterService debugCounters,
-                        @Nonnull Timer timer) {
-        Preconditions.checkNotNull(dpid, "dpid");
-        Preconditions.checkNotNull(factory, "factory");
-        Preconditions.checkNotNull(channel, "channel");
-        Preconditions.checkNotNull(timer, "timer");
-        Preconditions.checkNotNull(debugCounters);
-
-        this.listener = NullConnectionListener.INSTANCE;
-        this.dpid = dpid;
-        this.factory = factory;
-        this.channel = channel;
-        this.auxId = auxId;
-        this.connectedSince = new Date();
-        this.xidDeliverableMap = new ConcurrentHashMap<>();
-        this.counters = new OFConnectionCounters(debugCounters, dpid, this.auxId);
-        this.timer = timer;
-        this.latency = U64.ZERO;
-    }
-
-    @Override
-    public void write(OFMessage m) {
-        if (!isConnected()) {
-            if (logger.isDebugEnabled())
-                logger.debug("{}: not connected - dropping message {}", this, m);
-            return;
-        }
-        if (logger.isDebugEnabled())
-            logger.debug("{}: send {}", this, m);
-        List<OFMessage> msgBuffer = localMsgBuffer.get();
-        if (msgBuffer == null) {
-            msgBuffer = new ArrayList<OFMessage>();
-            localMsgBuffer.set(msgBuffer);
-        }
-
-        counters.updateWriteStats(m);
-        msgBuffer.add(m);
-
-        if ((msgBuffer.size() >= Controller.BATCH_MAX_SIZE) || ((m.getType() != OFType.PACKET_OUT) && (m.getType() != OFType.FLOW_MOD))) {
-            this.write(msgBuffer);
-            localMsgBuffer.set(null);
-        }
-    }
-
-    @Override
-    public <R extends OFMessage> ListenableFuture<R> writeRequest(OFRequest<R> request) {
-        if (!isConnected())
-            return Futures.immediateFailedFuture(new SwitchDisconnectedException(getDatapathId()));
-
-        DeliverableListenableFuture<R> future = new DeliverableListenableFuture<R>();
-        xidDeliverableMap.put(request.getXid(), future);
-        listener.messageWritten(this, request);
-        write(request);
-        return future;
-    }
-
-    @Override
-    public void write(Iterable<OFMessage> msglist) {
-        if (!isConnected()) {
-            if (logger.isDebugEnabled())
-                logger.debug(this.toString() + " : not connected - dropping {} element msglist {} ",
-                        Iterables.size(msglist),
-                        String.valueOf(msglist).substring(0, 80));
-            return;
-        }
-        for (OFMessage m : msglist) {
-            if (logger.isTraceEnabled())
-                logger.trace("{}: send {}", this, m);
-            counters.updateWriteStats(m);
-        }
-        this.channel.writeAndFlush(msglist);
-    }
-
-    // Notifies the connection object that the channel has been disconnected
-    public void disconnected() {
-        SwitchDisconnectedException exception = new SwitchDisconnectedException(getDatapathId());
-        for (Long xid : xidDeliverableMap.keySet()) {
-            // protect against other mechanisms running at the same time
-            // (timeout)
-            Deliverable<?> removed = xidDeliverableMap.remove(xid);
-            if (removed != null) {
-                removed.deliverError(exception);
-            }
-        }
-    }
-
-    @Override
-    public void disconnect() {
-        this.channel.disconnect();
-        this.counters.uninstallCounters();
-    }
-
-    @Override
-    public String toString() {
-        String channelString = (channel != null) ? String.valueOf(channel.remoteAddress()): "?";
-        return "OFConnection [" + getDatapathId() + "(" + getAuxId() + ")" + "@" + channelString + "]";
-    }
-
-    @Override
-    public Date getConnectedSince() {
-        return connectedSince;
-    }
-
-    @Override
-    public <REPLY extends OFStatsReply> ListenableFuture<List<REPLY>> writeStatsRequest(
-            OFStatsRequest<REPLY> request) {
-        if (!isConnected())
-            return Futures.immediateFailedFuture(new SwitchDisconnectedException(getDatapathId()));
-
-        final DeliverableListenableFuture<List<REPLY>> future =
-                new DeliverableListenableFuture<List<REPLY>>();
-
-        Deliverable<REPLY> deliverable = new Deliverable<REPLY>() {
-            private final List<REPLY> results = Collections
-                    .synchronizedList(new ArrayList<REPLY>());
-
-            @Override
-            public void deliver(REPLY reply) {
-                results.add(reply);
-                if (!reply.getFlags().contains(OFStatsReplyFlags.REPLY_MORE)) {
-                    // done
-                    future.deliver(results);
-                }
-            }
-
-            @Override
-            public void deliverError(Throwable cause) {
-                future.deliverError(cause);
-            }
-
-            @Override
-            public boolean isDone() {
-                return future.isDone();
-            }
-
-            @Override
-            public boolean cancel(boolean mayInterruptIfRunning) {
-                return future.cancel(mayInterruptIfRunning);
-            }
-        };
-
-        registerDeliverable(request.getXid(), deliverable);
-        this.write(request);
-        return future;
-    }
-
-    private void registerDeliverable(long xid, Deliverable<?> deliverable) {
-        this.xidDeliverableMap.put(xid, deliverable);
-        timer.newTimeout(new TimeOutDeliverable(xid), DELIVERABLE_TIME_OUT, DELIVERABLE_TIME_OUT_UNIT);
-    }
-
-    public boolean handleGenericDeliverable(OFMessage reply) {
-        counters.updateReadStats(reply);
-        @SuppressWarnings("unchecked")
-        Deliverable<OFMessage> deliverable =
-                (Deliverable<OFMessage>) this.xidDeliverableMap.get(reply.getXid());
-        if (deliverable != null) {
-            if(reply instanceof OFErrorMsg) {
-                deliverable.deliverError(new OFErrorMsgException((OFErrorMsg) reply));
-            } else {
-                deliverable.deliver(reply);
-            }
-            if (deliverable.isDone())
-                this.xidDeliverableMap.remove(reply.getXid());
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    @Override
-    public void cancelAllPendingRequests() {
-        /*
-         * we don't need to be synchronized here. Even if another thread
-         * modifies the map while we're cleaning up the future will eventually
-         * timeout
-         */
-        for (Deliverable<?> d : xidDeliverableMap.values()) {
-            d.cancel(true);
-        }
-        xidDeliverableMap.clear();
-    }
-
-    @Override
-    public boolean isConnected() {
-        return channel.isActive();
-    }
-
-    @Override
-    public void flush() {
-        List<OFMessage> msglist = localMsgBuffer.get();
-        if ((msglist != null) && (msglist.size() > 0)) {
-            this.write(msglist);
-            localMsgBuffer.set(null);
-        }
-    }
-
-    @Override
-    public SocketAddress getRemoteInetAddress() {
-        return channel.remoteAddress();
-    }
-
-    @Override
-    public SocketAddress getLocalInetAddress() {
-        return channel.localAddress();
-    }
-
-    public boolean deliverResponse(OFMessage m) {
-        if (handleGenericDeliverable(m))
-            return true;
-        else
-            return false;
-    }
-
-    @Override
-    public boolean isWritable() {
-        return channel.isWritable();
-    }
-
-    @Override
-    public DatapathId getDatapathId() {
-        return dpid;
-    }
-
-    @Override
-    public OFAuxId getAuxId() {
-        return auxId;
-    }
-
-    Set<Long> getPendingRequestIds() {
-        return ImmutableSet.copyOf(xidDeliverableMap.keySet());
-    }
-
-    @Override
-    public OFFactory getOFFactory() {
-        return this.factory;
-    }
-
-    /**
-     * Timeout class instantiated for deliverables. Will throw a timeout exception
-     * if proper responses are not received in time.
-     *
-     */
-    private class TimeOutDeliverable implements TimerTask {
-        private final long xid;
-
-        public TimeOutDeliverable(long xid) {
-            this.xid = xid;
-        }
-
-        @Override
-        public void run(Timeout timeout) throws Exception {
-            Deliverable<?> removed = xidDeliverableMap.remove(xid);
-            if (removed != null && !removed.isDone()) {
-                removed.deliverError(new TimeoutException(
-                        "timeout - did not receive answer for xid " + xid));
-            }
-
-        }
-    }
-
-    public IOFConnectionListener getListener() {
-        return listener;
-    }
-
-    /** set the connection listener
-     *  <p>
-     *  Note: this is assumed to be called from the Connection's IO Thread.
-     *
-     * @param listener
-     */
-    @Override
-    public void setListener(IOFConnectionListener listener) {
-        this.listener = listener;
-    }
-
-    public void messageReceived(OFMessage m) {
-        // Check if message was a response for a xid waiting at the switch
-        if(!deliverResponse(m)){
-            listener.messageReceived(this, m);
-        }
-    }
-    
-    @Override
-    public U64 getLatency() {
-    	return this.latency;
-    }
-    
-    @Override
-    public void updateLatency(U64 latency) {
-    	if (latency == null) {
+	private static final Logger logger = LoggerFactory.getLogger(OFConnection.class);
+	private final DatapathId dpid;
+	private final OFFactory factory;
+
+	/** CAREFUL CAREFUL CAREFUL:
+	 *
+	 * Netty4 does not guarantee order of messages that are written into the channel any more.
+	 * To ensure messages do not get reordered, never directly call {@link Channel#write(Object)}.
+	 *
+	 * Instead, use {@link #write(Iterable)}, which queue up write request on the EventLoop,
+	 * to make sure they are handled in order.
+	 */
+	private final Channel channel;
+
+	private final OFAuxId auxId;
+	private final Timer timer;
+
+	private final Date connectedSince;
+
+	private final Map<Long, Deliverable<?>> xidDeliverableMap;
+
+	private static final long DELIVERABLE_TIME_OUT = 60;
+	private static final TimeUnit DELIVERABLE_TIME_OUT_UNIT = TimeUnit.SECONDS;
+
+	private final OFConnectionCounters counters;
+	private IOFConnectionListener listener;
+
+	private volatile U64 latency;
+
+	/**
+	 * Used to write messages to ensure order w/Netty4.
+	 * It also ensures we do not reuse the array, since
+	 * Netty4 will write the object, not the items.
+	 */
+	private class WriteMessageTask implements Runnable {
+		private final Iterable<OFMessage> msglist;
+
+		public WriteMessageTask(Iterable<OFMessage> msglist) {
+			this.msglist = msglist;
+		}
+
+		@Override
+		public void run() {
+			for (OFMessage m : msglist) {
+				if (logger.isTraceEnabled())
+					logger.trace("{}: send {}", this, m);
+				counters.updateWriteStats(m);
+			}
+			channel.writeAndFlush(msglist);
+		}
+	}
+
+	public OFConnection(@Nonnull DatapathId dpid,
+			@Nonnull OFFactory factory,
+			@Nonnull Channel channel,
+			@Nonnull OFAuxId auxId,
+			@Nonnull IDebugCounterService debugCounters,
+			@Nonnull Timer timer) {
+		Preconditions.checkNotNull(dpid, "dpid");
+		Preconditions.checkNotNull(factory, "factory");
+		Preconditions.checkNotNull(channel, "channel");
+		Preconditions.checkNotNull(timer, "timer");
+		Preconditions.checkNotNull(debugCounters);
+
+		this.listener = NullConnectionListener.INSTANCE;
+		this.dpid = dpid;
+		this.factory = factory;
+		this.channel = channel;
+		this.auxId = auxId;
+		this.connectedSince = new Date();
+		this.xidDeliverableMap = new ConcurrentHashMap<>();
+		this.counters = new OFConnectionCounters(debugCounters, dpid, this.auxId);
+		this.timer = timer;
+		this.latency = U64.ZERO;
+	}
+
+	/**
+	 * All write methods chain into this write() to use WriteMessageTask.
+	 */
+	@Override
+	public void write(final Iterable<OFMessage> msgList) {
+		if (!isConnected()) {
+			if (logger.isDebugEnabled())
+				logger.debug(this.toString() + " : not connected - dropping {} element msglist {} ",
+						Iterables.size(msgList),
+						String.valueOf(msgList).substring(0, 80));
+			return;
+		}
+		for (OFMessage m : msgList) {
+			if (logger.isTraceEnabled())
+				logger.trace("{}: send {}", this, m);
+			counters.updateWriteStats(m);
+		}
+		this.channel.eventLoop().execute(new WriteMessageTask(msgList));
+	}
+
+	@Override
+	public void write(OFMessage m) {
+		this.write(Collections.singletonList(m));
+	}
+
+	@Override
+	public <R extends OFMessage> ListenableFuture<R> writeRequest(OFRequest<R> request) {
+		if (!isConnected()) {
+			return Futures.immediateFailedFuture(new SwitchDisconnectedException(getDatapathId()));
+		}
+
+		DeliverableListenableFuture<R> future = new DeliverableListenableFuture<R>();
+		xidDeliverableMap.put(request.getXid(), future);
+		listener.messageWritten(this, request);
+		this.write(request);
+		return future;
+	}
+
+	@Override
+	public <REPLY extends OFStatsReply> ListenableFuture<List<REPLY>> writeStatsRequest(
+			OFStatsRequest<REPLY> request) {
+		if (!isConnected()) {
+			return Futures.immediateFailedFuture(new SwitchDisconnectedException(getDatapathId()));
+		}
+
+		final DeliverableListenableFuture<List<REPLY>> future =
+				new DeliverableListenableFuture<List<REPLY>>();
+
+		Deliverable<REPLY> deliverable = new Deliverable<REPLY>() {
+			private final List<REPLY> results = Collections
+					.synchronizedList(new ArrayList<REPLY>());
+
+			@Override
+			public void deliver(REPLY reply) {
+				results.add(reply);
+				if (!reply.getFlags().contains(OFStatsReplyFlags.REPLY_MORE)) {
+					// done
+					future.deliver(results);
+				}
+			}
+
+			@Override
+			public void deliverError(Throwable cause) {
+				future.deliverError(cause);
+			}
+
+			@Override
+			public boolean isDone() {
+				return future.isDone();
+			}
+
+			@Override
+			public boolean cancel(boolean mayInterruptIfRunning) {
+				return future.cancel(mayInterruptIfRunning);
+			}
+		};
+
+		registerDeliverable(request.getXid(), deliverable);
+		this.write(request);
+		return future;
+	}
+
+	public void disconnected() {
+		SwitchDisconnectedException exception = new SwitchDisconnectedException(getDatapathId());
+		for (Long xid : xidDeliverableMap.keySet()) {
+			// protect against other mechanisms running at the same time
+			// (timeout)
+			Deliverable<?> removed = xidDeliverableMap.remove(xid);
+			if (removed != null) {
+				removed.deliverError(exception);
+			}
+		}
+	}
+
+	@Override
+	public void disconnect() {
+		this.channel.disconnect();
+		this.counters.uninstallCounters();
+	}
+
+	@Override
+	public String toString() {
+		String channelString = (channel != null) ? String.valueOf(channel.remoteAddress()): "?";
+		return "OFConnection [" + getDatapathId() + "(" + getAuxId() + ")" + "@" + channelString + "]";
+	}
+
+	@Override
+	public Date getConnectedSince() {
+		return connectedSince;
+	}
+
+	private void registerDeliverable(long xid, Deliverable<?> deliverable) {
+		this.xidDeliverableMap.put(xid, deliverable);
+		timer.newTimeout(new TimeOutDeliverable(xid), DELIVERABLE_TIME_OUT, DELIVERABLE_TIME_OUT_UNIT);
+	}
+
+	public boolean handleGenericDeliverable(OFMessage reply) {
+		counters.updateReadStats(reply);
+		@SuppressWarnings("unchecked")
+		Deliverable<OFMessage> deliverable =
+		(Deliverable<OFMessage>) this.xidDeliverableMap.get(reply.getXid());
+		if (deliverable != null) {
+			if(reply instanceof OFErrorMsg) {
+				deliverable.deliverError(new OFErrorMsgException((OFErrorMsg) reply));
+			} else {
+				deliverable.deliver(reply);
+			}
+			if (deliverable.isDone())
+				this.xidDeliverableMap.remove(reply.getXid());
+			return true;
+		} else {
+			return false;
+		}
+	}
+
+	@Override
+	public void cancelAllPendingRequests() {
+		/*
+		 * we don't need to be synchronized here. Even if another thread
+		 * modifies the map while we're cleaning up the future will eventually
+		 * timeout
+		 */
+		for (Deliverable<?> d : xidDeliverableMap.values()) {
+			d.cancel(true);
+		}
+		xidDeliverableMap.clear();
+	}
+
+	@Override
+	public boolean isConnected() {
+		return channel.isActive();
+	}
+
+	@Override
+	public SocketAddress getRemoteInetAddress() {
+		return channel.remoteAddress();
+	}
+
+	@Override
+	public SocketAddress getLocalInetAddress() {
+		return channel.localAddress();
+	}
+
+	public boolean deliverResponse(OFMessage m) {
+		if (handleGenericDeliverable(m))
+			return true;
+		else
+			return false;
+	}
+
+	@Override
+	public boolean isWritable() {
+		return channel.isWritable();
+	}
+
+	@Override
+	public DatapathId getDatapathId() {
+		return dpid;
+	}
+
+	@Override
+	public OFAuxId getAuxId() {
+		return auxId;
+	}
+
+	Set<Long> getPendingRequestIds() {
+		return ImmutableSet.copyOf(xidDeliverableMap.keySet());
+	}
+
+	@Override
+	public OFFactory getOFFactory() {
+		return this.factory;
+	}
+
+	/**
+	 * Timeout class instantiated for deliverables. Will throw a timeout exception
+	 * if proper responses are not received in time.
+	 *
+	 */
+	private class TimeOutDeliverable implements TimerTask {
+		private final long xid;
+
+		public TimeOutDeliverable(long xid) {
+			this.xid = xid;
+		}
+
+		@Override
+		public void run(Timeout timeout) throws Exception {
+			Deliverable<?> removed = xidDeliverableMap.remove(xid);
+			if (removed != null && !removed.isDone()) {
+				removed.deliverError(new TimeoutException(
+						"timeout - did not receive answer for xid " + xid));
+			}
+
+		}
+	}
+
+	public IOFConnectionListener getListener() {
+		return listener;
+	}
+
+	/** set the connection listener
+	 *  <p>
+	 *  Note: this is assumed to be called from the Connection's IO Thread.
+	 *
+	 * @param listener
+	 */
+	@Override
+	public void setListener(IOFConnectionListener listener) {
+		this.listener = listener;
+	}
+
+	public void messageReceived(OFMessage m) {
+		// Check if message was a response for a xid waiting at the switch
+		if(!deliverResponse(m)){
+			listener.messageReceived(this, m);
+		}
+	}
+
+	@Override
+	public U64 getLatency() {
+		return this.latency;
+	}
+
+	@Override
+	public void updateLatency(U64 latency) {
+		if (latency == null) {
 			logger.error("Latency must be non-null. Ignoring null latency value.");
 			return;
 		} else if (this.latency.equals(U64.ZERO)) { 
@@ -399,35 +404,35 @@ public class OFConnection implements IOFConnection, IOFConnectionBackend{
 			this.latency = U64.of((long) (this.latency.getValue() * oldWeight + latency.getValue() * (1 - oldWeight)));
 			logger.debug("Switch {} latency updated to {}ms", this.getDatapathId(), this.latency.getValue());
 		}
-    }
+	}
 
-    /** A dummy connection listener that just logs warn messages. Saves us a few null checks
-     * @author Andreas Wundsam <andreas.wundsam@bigswitch.com>
-     */
-    private static class NullConnectionListener implements IOFConnectionListener {
-        public final static NullConnectionListener INSTANCE = new NullConnectionListener();
+	/** A dummy connection listener that just logs warn messages. Saves us a few null checks
+	 * @author Andreas Wundsam <andreas.wundsam@bigswitch.com>
+	 */
+	private static class NullConnectionListener implements IOFConnectionListener {
+		public final static NullConnectionListener INSTANCE = new NullConnectionListener();
 
-        private NullConnectionListener() { }
+		private NullConnectionListener() { }
 
-        @Override
-        public void connectionClosed(IOFConnectionBackend connection) {
-            logger.warn("NullConnectionListener for {} - received connectionClosed", connection);
-        }
+		@Override
+		public void connectionClosed(IOFConnectionBackend connection) {
+			logger.warn("NullConnectionListener for {} - received connectionClosed", connection);
+		}
 
-        @Override
-        public void messageReceived(IOFConnectionBackend connection, OFMessage m) {
-            logger.warn("NullConnectionListener for {} - received messageReceived: {}", connection, m);
-        }
+		@Override
+		public void messageReceived(IOFConnectionBackend connection, OFMessage m) {
+			logger.warn("NullConnectionListener for {} - received messageReceived: {}", connection, m);
+		}
 
-        @Override
-        public boolean isSwitchHandshakeComplete(IOFConnectionBackend connection) {
-            return false;
-        }
+		@Override
+		public boolean isSwitchHandshakeComplete(IOFConnectionBackend connection) {
+			return false;
+		}
 
 		@Override
 		public void messageWritten(IOFConnectionBackend connection, OFMessage m) {
 			// TODO Auto-generated method stub
-			
+
 		}
-    }
+	}
 }
\ No newline at end of file
diff --git a/src/main/java/net/floodlightcontroller/core/internal/OFSwitch.java b/src/main/java/net/floodlightcontroller/core/internal/OFSwitch.java
index 1c95a2bfe2ff9e84fde91d75daa025d826b095e8..d9f6ea24bce4032c41f4624eaf81adc841ed50e6 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/OFSwitch.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/OFSwitch.java
@@ -39,7 +39,6 @@ import javax.annotation.Nonnull;
 
 import net.floodlightcontroller.core.IOFConnection;
 import net.floodlightcontroller.core.IOFConnectionBackend;
-import net.floodlightcontroller.core.IOFSwitch;
 import net.floodlightcontroller.core.IOFSwitchBackend;
 import net.floodlightcontroller.core.LogicalOFMessageCategory;
 import net.floodlightcontroller.core.PortChangeEvent;
@@ -48,7 +47,6 @@ import net.floodlightcontroller.core.SwitchDescription;
 import net.floodlightcontroller.core.SwitchDriverSubHandshakeAlreadyStarted;
 import net.floodlightcontroller.core.SwitchDriverSubHandshakeCompleted;
 import net.floodlightcontroller.core.SwitchDriverSubHandshakeNotStarted;
-import net.floodlightcontroller.core.IOFSwitch.SwitchStatus;
 import net.floodlightcontroller.core.util.AppCookie;
 import net.floodlightcontroller.core.util.URIUtil;
 
@@ -730,17 +728,6 @@ public class OFSwitch implements IOFSwitchBackend {
 		this.connections.remove(connection.getAuxId());
 	}
 
-	@Override
-	public void write(OFMessage m) {
-		log.trace("Channel: {}, Connected: {}", connections.get(OFAuxId.MAIN).getRemoteInetAddress(), connections.get(OFAuxId.MAIN).isConnected());
-		if (isActive()) {
-			connections.get(OFAuxId.MAIN).write(m);
-			switchManager.handleOutgoingMessage(this, m);
-		} else {
-			log.warn("Attempted to write to switch {} that is SLAVE.", this.getId().toString());
-		}
-	}
-
 	/**
 	 * Gets a connection specified by aux Id.
 	 * @param auxId the specified aux id for the connection desired.
@@ -764,21 +751,32 @@ public class OFSwitch implements IOFSwitchBackend {
 	}
 
 	@Override
-	public void write(OFMessage m, LogicalOFMessageCategory category) {
+	public void write(OFMessage m) {
+		this.write(Collections.singletonList(m));
+	}
+	
+	@Override
+	public void write(Iterable<OFMessage> msglist) {
 		if (isActive()) {
-			this.getConnection(category).write(m);
-			switchManager.handleOutgoingMessage(this, m);
+			connections.get(OFAuxId.MAIN).write(msglist);
+			for (OFMessage m : msglist) {
+				switchManager.handleOutgoingMessage(this, m);
+			}
 		} else {
 			log.warn("Attempted to write to switch {} that is SLAVE.", this.getId().toString());
 		}
 	}
+	
+	@Override
+	public void write(OFMessage m, LogicalOFMessageCategory category) {
+		this.write(Collections.singletonList(m), category);
+	}
 
 	@Override
 	public void write(Iterable<OFMessage> msglist, LogicalOFMessageCategory category) {
 		if (isActive()) {
 			this.getConnection(category).write(msglist);
-
-			for(OFMessage m : msglist) {
+			for (OFMessage m : msglist) {
 				switchManager.handleOutgoingMessage(this, m);				
 			}
 		} else {
@@ -801,24 +799,10 @@ public class OFSwitch implements IOFSwitchBackend {
 		return connections.get(OFAuxId.MAIN).writeRequest(request);
 	}
 
-	@Override
-	public void write(Iterable<OFMessage> msglist) {
-		if (isActive()) {
-			connections.get(OFAuxId.MAIN).write(msglist);
-
-			for(OFMessage m : msglist) {
-				switchManager.handleOutgoingMessage(this, m);
-			}
-		} else {
-			log.warn("Attempted to write to switch {} that is SLAVE.", this.getId().toString());
-		}
-	}
-
 	@Override
 	public void disconnect() {
-
 		// Iterate through connections and perform cleanup
-		for(Entry<OFAuxId, IOFConnectionBackend> entry : this.connections.entrySet()){
+		for (Entry<OFAuxId, IOFConnectionBackend> entry : this.connections.entrySet()) {
 			entry.getValue().disconnect();
 			this.connections.remove(entry.getKey());
 		}
@@ -953,12 +937,9 @@ public class OFSwitch implements IOFSwitchBackend {
 		return datapathId;
 	}
 
-	/* (non-Javadoc)
-	 * @see java.lang.Object#toString()
-	 */
 	@Override
 	public String toString() {
-		return "OFSwitchBase DPID[" + ((datapathId != null) ? datapathId.toString() : "?") + "]";
+		return "OFSwitch DPID[" + ((datapathId != null) ? datapathId.toString() : "?") + "]";
 	}
 
 	@Override
@@ -1067,13 +1048,6 @@ public class OFSwitch implements IOFSwitchBackend {
 		this.role = role;
 	}
 
-	@Override
-	public void flush() {
-		for(Entry<OFAuxId, IOFConnectionBackend> entry : this.connections.entrySet()){
-			entry.getValue().flush();
-		}
-	}
-
 	/**
 	 * Get the IP Address for the switch
 	 * @return the inet address
diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java
index a26d8d8fd4a6c39539b2c92c347d0848a3d6ecdd..c50930ed6580cb5cf7a499d83b912522fd2c2821 100644
--- a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java
+++ b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java
@@ -1219,7 +1219,6 @@ IFloodlightModule, IInfoProvider {
 		// send
 		// no more try-catch. switch will silently fail
 		iofSwitch.write(pob.build());
-		iofSwitch.flush();
 	}
 
 	/**
diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java
index d4e95df918bb5792906e633c6bf5cab14c9e3780..7875e70267b68508c23d65ad099c50bb66282829 100644
--- a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java
+++ b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java
@@ -610,7 +610,6 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService,
 				log.debug("Sending {} new entries to {}", messages.size(), dpid);
 			}
 			ofswitch.write(messages);
-			ofswitch.flush();
 		}
 	}
 
@@ -626,7 +625,6 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService,
 				log.debug("Sending 1 new entries to {}", dpid.toString());
 			}
 			ofswitch.write(message);
-			ofswitch.flush();
 		}
 	}
 
@@ -654,7 +652,6 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService,
 	 */
 	private void writeFlowModToSwitch(IOFSwitch sw, OFFlowMod flowMod) {
 		sw.write(flowMod);
-		sw.flush();
 	}
 	@Override
 	public String getName() {
diff --git a/src/main/java/net/floodlightcontroller/util/OFMessageDamper.java b/src/main/java/net/floodlightcontroller/util/OFMessageDamper.java
index 296adc157236de7dac02f5f15d544abc66228450..3e1b86f59362d077e513705b76da1c235f956b7b 100644
--- a/src/main/java/net/floodlightcontroller/util/OFMessageDamper.java
+++ b/src/main/java/net/floodlightcontroller/util/OFMessageDamper.java
@@ -114,24 +114,8 @@ public class OFMessageDamper {
      * @throws IOException
      */
     public boolean write(IOFSwitch sw, OFMessage msg) throws IOException {
-        return write(sw, msg, false);
-    }
-    
-    /**
-     * write the message to the switch according to our dampening settings
-     * @param sw
-     * @param msg
-     * @param flush true to flush the packet immediately
-     * @return true if the message was written to the switch, false if
-     * the message was dampened. 
-     * @throws IOException
-     */
-    public boolean write(IOFSwitch sw, OFMessage msg, boolean flush) throws IOException {
         if (!msgTypesToCache.contains(msg.getType())) {
             sw.write(msg);
-            if (flush) {
-                sw.flush();
-            }
             return true;
         }
         
@@ -141,9 +125,6 @@ public class OFMessageDamper {
             return false; 
         } else {
             sw.write(msg);
-            if (flush) {
-                sw.flush();
-            }
             return true;
         }
     }
diff --git a/src/main/resources/floodlightdefault.properties b/src/main/resources/floodlightdefault.properties
index fe32a37ed46be47de5f6405754885835eff6e6e1..89bf32381355331dd93a011d0e59d2a2581d4d5d 100644
--- a/src/main/resources/floodlightdefault.properties
+++ b/src/main/resources/floodlightdefault.properties
@@ -23,11 +23,11 @@ org.sdnplatform.sync.internal.SyncManager.dbPath=/var/lib/floodlight/
 org.sdnplatform.sync.internal.SyncManager.port=6642
 net.floodlightcontroller.forwarding.Forwarding.match=vlan, mac, ip, transport
 net.floodlightcontroller.forwarding.Forwarding.flood-arp=NO
-net.floodlightcontroller.core.internal.FloodlightProvider.openflowPort=6653
+net.floodlightcontroller.core.internal.FloodlightProvider.openFlowPort=6653
 net.floodlightcontroller.core.internal.FloodlightProvider.role=ACTIVE
 net.floodlightcontroller.linkdiscovery.internal.LinkDiscoveryManager.latency-history-size=10
 net.floodlightcontroller.linkdiscovery.internal.LinkDiscoveryManager.latency-update-threshold=0.5
-net.floodlightcontroller.core.internal.OFSwitchManager.defaultMaxTablesToReceiveTableMissFlow=2
+net.floodlightcontroller.core.internal.OFSwitchManager.defaultMaxTablesToReceiveTableMissFlow=1
 net.floodlightcontroller.core.internal.OFSwitchManager.maxTablesToReceiveTableMissFlowPerDpid={"00:00:00:00:00:00:00:01":"1","2":"1"}
 net.floodlightcontroller.core.internal.OFSwitchManager.clearTablesOnInitialHandshakeAsMaster=YES
 net.floodlightcontroller.core.internal.OFSwitchManager.clearTablesOnEachTransitionToMaster=YES
diff --git a/src/main/resources/logback-test.xml b/src/main/resources/logback-test.xml
index b5e3bfd8093df991c049e5f86e873a9834d12747..8fa1e8f86065f20fa51ea0b42336af21b4e15cdc 100644
--- a/src/main/resources/logback-test.xml
+++ b/src/main/resources/logback-test.xml
@@ -11,6 +11,7 @@
     <appender-ref ref="EV_WARN_ERR" />
   </root>
   <logger name="org" level="WARN"/>
+  <logger name="io" level="INFO"></logger> <!-- Netty logging -->
   <logger name="LogService" level="DEBUG"></logger> <!-- Restlet access logging -->
   <logger name="net.floodlightcontroller" level="INFO"/>
   <logger name="org.sdnplatform" level="INFO"></logger>
diff --git a/src/test/java/net/floodlightcontroller/core/internal/MockOFConnection.java b/src/test/java/net/floodlightcontroller/core/internal/MockOFConnection.java
index c1eab8ba8baedd748aaddeb089504befb4cad6a0..597ab8523b4ce1874d12495d3b4c8c61b5e4c035 100644
--- a/src/test/java/net/floodlightcontroller/core/internal/MockOFConnection.java
+++ b/src/test/java/net/floodlightcontroller/core/internal/MockOFConnection.java
@@ -124,11 +124,6 @@ public class MockOFConnection implements IOFConnectionBackend {
         return this.connectedSince;
     }
 
-    @Override
-    public void flush() {
-        // no op
-    }
-
     @Override
     public DatapathId getDatapathId() {
         return this.id;
diff --git a/src/test/java/net/floodlightcontroller/core/internal/OFChannelHandlerVer10Test.java b/src/test/java/net/floodlightcontroller/core/internal/OFChannelHandlerVer10Test.java
index 2460b3a7687c93ba64c32af6779ea7517847e031..39ec2714e9aa9170a2f115f46cef7533e6593af8 100644
--- a/src/test/java/net/floodlightcontroller/core/internal/OFChannelHandlerVer10Test.java
+++ b/src/test/java/net/floodlightcontroller/core/internal/OFChannelHandlerVer10Test.java
@@ -23,11 +23,14 @@ import java.util.Set;
 import org.easymock.Capture;
 import org.easymock.CaptureType;
 import org.easymock.EasyMock;
+import org.easymock.IAnswer;
 import org.hamcrest.CoreMatchers;
 
 import io.netty.channel.Channel;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.ChannelPipeline;
+import io.netty.channel.ChannelPromise;
+import io.netty.channel.DefaultChannelPromise;
 import io.netty.util.HashedWheelTimer;
 import io.netty.util.Timer;
 
@@ -38,6 +41,7 @@ import org.junit.Test;
 import net.floodlightcontroller.core.IOFConnectionBackend;
 import net.floodlightcontroller.core.internal.OFChannelInitializer.PipelineHandler;
 import net.floodlightcontroller.core.internal.OFChannelInitializer.PipelineHandshakeTimeout;
+import net.floodlightcontroller.core.test.TestEventLoop;
 import net.floodlightcontroller.debugcounter.DebugCounterServiceImpl;
 import net.floodlightcontroller.debugcounter.IDebugCounterService;
 
@@ -90,6 +94,8 @@ public class OFChannelHandlerVer10Test {
     private INewOFConnectionListener newConnectionListener;
     private Capture<IOFConnectionBackend> newConnection;
     private Capture<OFFeaturesReply> newFeaturesReply;
+    
+    private TestEventLoop eventLoop;
 
     public void setUpFeaturesReply() {
        portDesc = factory.buildPortDesc()
@@ -115,6 +121,7 @@ public class OFChannelHandlerVer10Test {
         newConnectionListener = createMock(INewOFConnectionListener.class);
         newConnection = new Capture<IOFConnectionBackend>();
         newFeaturesReply = new Capture<OFFeaturesReply>();
+        eventLoop = new TestEventLoop();
 
         ctx = createMock(ChannelHandlerContext.class);
         channel = createMock(Channel.class);
@@ -176,6 +183,14 @@ public class OFChannelHandlerVer10Test {
     /** Reset the channel mock and set basic method call expectations */
     void resetChannel() {
         reset(channel);
+        expect(channel.newPromise()).andAnswer(new IAnswer<ChannelPromise>() {
+			@Override
+			public ChannelPromise answer() throws Throwable {
+				return new DefaultChannelPromise(channel);
+			}
+		}).anyTimes();
+		eventLoop = new TestEventLoop();
+		expect(channel.eventLoop()).andReturn(eventLoop).anyTimes();
         expect(channel.pipeline()).andReturn(pipeline).anyTimes();
         expect(channel.remoteAddress()).andReturn(InetSocketAddress.createUnresolved("1.1.1.1", 80)).anyTimes();
     }
diff --git a/src/test/java/net/floodlightcontroller/core/internal/OFChannelHandlerVer13Test.java b/src/test/java/net/floodlightcontroller/core/internal/OFChannelHandlerVer13Test.java
index 6764bdef866c9d61dd65628e8ca0eb9413cfc9a7..643bc416ba1df288845efe8ce1debb161e96c13e 100644
--- a/src/test/java/net/floodlightcontroller/core/internal/OFChannelHandlerVer13Test.java
+++ b/src/test/java/net/floodlightcontroller/core/internal/OFChannelHandlerVer13Test.java
@@ -23,11 +23,14 @@ import java.util.Set;
 import org.easymock.Capture;
 import org.easymock.CaptureType;
 import org.easymock.EasyMock;
+import org.easymock.IAnswer;
 import org.hamcrest.CoreMatchers;
 
 import io.netty.channel.Channel;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.ChannelPipeline;
+import io.netty.channel.ChannelPromise;
+import io.netty.channel.DefaultChannelPromise;
 import io.netty.util.HashedWheelTimer;
 import io.netty.util.Timer;
 
@@ -38,6 +41,7 @@ import org.junit.Test;
 import net.floodlightcontroller.core.IOFConnectionBackend;
 import net.floodlightcontroller.core.internal.OFChannelInitializer.PipelineHandler;
 import net.floodlightcontroller.core.internal.OFChannelInitializer.PipelineHandshakeTimeout;
+import net.floodlightcontroller.core.test.TestEventLoop;
 import net.floodlightcontroller.debugcounter.DebugCounterServiceImpl;
 import net.floodlightcontroller.debugcounter.IDebugCounterService;
 
@@ -71,379 +75,391 @@ import com.google.common.collect.ImmutableList;
 
 
 public class OFChannelHandlerVer13Test {
-    private static final DatapathId dpid = DatapathId.of(0x42L);
-
-    private IOFSwitchManager switchManager;
-    private IOFConnectionListener connectionListener;
-    private INewOFConnectionListener newConnectionListener;
-    private IDebugCounterService debugCounterService;
-    private OFChannelHandler handler;
-    private Channel channel;
-    private Timer timer;
-    private ChannelHandlerContext ctx;
-    private ChannelPipeline pipeline;
-    private final OFFactory factory = OFFactories.getFactory(OFVersion.OF_13);
-
-    private Capture<Throwable> exceptionEventCapture;
-    private Capture<List<OFMessage>> writeCapture;
-
-    private OFFeaturesReply featuresReply;
-    private OFPortDesc portDesc;
-
-    private Set<Long> seenXids = null;
-
-    private Capture<IOFConnectionBackend> newConnection;
-
-    private Capture<OFFeaturesReply> newFeaturesReply;
-
-    public void setUpFeaturesReply() {
-        portDesc = factory.buildPortDesc()
-                .setName("Eth1")
-                .setPortNo(OFPort.of(1))
-                .build();
-        featuresReply = factory.buildFeaturesReply()
-                .setDatapathId(dpid)
-                .setNBuffers(1)
-                .setNTables((short)1)
-                .setCapabilities(EnumSet.<OFCapabilities>of(OFCapabilities.FLOW_STATS, OFCapabilities.TABLE_STATS))
-                .setAuxiliaryId(OFAuxId.MAIN)
-                .build();
-    }
-
-    @Before
-    public void setUp() throws Exception {
-    	setUpFeaturesReply();
-        switchManager = createMock(IOFSwitchManager.class);
-        connectionListener = createMock(IOFConnectionListener.class);
-        newConnectionListener = createMock(INewOFConnectionListener.class);
-        newConnection = new Capture<IOFConnectionBackend>();
-        newFeaturesReply = new Capture<OFFeaturesReply>();
-
-        ctx = createMock(ChannelHandlerContext.class);
-        channel = createMock(Channel.class);
-        timer = new HashedWheelTimer();
-        exceptionEventCapture = new Capture<Throwable>(CaptureType.ALL);
-        pipeline = createMock(ChannelPipeline.class);
-        writeCapture = new Capture<List<OFMessage>>(CaptureType.ALL);
-        seenXids = null;
-
-
-        // TODO: should mock IDebugCounterService and make sure
-        // the expected counters are updated.
-        debugCounterService = new DebugCounterServiceImpl();
-        debugCounterService.registerModule(OFConnectionCounters.COUNTER_MODULE);
-        SwitchManagerCounters counters =
-                new SwitchManagerCounters(debugCounterService);
-        expect(switchManager.getCounters()).andReturn(counters).anyTimes();
-        replay(switchManager);
-        handler = new OFChannelHandler(switchManager, newConnectionListener,
-                                       pipeline, debugCounterService, /* 62 is OF versions 1.0 thru 1.4 in decimal */
-                                       timer, Collections.singletonList(U32.of(62)), OFFactories.getFactory(OFVersion.OF_14));
-
-        verify(switchManager);
-        reset(switchManager);
-
-        resetChannel();
-
-        // replay controller. Reset it if you need more specific behavior
-        replay(switchManager);
-
-        // Mock ctx and channelStateEvent
-        expect(ctx.channel()).andReturn(channel).anyTimes();
-        expect(ctx.fireExceptionCaught(capture(exceptionEventCapture))).andReturn(ctx).anyTimes();
-        replay(ctx);
-
-        /* Setup an exception event capture on the channel. Right now
-         * we only expect exception events to be send up the channel.
-         * However, it's easy to extend to other events if we need it
-         */
-        expect(pipeline.get(OFMessageDecoder.class)).andReturn(new OFMessageDecoder()).anyTimes();
-        replay(pipeline);
-    }
-
-    @After
-    public void tearDown() {
-        /* ensure no exception was thrown */
-        if (exceptionEventCapture.hasCaptured()) {
-            Throwable ex = exceptionEventCapture.getValue();
-            ex.printStackTrace();
-            Throwables.propagate(ex);
-        }
-        assertFalse("Unexpected messages have been captured",
-                    writeCapture.hasCaptured());
-        // verify all mocks.
-        verify(channel);
-        verify(switchManager);
-        verify(ctx);
-        verify(pipeline);
-    }
-
-    /** Reset the channel mock and set basic method call expectations */
-    void resetChannel() {
-        reset(channel);
-        expect(channel.pipeline()).andReturn(pipeline).anyTimes();
-        expect(channel.remoteAddress()).andReturn(null).anyTimes();
-    }
-
-    /** reset, setup, and replay the messageEvent mock for the given
-     * messages, mock controller  send message to channel handler
-     *
-     * This method will reset, start replay on controller, and then verify
-     */
-    void sendMessageToHandlerWithControllerReset(List<OFMessage> messages)
-            throws Exception {
-        sendMessageToHandlerNoControllerReset(messages);
-    }
-
-    /** reset, setup, and replay the messageEvent mock for the given
-     * messages, mock controller  send message to channel handler
-     *
-     * This method will start replay on controller, and then verify
-     */
-    void sendMessageToHandlerNoControllerReset(List<OFMessage> messages)
-            throws Exception {
-        handler.channelRead(ctx, messages);
-    }
-
-    /**
-     * Extract the list of OFMessages that was captured by the Channel.write()
-     * capture. Will check that something was actually captured first. We'll
-     * collapse the messages from multiple writes into a single list of
-     * OFMessages.
-     * Resets the channelWriteCapture.
-     */
-    List<OFMessage> getMessagesFromCapture() {
-        List<OFMessage> msgs = new ArrayList<OFMessage>();
-
-        assertTrue("No write on channel was captured",
-                   writeCapture.hasCaptured());
-        List<List<OFMessage>> capturedVals = writeCapture.getValues();
-
-        for (List<OFMessage> oneWriteList: capturedVals)
-            msgs.addAll(oneWriteList);
-        writeCapture.reset();
-        return msgs;
-    }
-
-
-    /**
-     * Verify that the given exception event capture (as returned by
-     * getAndInitExceptionCapture) has thrown an exception of the given
-     * expectedExceptionClass.
-     * Resets the capture
-     */
-    void verifyExceptionCaptured(Class<? extends Throwable> expectedExceptionClass) {
-        assertTrue("Excpected exception not thrown", exceptionEventCapture.hasCaptured());
-        Throwable caughtEx = exceptionEventCapture.getValue();
-        assertEquals(expectedExceptionClass, caughtEx.getClass());
-        exceptionEventCapture.reset();
-    }
-
-    /** make sure that the transaction ids in the given messages are
-     * not 0 and differ between each other.
-     * While it's not a defect per se if the xids are we want to ensure
-     * we use different ones for each message we send.
-     */
-    void verifyUniqueXids(List<OFMessage> msgs) {
-        if (seenXids == null)
-            seenXids = new HashSet<Long>();
-        for (OFMessage m: msgs)  {
-            long xid = m.getXid();
-            assertTrue("Xid in messags is 0", xid != 0);
-            assertFalse("Xid " + xid + " has already been used",
-                        seenXids.contains(xid));
-            seenXids.add(xid);
-        }
-    }
-
-    @Test
-    public void testNullMsg() throws Exception {
-    	reset(ctx);
-    	expect(ctx.fireChannelRead(null)).andReturn(ctx).once();
-    	replay(ctx, channel);
-    	
-    	// null message is not passed to the handler
-    	handler.channelRead(ctx, null);
-    	verify(channel, ctx);
-    }
-
-    @Test
-    public void testInitState() throws Exception {
-        replay(channel);
-
-        // We don't expect to receive /any/ messages in init state since
-        // channelConnected moves us to a different state
-        OFMessage m = factory.buildHello().build();
-        sendMessageToHandlerWithControllerReset(ImmutableList.<OFMessage>of(m));
-
-        verifyExceptionCaptured(SwitchStateException.class);
-        assertThat(handler.getStateForTesting(), CoreMatchers.instanceOf(OFChannelHandler.InitState.class));
-    }
-
-    /* Move the channel from scratch to WAIT_HELLO state */
-    @Test
-    public void moveToWaitHello() throws Exception {
-        resetChannel();
-        expect(channel.writeAndFlush(capture(writeCapture))).andReturn(null).once();
-        replay(channel);
-
-        handler.channelActive(ctx);
-
-        List<OFMessage> msgs = getMessagesFromCapture();
-        assertEquals(1, msgs.size());
-        assertEquals(OFType.HELLO, msgs.get(0).getType());
-        assertThat(handler.getStateForTesting(), CoreMatchers.instanceOf(OFChannelHandler.WaitHelloState.class));
-        verifyUniqueXids(msgs);
-    }
-
-    /** Move the channel from scratch to WAIT_FEATURES_REPLY state
-     * Builds on moveToWaitHello()
-     * adds testing for WAIT_HELLO state
-     */
-    @Test
-    public void moveToWaitFeaturesReply() throws Exception {
-        moveToWaitHello();
-        resetChannel();
-        expect(channel.writeAndFlush(capture(writeCapture))).andReturn(null).once();
-        replay(channel);
-
-        OFMessage hello = factory.buildHello().build();
-        sendMessageToHandlerWithControllerReset(ImmutableList.<OFMessage>of(hello));
-
-        List<OFMessage> msgs = getMessagesFromCapture();
-        assertEquals(1, msgs.size());
-        assertEquals(OFType.FEATURES_REQUEST, msgs.get(0).getType());
-        verifyUniqueXids(msgs);
-
-        assertThat(handler.getStateForTesting(), CoreMatchers.instanceOf(OFChannelHandler.WaitFeaturesReplyState.class));
-    }
-
-
-    /** Move the channel from scratch to WAIT_FEATURES_REPLY state
-     * Builds on moveToWaitHello()
-     * adds testing for WAIT_HELLO state
-     */
-    @Test
-    public void moveToComplete() throws Exception {
-        moveToWaitFeaturesReply();
-
-        reset(pipeline);
-        HandshakeTimeoutHandler newHandler = new HandshakeTimeoutHandler(
-                                                                         handler,
-                                                                         timer,
-                                                                         PipelineHandshakeTimeout.SWITCH);
-
-        expect(
-               pipeline.replace(EasyMock.eq(PipelineHandler.CHANNEL_HANDSHAKE_TIMEOUT),
-                                EasyMock.eq(PipelineHandler.SWITCH_HANDSHAKE_TIMEOUT),
-                                EasyMock.anyObject(HandshakeTimeoutHandler.class))).andReturn(newHandler)
-                                                                          .once();
-
-        replay(pipeline);
-
-        newConnectionListener.connectionOpened(capture(newConnection), capture(newFeaturesReply));
-        expectLastCall().once();
-        replay(newConnectionListener);
-
-        sendMessageToHandlerWithControllerReset(Collections.<OFMessage>singletonList(featuresReply));
-
-        assertThat(handler.getStateForTesting(), CoreMatchers.instanceOf(OFChannelHandler.CompleteState.class));
-        assertTrue("A connection has been created and set", handler.getConnectionForTesting() != null);
-        verify(newConnectionListener);
-        assertTrue(newConnection.hasCaptured());
-        assertThat(newFeaturesReply.getValue(), equalTo(featuresReply));
-    }
-
-    /**
-     * Test dispatch of messages while in Complete state
-     */
-    @Test
-    public void testMessageDispatchComplete() throws Exception {
-        moveToComplete();
-        newConnection.getValue().setListener(connectionListener);
+	private static final DatapathId dpid = DatapathId.of(0x42L);
+
+	private IOFSwitchManager switchManager;
+	private IOFConnectionListener connectionListener;
+	private INewOFConnectionListener newConnectionListener;
+	private IDebugCounterService debugCounterService;
+	private OFChannelHandler handler;
+	private Channel channel;
+	private Timer timer;
+	private ChannelHandlerContext ctx;
+	private ChannelPipeline pipeline;
+	private final OFFactory factory = OFFactories.getFactory(OFVersion.OF_13);
+
+	private Capture<Throwable> exceptionEventCapture;
+	private Capture<List<OFMessage>> writeCapture;
+
+	private OFFeaturesReply featuresReply;
+	private OFPortDesc portDesc;
+
+	private Set<Long> seenXids = null;
+
+	private Capture<IOFConnectionBackend> newConnection;
+
+	private Capture<OFFeaturesReply> newFeaturesReply;
+
+	private TestEventLoop eventLoop;
+
+	public void setUpFeaturesReply() {
+		portDesc = factory.buildPortDesc()
+				.setName("Eth1")
+				.setPortNo(OFPort.of(1))
+				.build();
+		featuresReply = factory.buildFeaturesReply()
+				.setDatapathId(dpid)
+				.setNBuffers(1)
+				.setNTables((short)1)
+				.setCapabilities(EnumSet.<OFCapabilities>of(OFCapabilities.FLOW_STATS, OFCapabilities.TABLE_STATS))
+				.setAuxiliaryId(OFAuxId.MAIN)
+				.build();
+	}
+
+	@Before
+	public void setUp() throws Exception {
+		setUpFeaturesReply();
+		switchManager = createMock(IOFSwitchManager.class);
+		connectionListener = createMock(IOFConnectionListener.class);
+		newConnectionListener = createMock(INewOFConnectionListener.class);
+		newConnection = new Capture<IOFConnectionBackend>();
+		newFeaturesReply = new Capture<OFFeaturesReply>();
+        eventLoop = new TestEventLoop();
+
+		ctx = createMock(ChannelHandlerContext.class);
+		channel = createMock(Channel.class);
+		timer = new HashedWheelTimer();
+		exceptionEventCapture = new Capture<Throwable>(CaptureType.ALL);
+		pipeline = createMock(ChannelPipeline.class);
+		writeCapture = new Capture<List<OFMessage>>(CaptureType.ALL);
+		seenXids = null;
+
+
+		// TODO: should mock IDebugCounterService and make sure
+		// the expected counters are updated.
+		debugCounterService = new DebugCounterServiceImpl();
+		debugCounterService.registerModule(OFConnectionCounters.COUNTER_MODULE);
+		SwitchManagerCounters counters =
+				new SwitchManagerCounters(debugCounterService);
+		expect(switchManager.getCounters()).andReturn(counters).anyTimes();
+		replay(switchManager);
+		handler = new OFChannelHandler(switchManager, newConnectionListener,
+				pipeline, debugCounterService, /* 62 is OF versions 1.0 thru 1.4 in decimal */
+				timer, Collections.singletonList(U32.of(62)), OFFactories.getFactory(OFVersion.OF_14));
+
+		verify(switchManager);
+		reset(switchManager);
+
+		resetChannel();
+
+		// replay controller. Reset it if you need more specific behavior
+		replay(switchManager);
+
+		// Mock ctx and channelStateEvent
+		expect(ctx.channel()).andReturn(channel).anyTimes();
+		expect(ctx.fireExceptionCaught(capture(exceptionEventCapture))).andReturn(ctx).anyTimes();
+		replay(ctx);
+
+		/* Setup an exception event capture on the channel. Right now
+		 * we only expect exception events to be send up the channel.
+		 * However, it's easy to extend to other events if we need it
+		 */
+		expect(pipeline.get(OFMessageDecoder.class)).andReturn(new OFMessageDecoder()).anyTimes();
+		replay(pipeline);
+	}
+
+	@After
+	public void tearDown() {
+		/* ensure no exception was thrown */
+		if (exceptionEventCapture.hasCaptured()) {
+			Throwable ex = exceptionEventCapture.getValue();
+			ex.printStackTrace();
+			Throwables.propagate(ex);
+		}
+		assertFalse("Unexpected messages have been captured",
+				writeCapture.hasCaptured());
+		// verify all mocks.
+		verify(channel);
+		verify(switchManager);
+		verify(ctx);
+		verify(pipeline);
+	}
+
+	/** Reset the channel mock and set basic method call expectations */
+	void resetChannel() {
+		reset(channel);
+		expect(channel.newPromise()).andAnswer(new IAnswer<ChannelPromise>() {
+			@Override
+			public ChannelPromise answer() throws Throwable {
+				return new DefaultChannelPromise(channel);
+			}
+		}).anyTimes();
+		eventLoop = new TestEventLoop();
+		expect(channel.eventLoop()).andReturn(eventLoop).anyTimes();
+		expect(channel.pipeline()).andReturn(pipeline).anyTimes();
+		expect(channel.remoteAddress()).andReturn(null).anyTimes();
+	}
+
+	/** reset, setup, and replay the messageEvent mock for the given
+	 * messages, mock controller  send message to channel handler
+	 *
+	 * This method will reset, start replay on controller, and then verify
+	 */
+	void sendMessageToHandlerWithControllerReset(List<OFMessage> messages)
+			throws Exception {
+		sendMessageToHandlerNoControllerReset(messages);
+	}
+
+	/** reset, setup, and replay the messageEvent mock for the given
+	 * messages, mock controller  send message to channel handler
+	 *
+	 * This method will start replay on controller, and then verify
+	 */
+	void sendMessageToHandlerNoControllerReset(List<OFMessage> messages)
+			throws Exception {
+		handler.channelRead(ctx, messages);
+	}
+
+	/**
+	 * Extract the list of OFMessages that was captured by the Channel.write()
+	 * capture. Will check that something was actually captured first. We'll
+	 * collapse the messages from multiple writes into a single list of
+	 * OFMessages.
+	 * Resets the channelWriteCapture.
+	 */
+	List<OFMessage> getMessagesFromCapture() {
+		List<OFMessage> msgs = new ArrayList<OFMessage>();
+
+		assertTrue("No write on channel was captured",
+				writeCapture.hasCaptured());
+		List<List<OFMessage>> capturedVals = writeCapture.getValues();
+
+		for (List<OFMessage> oneWriteList: capturedVals)
+			msgs.addAll(oneWriteList);
+		writeCapture.reset();
+		return msgs;
+	}
+
+
+	/**
+	 * Verify that the given exception event capture (as returned by
+	 * getAndInitExceptionCapture) has thrown an exception of the given
+	 * expectedExceptionClass.
+	 * Resets the capture
+	 */
+	void verifyExceptionCaptured(Class<? extends Throwable> expectedExceptionClass) {
+		assertTrue("Excpected exception not thrown", exceptionEventCapture.hasCaptured());
+		Throwable caughtEx = exceptionEventCapture.getValue();
+		assertEquals(expectedExceptionClass, caughtEx.getClass());
+		exceptionEventCapture.reset();
+	}
+
+	/** make sure that the transaction ids in the given messages are
+	 * not 0 and differ between each other.
+	 * While it's not a defect per se if the xids are we want to ensure
+	 * we use different ones for each message we send.
+	 */
+	void verifyUniqueXids(List<OFMessage> msgs) {
+		if (seenXids == null)
+			seenXids = new HashSet<Long>();
+		for (OFMessage m: msgs)  {
+			long xid = m.getXid();
+			assertTrue("Xid in messags is 0", xid != 0);
+			assertFalse("Xid " + xid + " has already been used",
+					seenXids.contains(xid));
+			seenXids.add(xid);
+		}
+	}
+
+	@Test
+	public void testNullMsg() throws Exception {
+		reset(ctx);
+		expect(ctx.fireChannelRead(null)).andReturn(ctx).once();
+		replay(ctx, channel);
+
+		// null message is not passed to the handler
+		handler.channelRead(ctx, null);
+		verify(channel, ctx);
+	}
+
+	@Test
+	public void testInitState() throws Exception {
+		replay(channel);
+
+		// We don't expect to receive /any/ messages in init state since
+		// channelConnected moves us to a different state
+		OFMessage m = factory.buildHello().build();
+		sendMessageToHandlerWithControllerReset(ImmutableList.<OFMessage>of(m));
+
+		verifyExceptionCaptured(SwitchStateException.class);
+		assertThat(handler.getStateForTesting(), CoreMatchers.instanceOf(OFChannelHandler.InitState.class));
+	}
+
+	/* Move the channel from scratch to WAIT_HELLO state */
+	@Test
+	public void moveToWaitHello() throws Exception {
+		resetChannel();
+		expect(channel.writeAndFlush(capture(writeCapture))).andReturn(null).once();
+		replay(channel);
+
+		handler.channelActive(ctx);
+		eventLoop.runTasks();
+
+		List<OFMessage> msgs = getMessagesFromCapture();
+		assertEquals(1, msgs.size());
+		assertEquals(OFType.HELLO, msgs.get(0).getType());
+		assertThat(handler.getStateForTesting(), CoreMatchers.instanceOf(OFChannelHandler.WaitHelloState.class));
+		verifyUniqueXids(msgs);
+	}
+
+	/** Move the channel from scratch to WAIT_FEATURES_REPLY state
+	 * Builds on moveToWaitHello()
+	 * adds testing for WAIT_HELLO state
+	 */
+	@Test
+	public void moveToWaitFeaturesReply() throws Exception {
+		moveToWaitHello();
+		resetChannel();
+		expect(channel.writeAndFlush(capture(writeCapture))).andReturn(null).once();
+		replay(channel);
+
+		OFMessage hello = factory.buildHello().build();
+		sendMessageToHandlerWithControllerReset(ImmutableList.<OFMessage>of(hello));
+
+		List<OFMessage> msgs = getMessagesFromCapture();
+		assertEquals(1, msgs.size());
+		assertEquals(OFType.FEATURES_REQUEST, msgs.get(0).getType());
+		verifyUniqueXids(msgs);
+
+		assertThat(handler.getStateForTesting(), CoreMatchers.instanceOf(OFChannelHandler.WaitFeaturesReplyState.class));
+	}
+
+
+	/** Move the channel from scratch to WAIT_FEATURES_REPLY state
+	 * Builds on moveToWaitHello()
+	 * adds testing for WAIT_HELLO state
+	 */
+	@Test
+	public void moveToComplete() throws Exception {
+		moveToWaitFeaturesReply();
+
+		reset(pipeline);
+		HandshakeTimeoutHandler newHandler = new HandshakeTimeoutHandler(
+				handler,
+				timer,
+				PipelineHandshakeTimeout.SWITCH);
+
+		expect(
+				pipeline.replace(EasyMock.eq(PipelineHandler.CHANNEL_HANDSHAKE_TIMEOUT),
+						EasyMock.eq(PipelineHandler.SWITCH_HANDSHAKE_TIMEOUT),
+						EasyMock.anyObject(HandshakeTimeoutHandler.class))).andReturn(newHandler)
+						.once();
+
+		replay(pipeline);
+
+		newConnectionListener.connectionOpened(capture(newConnection), capture(newFeaturesReply));
+		expectLastCall().once();
+		replay(newConnectionListener);
+
+		sendMessageToHandlerWithControllerReset(Collections.<OFMessage>singletonList(featuresReply));
+
+		assertThat(handler.getStateForTesting(), CoreMatchers.instanceOf(OFChannelHandler.CompleteState.class));
+		assertTrue("A connection has been created and set", handler.getConnectionForTesting() != null);
+		verify(newConnectionListener);
+		assertTrue(newConnection.hasCaptured());
+		assertThat(newFeaturesReply.getValue(), equalTo(featuresReply));
+	}
 
-        resetChannel();
-        expect(channel.writeAndFlush(capture(writeCapture))).andReturn(null).once();
-        replay(channel);
+	/**
+	 * Test dispatch of messages while in Complete state
+	 */
+	@Test
+	public void testMessageDispatchComplete() throws Exception {
+		moveToComplete();
+		newConnection.getValue().setListener(connectionListener);
 
-        // Send echo request. expect reply
-        OFMessage echoRequest = factory.buildEchoRequest().build();
-        sendMessageToHandlerWithControllerReset(ImmutableList.<OFMessage>of(echoRequest));
+		resetChannel();
+		expect(channel.writeAndFlush(capture(writeCapture))).andReturn(null).once();
+		replay(channel);
 
-        List<OFMessage> msgs = getMessagesFromCapture();
-        assertEquals(1, msgs.size());
-        assertEquals(OFType.ECHO_REPLY, msgs.get(0).getType());
+		// Send echo request. expect reply
+		OFMessage echoRequest = factory.buildEchoRequest().build();
+		sendMessageToHandlerWithControllerReset(ImmutableList.<OFMessage>of(echoRequest));
 
+		List<OFMessage> msgs = getMessagesFromCapture();
+		assertEquals(1, msgs.size());
+		assertEquals(OFType.ECHO_REPLY, msgs.get(0).getType());
 
-        // Send barrier reply. expect dispatch
-        OFBarrierReply barrierReply = factory.buildBarrierReply()
-                .build();
 
-        resetAndExpectConnectionListener(barrierReply);
+		// Send barrier reply. expect dispatch
+		OFBarrierReply barrierReply = factory.buildBarrierReply()
+				.build();
 
+		resetAndExpectConnectionListener(barrierReply);
 
-        // Send packet in. expect dispatch
-        OFFlowRemoved flowRemoved = factory.buildFlowRemoved()
-                .build();
 
-        resetAndExpectConnectionListener(flowRemoved);
+		// Send packet in. expect dispatch
+		OFFlowRemoved flowRemoved = factory.buildFlowRemoved()
+				.build();
 
-        // Send get config reply. expect dispatch
-        OFGetConfigReply getConfigReply = factory.buildGetConfigReply()
-                .build();
+		resetAndExpectConnectionListener(flowRemoved);
 
-        resetAndExpectConnectionListener(getConfigReply);
+		// Send get config reply. expect dispatch
+		OFGetConfigReply getConfigReply = factory.buildGetConfigReply()
+				.build();
 
-        // Send packet in. expect dispatch
-        OFPacketIn pi = factory.buildPacketIn()
-                .setReason(OFPacketInReason.NO_MATCH)
-                .build();
+		resetAndExpectConnectionListener(getConfigReply);
 
-        resetAndExpectConnectionListener(pi);
+		// Send packet in. expect dispatch
+		OFPacketIn pi = factory.buildPacketIn()
+				.setReason(OFPacketInReason.NO_MATCH)
+				.build();
 
-        // Send port status. expect dispatch
-        OFPortStatus portStatus = factory.buildPortStatus()
-                .setReason(OFPortReason.DELETE)
-                .setDesc(portDesc)
-                .build();
+		resetAndExpectConnectionListener(pi);
 
-        resetAndExpectConnectionListener(portStatus);
+		// Send port status. expect dispatch
+		OFPortStatus portStatus = factory.buildPortStatus()
+				.setReason(OFPortReason.DELETE)
+				.setDesc(portDesc)
+				.build();
 
-        // Send queue reply. expect dispatch
-        OFQueueGetConfigReply queueReply = factory.buildQueueGetConfigReply()
-                .build();
+		resetAndExpectConnectionListener(portStatus);
 
-        resetAndExpectConnectionListener(queueReply);
+		// Send queue reply. expect dispatch
+		OFQueueGetConfigReply queueReply = factory.buildQueueGetConfigReply()
+				.build();
 
-        // Send stat reply. expect dispatch
-        OFFlowStatsReply statReply = factory.buildFlowStatsReply()
-                .build();
+		resetAndExpectConnectionListener(queueReply);
 
-        resetAndExpectConnectionListener(statReply);
+		// Send stat reply. expect dispatch
+		OFFlowStatsReply statReply = factory.buildFlowStatsReply()
+				.build();
 
-        // Send role reply. expect dispatch
-        OFRoleReply roleReply = factory.buildRoleReply()
-                .setRole(OFControllerRole.ROLE_MASTER)
-                .build();
+		resetAndExpectConnectionListener(statReply);
 
-        resetAndExpectConnectionListener(roleReply);
+		// Send role reply. expect dispatch
+		OFRoleReply roleReply = factory.buildRoleReply()
+				.setRole(OFControllerRole.ROLE_MASTER)
+				.build();
 
-        // Send experimenter. expect dispatch
-        OFBsnSetAuxCxnsReply auxReply = factory.buildBsnSetAuxCxnsReply()
-                .build();
+		resetAndExpectConnectionListener(roleReply);
 
-        resetAndExpectConnectionListener(auxReply);
+		// Send experimenter. expect dispatch
+		OFBsnSetAuxCxnsReply auxReply = factory.buildBsnSetAuxCxnsReply()
+				.build();
 
-    }
+		resetAndExpectConnectionListener(auxReply);
 
-    public void resetAndExpectConnectionListener(OFMessage m) throws Exception{
-        reset(connectionListener);
-        connectionListener.messageReceived(handler.getConnectionForTesting(), m);
-        expectLastCall().once();
-        replay(connectionListener);
+	}
 
-        sendMessageToHandlerWithControllerReset(Collections.<OFMessage>singletonList(m));
+	public void resetAndExpectConnectionListener(OFMessage m) throws Exception{
+		reset(connectionListener);
+		connectionListener.messageReceived(handler.getConnectionForTesting(), m);
+		expectLastCall().once();
+		replay(connectionListener);
 
-        verify(connectionListener);
-    }
+		sendMessageToHandlerWithControllerReset(Collections.<OFMessage>singletonList(m));
+
+		verify(connectionListener);
+	}
 }
diff --git a/src/test/java/net/floodlightcontroller/core/internal/OFConnectionTest.java b/src/test/java/net/floodlightcontroller/core/internal/OFConnectionTest.java
index 24d39515c6b8dd9d93208959632e7fe1da1249d7..23230074aacb2c69d45801bda2c5bdaa4bddff1c 100644
--- a/src/test/java/net/floodlightcontroller/core/internal/OFConnectionTest.java
+++ b/src/test/java/net/floodlightcontroller/core/internal/OFConnectionTest.java
@@ -18,6 +18,7 @@ import io.netty.channel.Channel;
 import io.netty.util.HashedWheelTimer;
 import io.netty.util.Timer;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -25,6 +26,7 @@ import net.floodlightcontroller.core.SwitchDisconnectedException;
 import net.floodlightcontroller.core.internal.OFConnection;
 import net.floodlightcontroller.core.internal.OFConnectionCounters;
 import net.floodlightcontroller.core.internal.OFErrorMsgException;
+import net.floodlightcontroller.core.test.TestEventLoop;
 import net.floodlightcontroller.debugcounter.DebugCounterServiceImpl;
 import net.floodlightcontroller.debugcounter.IDebugCounterService;
 
@@ -68,17 +70,28 @@ public class OFConnectionTest {
     private OFConnection conn;
     private DatapathId switchId;
     private Timer timer;
+    private TestEventLoop eventLoop;
 
     @Before
     public void setUp() throws Exception {
         factory = OFFactories.getFactory(OFVersion.OF_13);
         switchId = DatapathId.of(1);
         timer = new HashedWheelTimer();
-        channel = EasyMock.createNiceMock(Channel.class);        
+        channel = EasyMock.createMock(Channel.class);        
         IDebugCounterService debugCounterService = new DebugCounterServiceImpl();
         debugCounterService.registerModule(OFConnectionCounters.COUNTER_MODULE);
         conn = new OFConnection(switchId, factory, channel, OFAuxId.MAIN,
                                 debugCounterService, timer);
+        eventLoop = new TestEventLoop();
+        
+        expect(channel.eventLoop()).andReturn(eventLoop).anyTimes();
+    }
+    
+    @After
+    public void tearDown() throws Exception {
+    	if (timer != null) {
+    		timer.stop();
+    	}
     }
 
     @Test(timeout = 5000)
@@ -90,6 +103,7 @@ public class OFConnectionTest {
         assertThat("Connection should have 1 pending request",
                 conn.getPendingRequestIds().size(), equalTo(1));
 
+        eventLoop.runTasks();
         assertThat("Should have captured MsgList", cMsgList.getValue(),
                 Matchers.<OFMessage> contains(echoRequest));
 
@@ -117,7 +131,8 @@ public class OFConnectionTest {
         ListenableFuture<List<OFFlowStatsReply>> future = conn.writeStatsRequest(flowStatsRequest);
         assertThat("Connection should have 1 pending request",
                 conn.getPendingRequestIds().size(), equalTo(1));
-
+        
+        eventLoop.runTasks();
         assertThat("Should have captured MsgList", cMsgList.getValue(),
                 Matchers.<OFMessage> contains(flowStatsRequest));
 
@@ -165,6 +180,7 @@ public class OFConnectionTest {
         assertThat("Connection should have 1 pending request",
                 conn.getPendingRequestIds().size(), equalTo(1));
 
+        eventLoop.runTasks();
         assertThat("Should have captured MsgList", cMsgList.getValue(),
                 Matchers.<OFMessage> contains(roleRequest));
 
@@ -222,7 +238,7 @@ public class OFConnectionTest {
                 conn.getPendingRequestIds().isEmpty(), equalTo(true));
     }
 
-    /** write a packetOut, which is buffered */
+    /** write a packetOut, which is not buffered */
     @Test(timeout = 5000)
     public void testSingleMessageWrite() throws InterruptedException, ExecutionException {
         Capture<List<OFMessage>> cMsgList = prepareChannelForWriteList();
@@ -233,6 +249,7 @@ public class OFConnectionTest {
                 .build();
         
         conn.write(packetOut);
+        eventLoop.runTasks();
         assertThat("Write should have been flushed", cMsgList.hasCaptured(), equalTo(true));
         
         List<OFMessage> value = cMsgList.getValue();
@@ -253,7 +270,7 @@ public class OFConnectionTest {
                 .build();
 
         conn.write(ImmutableList.of(hello, packetOut));
-
+        eventLoop.runTasks();
         assertThat("Write should have been written", cMsgList.hasCaptured(), equalTo(true));
         List<OFMessage> value = cMsgList.getValue();
         logger.info("Captured channel write: "+value);
diff --git a/src/test/java/net/floodlightcontroller/core/test/TestEventLoop.java b/src/test/java/net/floodlightcontroller/core/test/TestEventLoop.java
new file mode 100644
index 0000000000000000000000000000000000000000..b31725e6762a47a4b35ce67f059ac27979b46da4
--- /dev/null
+++ b/src/test/java/net/floodlightcontroller/core/test/TestEventLoop.java
@@ -0,0 +1,134 @@
+package net.floodlightcontroller.core.test;
+
+import java.util.ArrayDeque;
+import java.util.Queue;
+import java.util.concurrent.TimeUnit;
+
+import com.google.common.collect.ImmutableList;
+
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelPromise;
+import io.netty.channel.DefaultChannelPromise;
+import io.netty.channel.EventLoop;
+import io.netty.channel.EventLoopGroup;
+import io.netty.util.concurrent.AbstractScheduledEventExecutor;
+import io.netty.util.concurrent.Future;
+
+public final class TestEventLoop extends AbstractScheduledEventExecutor implements EventLoop {
+
+    private final Queue<Runnable> tasks = new ArrayDeque<Runnable>(2);
+
+    @Override
+    public void execute(Runnable command) {
+        if (command == null) {
+            throw new NullPointerException("command");
+        }
+        tasks.add(command);
+    }
+
+    public void runTasks() {
+        for (;;) {
+            Runnable task = tasks.poll();
+            if (task == null) {
+                break;
+            }
+
+            task.run();
+        }
+    }
+
+    long runScheduledTasks() {
+        long time = AbstractScheduledEventExecutor.nanoTime();
+        for (;;) {
+            Runnable task = pollScheduledTask(time);
+            if (task == null) {
+                return nextScheduledTaskNano();
+            }
+
+            task.run();
+        }
+    }
+
+    long nextScheduledTask() {
+        return nextScheduledTaskNano();
+    }
+
+    @Override
+    protected void cancelScheduledTasks() {
+        super.cancelScheduledTasks();
+    }
+
+    @Override
+    public Future<?> shutdownGracefully(long quietPeriod, long timeout, TimeUnit unit) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Future<?> terminationFuture() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    @Deprecated
+    public void shutdown() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isShuttingDown() {
+        return false;
+    }
+
+    @Override
+    public boolean isShutdown() {
+        return false;
+    }
+
+    @Override
+    public boolean isTerminated() {
+        return false;
+    }
+
+    @Override
+    public boolean awaitTermination(long timeout, TimeUnit unit)
+            throws InterruptedException {
+        Thread.sleep(unit.toMillis(timeout));
+        return false;
+    }
+
+    @Override
+    public ChannelFuture register(Channel channel) {
+        return register(channel, new DefaultChannelPromise(channel, this));
+    }
+
+    @Override
+    public ChannelFuture register(Channel channel, ChannelPromise promise) {
+        channel.unsafe().register(this, promise);
+        return promise;
+    }
+
+    @Override
+    public boolean inEventLoop() {
+        return true;
+    }
+
+    @Override
+    public boolean inEventLoop(Thread thread) {
+        return true;
+    }
+
+    @Override
+    public EventLoop next() {
+        return this;
+    }
+
+    @Override
+    public EventLoopGroup parent() {
+        return this;
+    }
+
+    public ImmutableList<Runnable> getQueuedTasks() {
+        return ImmutableList.copyOf(tasks);
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/net/floodlightcontroller/loadbalancer/LoadBalancerTest.java b/src/test/java/net/floodlightcontroller/loadbalancer/LoadBalancerTest.java
index f19ce3bff93ff051ce38c8853c1b375246e0a1a2..b12b2f5cdc8adca998f20e319c4712164968b248 100644
--- a/src/test/java/net/floodlightcontroller/loadbalancer/LoadBalancerTest.java
+++ b/src/test/java/net/floodlightcontroller/loadbalancer/LoadBalancerTest.java
@@ -448,8 +448,6 @@ public class LoadBalancerTest extends FloodlightTestCase {
 		expect(sw1.getOFFactory()).andReturn(factory).anyTimes();
 		sw1.write(capture(wc1));
 		expectLastCall().anyTimes();
-		sw1.flush();
-		expectLastCall().anyTimes();
 		
 		replay(sw1);
 		sfp.switchAdded(DatapathId.of(1L));
diff --git a/src/test/java/net/floodlightcontroller/staticflowentry/StaticFlowTests.java b/src/test/java/net/floodlightcontroller/staticflowentry/StaticFlowTests.java
index 51b2319f19053890ae402247eaf4b05a83f6bebe..407db1d3c70d6c25ea458460983eec0811329195 100644
--- a/src/test/java/net/floodlightcontroller/staticflowentry/StaticFlowTests.java
+++ b/src/test/java/net/floodlightcontroller/staticflowentry/StaticFlowTests.java
@@ -207,8 +207,6 @@ public class StaticFlowTests extends FloodlightTestCase {
 		expectLastCall().anyTimes();
 		mockSwitch.write(capture(writeCaptureList));
 		expectLastCall().anyTimes();
-		mockSwitch.flush();
-		expectLastCall().anyTimes();
 		expect(mockSwitch.getOFFactory()).andReturn(factory).anyTimes();
 		replay(mockSwitch);
 
@@ -253,8 +251,6 @@ public class StaticFlowTests extends FloodlightTestCase {
 		expectLastCall().anyTimes();
 		mockSwitch.write(capture(writeCaptureList));
 		expectLastCall().anyTimes();
-		mockSwitch.flush();
-		expectLastCall().anyTimes();
 		expect(mockSwitch.getOFFactory()).andReturn(factory).anyTimes();
 		expect(mockSwitch.getId()).andReturn(DatapathId.of(dpid)).anyTimes();
 		replay(mockSwitch);
diff --git a/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java b/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java
index 119b7acf8dcba7ca15ca9d5bf89a92ce798c5483..ca5d326569d59c60891e312f46cf878cd28632a0 100644
--- a/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java
+++ b/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java
@@ -160,11 +160,6 @@ public class OFMessageDamperMockSwitch implements IOFSwitch {
         return null;
     }
 
-    @Override
-    public void flush() {
-        assertTrue("Unexpected method call", false);
-    }
-
     @Override
     public long getBuffers() {
         fail("Unexpected method call");