diff --git a/of/api/pom.xml b/of/api/pom.xml
index 8f123e1..050fedd 100644
--- a/of/api/pom.xml
+++ b/of/api/pom.xml
@@ -63,7 +63,7 @@
                 <configuration>
                     <instructions>
                         <Export-Package>
-                            org.projectfloodlight.openflow.*
+                            org.onlab.onos.of.*,org.projectfloodlight.openflow.*
                         </Export-Package>
                     </instructions>
                 </configuration>
diff --git a/of/api/src/main/java/org/onlab/onos/of/controller/DeleteMe.java b/of/api/src/main/java/org/onlab/onos/of/controller/DeleteMe.java
deleted file mode 100644
index 1db6eae..0000000
--- a/of/api/src/main/java/org/onlab/onos/of/controller/DeleteMe.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package org.onlab.onos.of.controller;
-
-/**
- * Created by tom on 8/21/14.
- */
-public interface DeleteMe {
-}
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/util/Dpid.java b/of/api/src/main/java/org/onlab/onos/of/controller/Dpid.java
similarity index 96%
rename from of/ctl/src/main/java/org/onlab/onos/of/controller/impl/util/Dpid.java
rename to of/api/src/main/java/org/onlab/onos/of/controller/Dpid.java
index dec8424..02a957e 100644
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/util/Dpid.java
+++ b/of/api/src/main/java/org/onlab/onos/of/controller/Dpid.java
@@ -1,4 +1,4 @@
-package org.onlab.onos.of.controller.impl.util;
+package org.onlab.onos.of.controller;
 
 import org.projectfloodlight.openflow.util.HexString;
 
diff --git a/of/api/src/main/java/org/onlab/onos/of/controller/OpenFlowController.java b/of/api/src/main/java/org/onlab/onos/of/controller/OpenFlowController.java
new file mode 100644
index 0000000..5aec885
--- /dev/null
+++ b/of/api/src/main/java/org/onlab/onos/of/controller/OpenFlowController.java
@@ -0,0 +1,100 @@
+package org.onlab.onos.of.controller;
+
+import org.projectfloodlight.openflow.protocol.OFMessage;
+
+/**
+ * Abstraction of an OpenFlow controller. Serves as a one stop
+ * shop for obtaining OpenFlow devices and (un)register listeners
+ * on OpenFlow events
+ */
+public interface OpenFlowController {
+
+    /**
+     * Returns all switches known to this OF controller.
+     * @return Iterable of dpid elements
+     */
+    public Iterable<OpenFlowSwitch> getSwitches();
+
+    /**
+     * Returns all master switches known to this OF controller.
+     * @return Iterable of dpid elements
+     */
+    public Iterable<OpenFlowSwitch> getMasterSwitches();
+
+    /**
+     * Returns all equal switches known to this OF controller.
+     * @return Iterable of dpid elements
+     */
+    public Iterable<OpenFlowSwitch> getEqualSwitches();
+
+
+    /**
+     * Returns the actual switch for the given Dpid.
+     * @param dpid the switch to fetch
+     * @return the interface to this switch
+     */
+    public OpenFlowSwitch getSwitch(Dpid dpid);
+
+    /**
+     * Returns the actual master switch for the given Dpid, if one exists.
+     * @param dpid the switch to fetch
+     * @return the interface to this switch
+     */
+    public OpenFlowSwitch getMasterSwitch(Dpid dpid);
+
+    /**
+     * Returns the actual equal switch for the given Dpid, if one exists.
+     * @param dpid the switch to fetch
+     * @return the interface to this switch
+     */
+    public OpenFlowSwitch getEqualSwitch(Dpid dpid);
+
+    /**
+     * Register a listener for meta events that occur to OF
+     * devices.
+     * @param listener the listener to notify
+     */
+    public void addListener(OpenFlowSwitchListener listener);
+
+    /**
+     * Unregister a listener.
+     *
+     * @param listener the listener to unregister
+     */
+    public void removeListener(OpenFlowSwitchListener listener);
+
+    /**
+     * Register a listener for packet events.
+     * @param priority the importance of this listener, lower values are more important
+     * @param listener the listener to notify
+     */
+    public void addPacketListener(int priority, PacketListener listener);
+
+    /**
+     * Unregister a listener.
+     *
+     * @param listener the listener to unregister
+     */
+    public void removePacketListener(PacketListener listener);
+
+    /**
+     * Send a message to a particular switch.
+     * @param dpid the switch to send to.
+     * @param msg the message to send
+     */
+    public void write(Dpid dpid, OFMessage msg);
+
+    /**
+     * Process a message and notify the appropriate listeners.
+     *
+     * @param msg the message to process.
+     */
+    public void processPacket(OFMessage msg);
+
+    /**
+     * Sets the role for a given switch.
+     * @param role the desired role
+     * @param dpid the switch to set the role for.
+     */
+    public void setRole(Dpid dpid, RoleState role);
+}
diff --git a/of/api/src/main/java/org/onlab/onos/of/controller/OpenFlowSwitch.java b/of/api/src/main/java/org/onlab/onos/of/controller/OpenFlowSwitch.java
new file mode 100644
index 0000000..e6f52bd
--- /dev/null
+++ b/of/api/src/main/java/org/onlab/onos/of/controller/OpenFlowSwitch.java
@@ -0,0 +1,23 @@
+package org.onlab.onos.of.controller;
+
+import org.projectfloodlight.openflow.protocol.OFMessage;
+
+/**
+ * Abstract model of an OpenFlow Switch.
+ *
+ */
+public interface OpenFlowSwitch {
+
+    /**
+     * Writes the message to this switch.
+     *
+     * @param msg the message to write
+     */
+    public void write(OFMessage msg);
+
+    /**
+     * Handle a message from the switch.
+     * @param fromSwitch the message to handle
+     */
+    public void handleMessage(OFMessage fromSwitch);
+}
diff --git a/of/api/src/main/java/org/onlab/onos/of/controller/OpenFlowSwitchEvent.java b/of/api/src/main/java/org/onlab/onos/of/controller/OpenFlowSwitchEvent.java
new file mode 100644
index 0000000..281d505
--- /dev/null
+++ b/of/api/src/main/java/org/onlab/onos/of/controller/OpenFlowSwitchEvent.java
@@ -0,0 +1,17 @@
+package org.onlab.onos.of.controller;
+
+/**
+ * Meta events that can happen at a switch.
+ *
+ */
+public enum OpenFlowSwitchEvent {
+    /**
+     * The switch connected.
+     */
+    SWITCH_CONNECTED,
+
+    /**
+     * The switch disconnected.
+     */
+    SWITCH_DISCONNECTED
+}
diff --git a/of/api/src/main/java/org/onlab/onos/of/controller/OpenFlowSwitchListener.java b/of/api/src/main/java/org/onlab/onos/of/controller/OpenFlowSwitchListener.java
new file mode 100644
index 0000000..7ccba6d
--- /dev/null
+++ b/of/api/src/main/java/org/onlab/onos/of/controller/OpenFlowSwitchListener.java
@@ -0,0 +1,20 @@
+package org.onlab.onos.of.controller;
+
+/**
+ * Allows for providers interested in Switch events to be notified.
+ */
+public interface OpenFlowSwitchListener {
+
+    /**
+     * Notify that the switch was added.
+     * @param dpid the switch where the event occurred
+     */
+    public void switchAdded(Dpid dpid);
+
+    /**
+     * Notify that the switch was removed.
+     * @param dpid the switch where the event occurred.
+     */
+    public void switchRemoved(Dpid dpid);
+
+}
diff --git a/of/api/src/main/java/org/onlab/onos/of/controller/PacketContext.java b/of/api/src/main/java/org/onlab/onos/of/controller/PacketContext.java
new file mode 100644
index 0000000..bc06e93
--- /dev/null
+++ b/of/api/src/main/java/org/onlab/onos/of/controller/PacketContext.java
@@ -0,0 +1,50 @@
+package org.onlab.onos.of.controller;
+
+import org.projectfloodlight.openflow.types.OFPort;
+
+/**
+ * A representation of a packet context which allows any provider
+ * to view the packet in event but may block the response to the
+ * event if blocked has been called.
+ */
+public interface PacketContext {
+
+    //TODO: may want to support sending packet out other switches than
+    // the one it came in on.
+    /**
+     * Blocks further responses (ie. send() calls) on this
+     * packet in event.
+     */
+    public void block();
+
+    /**
+     * Provided build has been called send the packet
+     * out the switch it came in on.
+     */
+    public void send();
+
+    /**
+     * Build the packet out in response to this packet in event.
+     * @param outPort the out port to send to packet out of.
+     */
+    public void build(OFPort outPort);
+
+    /**
+     * Build the packet out in response to this packet in event.
+     * @param ethFrame the actual packet to send out.
+     * @param outPort the out port to send to packet out of.
+     */
+    public void build(Object ethFrame, OFPort outPort);
+
+    /**
+     * Provided a handle onto the parsed payload.
+     * @return the parsed form of the payload.
+     */
+    public Object parsed();
+
+    /**
+     * Provide the dpid of the switch where the packet in arrived.
+     * @return the dpid of the switch.
+     */
+    public Dpid dpid();
+}
diff --git a/of/api/src/main/java/org/onlab/onos/of/controller/PacketListener.java b/of/api/src/main/java/org/onlab/onos/of/controller/PacketListener.java
new file mode 100644
index 0000000..5c6d73f
--- /dev/null
+++ b/of/api/src/main/java/org/onlab/onos/of/controller/PacketListener.java
@@ -0,0 +1,13 @@
+package org.onlab.onos.of.controller;
+
+/**
+ * Notifies providers about Packet in events.
+ */
+public interface PacketListener {
+
+    /**
+     * Handle the packet.
+     * @param pktCtx the packet context ({@link }
+     */
+    public void handlePacket(PacketContext pktCtx);
+}
diff --git a/of/api/src/main/java/org/onlab/onos/of/controller/RoleState.java b/of/api/src/main/java/org/onlab/onos/of/controller/RoleState.java
new file mode 100644
index 0000000..527a91c
--- /dev/null
+++ b/of/api/src/main/java/org/onlab/onos/of/controller/RoleState.java
@@ -0,0 +1,23 @@
+package org.onlab.onos.of.controller;
+
+import org.projectfloodlight.openflow.protocol.OFControllerRole;
+
+/**
+ * The role of the controller as it pertains to a particular switch.
+ * Note that this definition of the role enum is different from the
+ * OF1.3 definition. It is maintained here to be backward compatible to
+ * earlier versions of the controller code. This enum is translated
+ * to the OF1.3 enum, before role messages are sent to the switch.
+ * See sendRoleRequestMessage method in OFSwitchImpl
+ */
+public enum RoleState {
+    EQUAL(OFControllerRole.ROLE_EQUAL),
+    MASTER(OFControllerRole.ROLE_MASTER),
+    SLAVE(OFControllerRole.ROLE_SLAVE);
+
+    private RoleState(OFControllerRole nxRole) {
+        nxRole.ordinal();
+    }
+
+}
+
diff --git a/of/ctl/pom.xml b/of/ctl/pom.xml
index 5c090cb..88bdcd9 100644
--- a/of/ctl/pom.xml
+++ b/of/ctl/pom.xml
@@ -38,6 +38,10 @@
     </properties>
 
     <dependencies>
+        <dependency>
+            <groupId>org.onlab.onos</groupId>
+            <artifactId>onos-of-api</artifactId>
+        </dependency>
         <!-- ONOS's direct dependencies -->
         <dependency>
             <groupId>org.apache.felix</groupId>
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/IOFSwitch.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/IOFSwitch.java
deleted file mode 100644
index afa3703..0000000
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/IOFSwitch.java
+++ /dev/null
@@ -1,584 +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 org.onlab.onos.of.controller.impl;
-
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Future;
-
-import org.onlab.onos.of.controller.impl.debugcounter.IDebugCounterService;
-import org.onlab.onos.of.controller.impl.debugcounter.IDebugCounterService.CounterException;
-import org.onlab.onos.of.controller.impl.util.OrderedCollection;
-
-import org.jboss.netty.channel.Channel;
-import org.projectfloodlight.openflow.protocol.OFActionType;
-import org.projectfloodlight.openflow.protocol.OFCapabilities;
-import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
-import org.projectfloodlight.openflow.protocol.OFFeaturesReply;
-import org.projectfloodlight.openflow.protocol.OFMessage;
-import org.projectfloodlight.openflow.protocol.OFPortDesc;
-import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply;
-import org.projectfloodlight.openflow.protocol.OFPortStatus;
-import org.projectfloodlight.openflow.protocol.OFStatsReply;
-import org.projectfloodlight.openflow.protocol.OFStatsRequest;
-import org.projectfloodlight.openflow.protocol.OFVersion;
-import org.projectfloodlight.openflow.types.U64;
-
-
-public interface IOFSwitch {
-
-    /**
-     * OF1.3 switches should support role-request messages as in the 1.3 spec.
-     * OF1.0 switches may or may not support the Nicira role request extensions.
-     * To indicate the support, this property should be set by the associated
-     * OF1.0 switch driver in the net.onrc.onos.core.drivermanager package.
-     * The property will be ignored for OF1.3 switches.
-     */
-    public static final String SWITCH_SUPPORTS_NX_ROLE = "supportsNxRole";
-
-
-    //************************
-    // Channel related
-    //************************
-
-    /**
-     * Disconnects the switch by closing the TCP connection. Results in a call
-     * to the channel handler's channelDisconnected method for cleanup
-     * @throws IOException
-     */
-    public void disconnectSwitch();
-
-    /**
-     * Writes to the OFMessage to the output stream.
-     *
-     * @param m
-     * @throws IOException
-     */
-    public void write(OFMessage m) throws IOException;
-
-    /**
-     * Writes the list of messages to the output stream.
-     *
-     * @param msglist
-     * @throws IOException
-     */
-    public void write(List<OFMessage> msglist) throws IOException;
-
-    /**
-     * Gets the date the switch connected to this controller.
-     *
-     * @return the date
-     */
-    public Date getConnectedSince();
-
-    /**
-     * Gets the next available transaction id.
-     *
-     * @return the next transaction ID
-     */
-    public int getNextTransactionId();
-
-    /**
-     * Checks if the switch is still connected.
-     * Only call while holding processMessageLock
-     *
-     * @return whether the switch is still disconnected
-     */
-    public boolean isConnected();
-
-    /**
-     * Sets whether the switch is connected.
-     * Only call while holding modifySwitchLock
-     *
-     * @param connected whether the switch is connected
-     */
-    public void setConnected(boolean connected);
-
-    /**
-     * Flushes all flows queued for this switch in the current thread.
-     * NOTE: The contract is limited to the current thread
-     */
-    public void flush();
-
-    /**
-     * Sets the Netty Channel this switch instance is associated with.
-     * <p>
-     * Called immediately after instantiation
-     *
-     * @param channel the channel
-     */
-    public void setChannel(Channel channel);
-
-    //************************
-    // Switch features related
-    //************************
-
-    /**
-     * Gets the datapathId of the switch.
-     *
-     * @return the switch buffers
-     */
-    public long getId();
-
-    /**
-     * Gets a string version of the ID for this switch.
-     *
-     * @return string version of the ID
-     */
-    public String getStringId();
-
-    /**
-     * Gets the number of buffers.
-     *
-     * @return the number of buffers
-     */
-    public int getNumBuffers();
-
-    public Set<OFCapabilities> getCapabilities();
-
-    public byte getNumTables();
-
-    /**
-     * Returns an OFDescStatsReply message object. Use the methods contained
-     * to retrieve switch descriptions for Manufacturer, Hw/Sw version etc.
-     */
-    public OFDescStatsReply getSwitchDescription();
-
-    /**
-     * Cancel features reply with a specific transaction ID.
-     * @param transactionId the transaction ID
-     */
-    public void cancelFeaturesReply(int transactionId);
-
-    /**
-     * Gets the OFActionType set.
-     * <p>
-     * getActions has relevance only for an OpenFlow 1.0 switch.
-     * For OF1.3, each table can support different actions
-     *
-     * @return the action set
-     */
-    public Set<OFActionType> getActions();
-
-    public void setOFVersion(OFVersion ofv);
-
-    public OFVersion getOFVersion();
-
-
-    //************************
-    //  Switch port related
-    //************************
-
-    /**
-     * the type of change that happened to an open flow port.
-     */
-    public enum PortChangeType {
-        /** Either a new port has been added by the switch, or we are
-         * adding a port we just deleted (via a prior notification) due to
-         * a change in the portNumber-portName mapping.
-         */
-        ADD,
-        /** some other feature of the port has changed (eg. speed)*/
-        OTHER_UPDATE,
-        /** Either a port has been deleted by the switch, or we are deleting
-         * a port whose portNumber-portName mapping has changed. Note that in
-         * the latter case, a subsequent notification will be sent out to add a
-         * port with the new portNumber-portName mapping.
-         */
-        DELETE,
-        /** Port is up (i.e. enabled). Presumably an earlier notification had
-         * indicated that it was down. To be UP implies that the port is
-         * administratively considered UP (see ofp_port_config) AND the port
-         * link is up AND the port is no longer blocked (see ofp_port_state).
-         */
-        UP,
-        /** Port is down (i.e. disabled). Presumably an earlier notification had
-         * indicated that it was up, or the port was always up.
-         * To be DOWN implies that the port has been either
-         * administratively brought down (see ofp_port_config) OR the port
-         * link is down OR the port is blocked (see ofp_port_state).
-         */
-        DOWN,
-    }
-
-    /**
-     * Describes a change of an open flow port.
-     */
-    public static class PortChangeEvent {
-        public final OFPortDesc port;
-        public final PortChangeType type;
-        /**
-         * @param port
-         * @param type
-         */
-        public PortChangeEvent(OFPortDesc port,
-                               PortChangeType type) {
-            this.port = port;
-            this.type = type;
-        }
-        /* (non-Javadoc)
-         * @see java.lang.Object#hashCode()
-         */
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = 1;
-            result = prime * result + ((port == null) ? 0 : port.hashCode());
-            result = prime * result + ((type == null) ? 0 : type.hashCode());
-            return result;
-        }
-        /* (non-Javadoc)
-         * @see java.lang.Object#equals(java.lang.Object)
-         */
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj == null) {
-                return false;
-            }
-            if (getClass() != obj.getClass()) {
-                return false;
-            }
-            PortChangeEvent other = (PortChangeEvent) obj;
-            if (port == null) {
-                if (other.port != null) {
-                    return false;
-                }
-            } else if (!port.equals(other.port)) {
-                return false;
-            }
-            if (type != other.type) {
-                return false;
-            }
-            return true;
-        }
-        /* (non-Javadoc)
-         * @see java.lang.Object#toString()
-         */
-        @Override
-        public String toString() {
-            return "[" + type + " " + port.toString() + "]";
-        }
-    }
-
-
-    /**
-     * Get list of all enabled ports. This will typically be different from
-     * the list of ports in the OFFeaturesReply, since that one is a static
-     * snapshot of the ports at the time the switch connected to the controller
-     * whereas this port list also reflects the port status messages that have
-     * been received.
-     *
-     * @return Unmodifiable list of ports not backed by the underlying collection
-     */
-    public Collection<OFPortDesc> getEnabledPorts();
-
-    /**
-     * Get list of the port numbers of all enabled ports. This will typically
-     * be different from the list of ports in the OFFeaturesReply, since that
-     * one is a static snapshot of the ports at the time the switch connected
-     * to the controller whereas this port list also reflects the port status
-     * messages that have been received.
-     *
-     * @return Unmodifiable list of ports not backed by the underlying collection
-     */
-    public Collection<Integer> getEnabledPortNumbers();
-
-    /**
-     * Retrieve the port object by the port number. The port object
-     * is the one that reflects the port status updates that have been
-     * received, not the one from the features reply.
-     *
-     * @param portNumber
-     * @return port object
-     */
-    public OFPortDesc getPort(int portNumber);
-
-    /**
-     * Retrieve the port object by the port name. The port object
-     * is the one that reflects the port status updates that have been
-     * received, not the one from the features reply.
-     *
-     * @param portName
-     * @return port object
-     */
-    public OFPortDesc getPort(String portName);
-
-    /**
-     * Add or modify a switch port. This is called by the core controller
-     * code in response to a OFPortStatus message.
-     *
-     * OFPPR_MODIFY and OFPPR_ADD will be treated as equivalent. The OpenFlow
-     * spec is not clear on whether portNames are portNumbers are considered
-     * authoritative identifiers. We treat portNames <-> portNumber mappings
-     * as fixed. If they change, we delete all previous conflicting ports and
-     * add all new ports.
-     *
-     * @param ps the port status message
-     * @return the ordered Collection of changes "applied" to the old ports
-     * of the switch according to the PortStatus message. A single PortStatus
-     * message can result in multiple changes.
-     * If portName <-> portNumber mappings have
-     * changed, the iteration order ensures that delete events for old
-     * conflicting appear before before events adding new ports
-     */
-    public OrderedCollection<PortChangeEvent> processOFPortStatus(OFPortStatus ps);
-
-    /**
-     * Get list of all ports. This will typically be different from
-     * the list of ports in the OFFeaturesReply, since that one is a static
-     * snapshot of the ports at the time the switch connected to the controller
-     * whereas this port list also reflects the port status messages that have
-     * been received.
-     *
-     * @return Unmodifiable list of ports
-     */
-    public Collection<OFPortDesc> getPorts();
-
-    /**
-     * @param portName
-     * @return Whether a port is enabled per latest port status message
-     * (not configured down nor link down nor in spanning tree blocking state)
-     */
-    public boolean portEnabled(int portName);
-
-    /**
-     * @param portName
-     * @return Whether a port is enabled per latest port status message
-     * (not configured down nor link down nor in spanning tree blocking state)
-     */
-    public boolean portEnabled(String portName);
-
-    /**
-     * Compute the changes that would be required to replace the old ports
-     * of this switch with the new ports.
-     * @param ports new ports to set
-     * @return the ordered collection of changes "applied" to the old ports
-     * of the switch in order to set them to the new set.
-     * If portName <-> portNumber mappings have
-     * changed, the iteration order ensures that delete events for old
-     * conflicting appear before before events adding new ports
-     */
-    public OrderedCollection<PortChangeEvent>
-            comparePorts(Collection<OFPortDesc> ports);
-
-    /**
-     * Replace the ports of this switch with the given ports.
-     * @param ports new ports to set
-     * @return the ordered collection of changes "applied" to the old ports
-     * of the switch in order to set them to the new set.
-     * If portName <-> portNumber mappings have
-     * changed, the iteration order ensures that delete events for old
-     * conflicting appear before before events adding new ports
-     */
-    public OrderedCollection<PortChangeEvent>
-            setPorts(Collection<OFPortDesc> ports);
-
-    //*******************************************
-    //  IOFSwitch object attributes
-    //************************
-
-    /**
-     * Gets attributes of this switch.
-     *
-     * @return attributes of the switch
-     */
-    public Map<Object, Object> getAttributes();
-
-    /**
-     * Checks if a specific switch property exists for this switch.
-     *
-     * @param name name of property
-     * @return value for name
-     */
-    boolean hasAttribute(String name);
-
-    /**
-     * Gets properties for switch specific behavior.
-     *
-     * @param name name of property
-     * @return 'value' for 'name', or null if no entry for 'name' exists
-     */
-    Object getAttribute(String name);
-
-    /**
-     * Sets properties for switch specific behavior.
-     *
-     * @param name  name of property
-     * @param value value for name
-     */
-    void setAttribute(String name, Object value);
-
-    /**
-     * Removes properties for switch specific behavior.
-     *
-     * @param name name of property
-     * @return current value for name or null (if not present)
-     */
-    Object removeAttribute(String name);
-
-    //************************
-    //  Switch statistics
-    //************************
-
-    /**
-     * Delivers the statistics future reply.
-     *
-     * @param reply the reply to deliver
-     */
-    public void deliverStatisticsReply(OFMessage reply);
-
-    /**
-     * Cancels the statistics reply with the given transaction ID.
-     *
-     * @param transactionId the transaction ID
-     */
-    public void cancelStatisticsReply(int transactionId);
-
-    /**
-     * Cancels all statistics replies.
-     */
-    public void cancelAllStatisticsReplies();
-
-    /**
-     * Gets a Future object that can be used to retrieve the asynchronous.
-     * OFStatisticsReply when it is available.
-     *
-     * @param request statistics request
-     * @return Future object wrapping OFStatisticsReply
-     * @throws IOException
-     */
-    public Future<List<OFStatsReply>> getStatistics(OFStatsRequest<?> request)
-            throws IOException;
-
-    //************************
-    //  Switch other utilities
-    //************************
-
-    /**
-     * Clears all flowmods on this switch.
-     */
-    public void clearAllFlowMods();
-
-    /**
-     * Gets the current role of this controller for this IOFSwitch.
-     */
-    public Role getRole();
-
-    /**
-     * Sets this controller's Role for this IOFSwitch to role.
-     *
-     * @param role
-     */
-    public void setRole(Role role);
-
-    /**
-     * Gets the next generation ID.
-     * <p>
-     * Note: relevant for role request messages in OF1.3
-     *
-     * @return next generation ID
-     */
-    public U64 getNextGenerationId();
-
-
-    /**
-     * Set debug counter service for per-switch counters.
-     * Called immediately after instantiation.
-     * @param debugCounter
-     * @throws CounterException
-     */
-    public void setDebugCounterService(IDebugCounterService debugCounter)
-            throws CounterException;
-
-    /**
-     * Start this switch driver's sub handshake. This might be a no-op but
-     * this method must be called at least once for the switch to be become
-     * ready.
-     * This method must only be called from the I/O thread
-     * @throws IOException
-     * @throws org.onlab.onos.of.controller.impl.internal.SwitchDriverSubHandshakeAlreadyStarted
-     * if the sub-handshake has
-     * already been started
-     */
-    public void startDriverHandshake() throws IOException;
-
-    /**
-     * Check if the sub-handshake for this switch driver has been completed.
-     * This method can only be called after startDriverHandshake()
-     *
-     * This methods must only be called from the I/O thread
-     * @return true if the sub-handshake has been completed. False otherwise
-     * @throws org.onlab.onos.of.controller.impl.internal.SwitchDriverSubHandshakeNotStarted
-     * if startDriverHandshake() has
-     * not been called yet.
-     */
-    public boolean isDriverHandshakeComplete();
-
-    /**
-     * Pass the given OFMessage to the driver as part of this driver's
-     * sub-handshake. Must not be called after the handshake has been completed
-     * This methods must only be called from the I/O thread
-     * @param m The message that the driver should process
-     * @throws org.onlab.onos.of.controller.impl.internal.SwitchDriverSubHandshakeCompleted
-     * if isDriverHandshake() returns
-     * false before this method call
-     * @throws org.onlab.onos.of.controller.impl.internal.SwitchDriverSubHandshakeNotStarted
-     * if startDriverHandshake() has
-     * not been called yet.
-     */
-    public void processDriverHandshakeMessage(OFMessage m);
-
-    /**
-     * Set the flow table full flag in the switch.
-     * XXX S Rethink this for multiple tables
-     */
-    public void setTableFull(boolean isFull);
-
-    /**
-     * Save the features reply for this switch.
-     *
-     * @param featuresReply
-     */
-    public void setFeaturesReply(OFFeaturesReply featuresReply);
-
-    /**
-     * Save the portset for this switch.
-     *
-     * @param portDescReply
-     */
-    public void setPortDescReply(OFPortDescStatsReply portDescReply);
-
-    //************************
-    //  Message handling
-    //************************
-    /**
-     * Handle the message coming from the dataplane.
-     *
-     * @param m the actual message
-     */
-    public void handleMessage(OFMessage m);
-
-
-}
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/Role.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/Role.java
deleted file mode 100644
index 081ea10..0000000
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/Role.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package org.onlab.onos.of.controller.impl;
-
-import org.projectfloodlight.openflow.protocol.OFControllerRole;
-
-/**
- * The role of the controller as it pertains to a particular switch.
- * Note that this definition of the role enum is different from the
- * OF1.3 definition. It is maintained here to be backward compatible to
- * earlier versions of the controller code. This enum is translated
- * to the OF1.3 enum, before role messages are sent to the switch.
- * See sendRoleRequestMessage method in OFSwitchImpl
- */
-public enum Role {
-    EQUAL(OFControllerRole.ROLE_EQUAL),
-    MASTER(OFControllerRole.ROLE_MASTER),
-    SLAVE(OFControllerRole.ROLE_SLAVE);
-
-    private Role(OFControllerRole nxRole) {
-        nxRole.ordinal();
-    }
-    /*
-    private static Map<Integer,Role> nxRoleToEnum
-            = new HashMap<Integer,Role>();
-    static {
-        for(Role r: Role.values())
-            nxRoleToEnum.put(r.toNxRole(), r);
-    }
-    public int toNxRole() {
-        return nxRole;
-    }
-    // Return the enum representing the given nxRole or null if no
-    // such role exists
-    public static Role fromNxRole(int nxRole) {
-        return nxRoleToEnum.get(nxRole);
-    }*/
-}
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/debugcounter/DebugCounter.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/debugcounter/DebugCounter.java
deleted file mode 100644
index f88a43e..0000000
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/debugcounter/DebugCounter.java
+++ /dev/null
@@ -1,727 +0,0 @@
-package org.onlab.onos.of.controller.impl.debugcounter;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicLong;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-import com.google.common.collect.Sets;
-
-
-
-/**
- * This class implements a central store for all counters used for debugging the
- * system. For counters based on traffic-type, see ICounterStoreService.
- *
- */
-//CHECKSTYLE:OFF
-public class DebugCounter implements IDebugCounterService {
-    protected static final Logger log = LoggerFactory.getLogger(DebugCounter.class);
-
-    /**
-     * registered counters need a counter id.
-     */
-    protected AtomicInteger counterIdCounter = new AtomicInteger();
-
-    /**
-     * The counter value.
-     */
-    protected static class MutableLong {
-        long value = 0;
-        public void increment() { value += 1; }
-        public void increment(long incr) { value += incr; }
-        public long get() { return value; }
-        public void set(long val) { value = val; }
-      }
-
-    /**
-     * protected class to store counter information.
-     */
-    public static class CounterInfo {
-        String moduleCounterHierarchy;
-        String counterDesc;
-        CounterType ctype;
-        String moduleName;
-        String counterHierarchy;
-        int counterId;
-        boolean enabled;
-        String[] metaData;
-
-        public CounterInfo(int counterId, boolean enabled,
-                           String moduleName, String counterHierarchy,
-                           String desc, CounterType ctype, String... metaData) {
-            this.moduleCounterHierarchy = moduleName + "/" + counterHierarchy;
-            this.moduleName = moduleName;
-            this.counterHierarchy = counterHierarchy;
-            this.counterDesc = desc;
-            this.ctype = ctype;
-            this.counterId = counterId;
-            this.enabled = enabled;
-            this.metaData = metaData;
-        }
-
-        public String getModuleCounterHierarchy() { return moduleCounterHierarchy; }
-        public String getCounterDesc() { return counterDesc; }
-        public CounterType getCtype() { return ctype; }
-        public String getModuleName() { return moduleName; }
-        public String getCounterHierarchy() { return counterHierarchy; }
-        public int getCounterId() { return counterId; }
-        public boolean isEnabled() { return enabled; }
-        public String[] getMetaData() { return this.metaData.clone(); }
-    }
-
-    //******************
-    //   Global stores
-    //******************
-
-    /**
-     * Counter info for a debug counter.
-     */
-    public static class DebugCounterInfo {
-        CounterInfo cinfo;
-        AtomicLong cvalue;
-
-        public DebugCounterInfo(CounterInfo cinfo) {
-            this.cinfo = cinfo;
-            this.cvalue = new AtomicLong();
-        }
-        public CounterInfo getCounterInfo() {
-            return cinfo;
-        }
-        public Long getCounterValue() {
-            return cvalue.get();
-        }
-    }
-
-    /**
-     * Global debug-counter storage across all threads. These are
-     * updated from the local per thread counters by the flush counters method.
-     */
-    private static final DebugCounterInfo[] ALLCOUNTERS =
-                            new DebugCounterInfo[MAX_COUNTERS];
-
-
-    /**
-     * per module counters, indexed by the module name and storing three levels
-     * of Counter information in the form of CounterIndexStore.
-     */
-    protected ConcurrentHashMap<String, ConcurrentHashMap<String, CounterIndexStore>>
-        moduleCounters = new ConcurrentHashMap<String,
-                                                ConcurrentHashMap<String,
-                                                                   CounterIndexStore>>();
-
-    protected static class CounterIndexStore {
-        int index;
-        Map<String, CounterIndexStore> nextLevel;
-
-        public CounterIndexStore(int index, Map<String, CounterIndexStore> cis) {
-            this.index = index;
-            this.nextLevel = cis;
-        }
-    }
-
-    /**
-     * fast global cache for counter ids that are currently active.
-     */
-    protected Set<Integer> currentCounters = Collections.newSetFromMap(
-                                         new ConcurrentHashMap<Integer, Boolean>());
-
-    //******************
-    // Thread local stores
-    //******************
-
-    /**
-     * Thread local storage of counter info.
-     */
-    protected static class LocalCounterInfo {
-        boolean enabled;
-        MutableLong cvalue;
-
-        public LocalCounterInfo(boolean enabled) {
-            this.enabled = enabled;
-            this.cvalue = new MutableLong();
-        }
-    }
-
-    /**
-     * Thread local debug counters used for maintaining counters local to a thread.
-     */
-    protected final ThreadLocal<LocalCounterInfo[]> threadlocalCounters =
-            new ThreadLocal<LocalCounterInfo[]>() {
-        @Override
-        protected LocalCounterInfo[] initialValue() {
-            return new LocalCounterInfo[MAX_COUNTERS];
-        }
-    };
-
-    /**
-     * Thread local cache for counter ids that are currently active.
-     */
-    protected final ThreadLocal<Set<Integer>> threadlocalCurrentCounters =
-            new ThreadLocal<Set<Integer>>() {
-        @Override
-        protected Set<Integer> initialValue() {
-            return new HashSet<Integer>();
-        }
-    };
-
-    //*******************************
-    //   IDebugCounter
-    //*******************************
-
-    protected class CounterImpl implements IDebugCounter {
-        private final int counterId;
-
-        public CounterImpl(int counterId) {
-            this.counterId = counterId;
-        }
-
-        @Override
-        public void updateCounterWithFlush() {
-            if (!validCounterId()) {
-                return;
-            }
-            updateCounter(counterId, 1, true);
-        }
-
-        @Override
-        public void updateCounterNoFlush() {
-            if (!validCounterId()) {
-                return;
-            }
-            updateCounter(counterId, 1, false);
-        }
-
-        @Override
-        public void updateCounterWithFlush(int incr) {
-            if (!validCounterId()) {
-                return;
-            }
-            updateCounter(counterId, incr, true);
-        }
-
-        @Override
-        public void updateCounterNoFlush(int incr) {
-            if (!validCounterId()) {
-                return;
-            }
-            updateCounter(counterId, incr, false);
-        }
-
-        @Override
-        public long getCounterValue() {
-            if (!validCounterId()) {
-                return -1;
-            }
-            return ALLCOUNTERS[counterId].cvalue.get();
-        }
-
-        /**
-         * Checks if this is a valid counter.
-         * @return true if the counter id is valid
-         */
-        private boolean validCounterId() {
-            if (counterId < 0 || counterId >= MAX_COUNTERS) {
-                log.error("Invalid counterId invoked");
-                return false;
-            }
-            return true;
-        }
-
-    }
-
-   //*******************************
-   //   IDebugCounterService
-   //*******************************
-
-   @Override
-   public IDebugCounter registerCounter(String moduleName, String counterHierarchy,
-                           String counterDescription, CounterType counterType,
-                           String... metaData)
-               throws CounterException {
-       // check if counter already exists
-       if (!moduleCounters.containsKey(moduleName)) {
-           moduleCounters.putIfAbsent(moduleName,
-                new ConcurrentHashMap<String, CounterIndexStore>());
-       }
-       RetCtrInfo rci = getCounterId(moduleName, counterHierarchy);
-       if (rci.allLevelsFound) {
-           // counter exists
-           log.info("Counter exists for {}/{} -- resetting counters", moduleName,
-                    counterHierarchy);
-           resetCounterHierarchy(moduleName, counterHierarchy);
-           return new CounterImpl(rci.ctrIds[rci.foundUptoLevel - 1]);
-       }
-       // check for validity of counter
-       if (rci.levels.length > MAX_HIERARCHY) {
-           String err = "Registry of counterHierarchy " + counterHierarchy +
-                   " exceeds max hierachy " + MAX_HIERARCHY + ".. aborting";
-           throw new MaxHierarchyRegistered(err);
-       }
-       if (rci.foundUptoLevel < rci.levels.length - 1) {
-           StringBuilder sb = new StringBuilder();
-           for (int i = 0; i <= rci.foundUptoLevel; i++) {
-               sb.append(rci.levels[i]);
-           }
-           String needToRegister = sb.toString();
-           String err = "Attempting to register hierarchical counterHierarchy " +
-                   counterHierarchy + " but parts of hierarchy missing. " +
-                   "Please register " +  needToRegister + " first";
-           throw new MissingHierarchicalLevel(err);
-       }
-
-       // get a new counter id
-       int counterId = counterIdCounter.getAndIncrement();
-       if (counterId >= MAX_COUNTERS) {
-           throw new MaxCountersRegistered("max counters reached");
-       }
-       // create storage for counter
-       boolean enabled = (counterType == CounterType.ALWAYS_COUNT) ? true : false;
-       CounterInfo ci = new CounterInfo(counterId, enabled, moduleName,
-                                        counterHierarchy, counterDescription,
-                                        counterType, metaData);
-       ALLCOUNTERS[counterId] = new DebugCounterInfo(ci);
-
-       // account for the new counter in the module counter hierarchy
-       addToModuleCounterHierarchy(moduleName, counterId, rci);
-
-       // finally add to active counters
-       if (enabled) {
-           currentCounters.add(counterId);
-       }
-       return new CounterImpl(counterId);
-   }
-
-   private void updateCounter(int counterId, int incr, boolean flushNow) {
-       if (counterId < 0 || counterId >= MAX_COUNTERS) {
-        return;
-    }
-
-       LocalCounterInfo[] thiscounters =  this.threadlocalCounters.get();
-       if (thiscounters[counterId] == null) {
-           // seeing this counter for the first time in this thread - create local
-           // store by consulting global store
-           DebugCounterInfo dc = ALLCOUNTERS[counterId];
-           if (dc != null) {
-               thiscounters[counterId] = new LocalCounterInfo(dc.cinfo.enabled);
-               if (dc.cinfo.enabled) {
-                   Set<Integer> thisset = this.threadlocalCurrentCounters.get();
-                   thisset.add(counterId);
-               }
-           } else {
-               log.error("updateCounter seen locally for counter {} but no global"
-                          + "storage exists for it yet .. not updating", counterId);
-               return;
-           }
-       }
-
-       // update local store if enabled locally for updating
-       LocalCounterInfo lc = thiscounters[counterId];
-       if (lc.enabled) {
-           lc.cvalue.increment(incr);
-           if (flushNow) {
-               DebugCounterInfo dc = ALLCOUNTERS[counterId];
-               if (dc.cinfo.enabled) {
-                   // globally enabled - flush now
-                   dc.cvalue.addAndGet(lc.cvalue.get());
-                   lc.cvalue.set(0);
-               } else {
-                   // global counter is disabled - don't flush, disable locally
-                   lc.enabled = false;
-                   Set<Integer> thisset = this.threadlocalCurrentCounters.get();
-                   thisset.remove(counterId);
-               }
-           }
-       }
-   }
-
-   @Override
-   public void flushCounters() {
-       LocalCounterInfo[] thiscounters =  this.threadlocalCounters.get();
-       Set<Integer> thisset = this.threadlocalCurrentCounters.get();
-       ArrayList<Integer> temp = new ArrayList<Integer>();
-
-       for (int counterId : thisset) {
-           LocalCounterInfo lc = thiscounters[counterId];
-           if (lc.cvalue.get() > 0) {
-               DebugCounterInfo dc = ALLCOUNTERS[counterId];
-               if (dc.cinfo.enabled) {
-                   // globally enabled - flush now
-                   dc.cvalue.addAndGet(lc.cvalue.get());
-                   lc.cvalue.set(0);
-               } else {
-                   // global counter is disabled - don't flush, disable locally
-                   lc.enabled = false;
-                   temp.add(counterId);
-               }
-           }
-       }
-       for (int cId : temp) {
-           thisset.remove(cId);
-       }
-
-       // At this point it is possible that the thread-local set does not
-       // include a counter that has been enabled and is present in the global set.
-       // We need to sync thread-local currently enabled set of counterIds with
-       // the global set.
-       Sets.SetView<Integer> sv = Sets.difference(currentCounters, thisset);
-       for (int counterId : sv) {
-           if (thiscounters[counterId] != null) {
-               thiscounters[counterId].enabled = true;
-               thisset.add(counterId);
-           }
-       }
-   }
-
-   @Override
-   public void resetCounterHierarchy(String moduleName, String counterHierarchy) {
-       RetCtrInfo rci = getCounterId(moduleName, counterHierarchy);
-       if (!rci.allLevelsFound) {
-           String missing = rci.levels[rci.foundUptoLevel];
-           log.error("Cannot reset counter hierarchy - missing counter {}", missing);
-           return;
-       }
-       // reset at this level
-       ALLCOUNTERS[rci.ctrIds[rci.foundUptoLevel - 1]].cvalue.set(0);
-       // reset all levels below
-       ArrayList<Integer> resetIds = getHierarchyBelow(moduleName, rci);
-       for (int index : resetIds) {
-           ALLCOUNTERS[index].cvalue.set(0);
-       }
-   }
-
-   @Override
-   public void resetAllCounters() {
-       RetCtrInfo rci = new RetCtrInfo();
-       rci.levels = "".split("/");
-       for (String moduleName : moduleCounters.keySet()) {
-           ArrayList<Integer> resetIds = getHierarchyBelow(moduleName, rci);
-           for (int index : resetIds) {
-               ALLCOUNTERS[index].cvalue.set(0);
-           }
-       }
-   }
-
-   @Override
-   public void resetAllModuleCounters(String moduleName) {
-       Map<String, CounterIndexStore> target = moduleCounters.get(moduleName);
-       RetCtrInfo rci = new RetCtrInfo();
-       rci.levels = "".split("/");
-
-       if (target != null) {
-           ArrayList<Integer> resetIds = getHierarchyBelow(moduleName, rci);
-           for (int index : resetIds) {
-               ALLCOUNTERS[index].cvalue.set(0);
-           }
-       } else {
-           if (log.isDebugEnabled()) {
-            log.debug("No module found with name {}", moduleName);
-        }
-       }
-   }
-
-   @Override
-   public void enableCtrOnDemand(String moduleName, String counterHierarchy) {
-       RetCtrInfo rci = getCounterId(moduleName, counterHierarchy);
-       if (!rci.allLevelsFound) {
-           String missing = rci.levels[rci.foundUptoLevel];
-           log.error("Cannot enable counter - counter not found {}", missing);
-           return;
-       }
-       // enable specific counter
-       DebugCounterInfo dc = ALLCOUNTERS[rci.ctrIds[rci.foundUptoLevel - 1]];
-       dc.cinfo.enabled = true;
-       currentCounters.add(dc.cinfo.counterId);
-   }
-
-   @Override
-   public void disableCtrOnDemand(String moduleName, String counterHierarchy) {
-       RetCtrInfo rci = getCounterId(moduleName, counterHierarchy);
-       if (!rci.allLevelsFound) {
-           String missing = rci.levels[rci.foundUptoLevel];
-           log.error("Cannot disable counter - counter not found {}", missing);
-           return;
-       }
-       // disable specific counter
-       DebugCounterInfo dc = ALLCOUNTERS[rci.ctrIds[rci.foundUptoLevel - 1]];
-       if (dc.cinfo.ctype == CounterType.COUNT_ON_DEMAND) {
-           dc.cinfo.enabled = false;
-           dc.cvalue.set(0);
-           currentCounters.remove(dc.cinfo.counterId);
-       }
-   }
-
-   @Override
-   public List<DebugCounterInfo> getCounterHierarchy(String moduleName,
-                                                     String counterHierarchy) {
-       RetCtrInfo rci = getCounterId(moduleName, counterHierarchy);
-       if (!rci.allLevelsFound) {
-           String missing = rci.levels[rci.foundUptoLevel];
-           log.error("Cannot fetch counter - counter not found {}", missing);
-           return Collections.emptyList();
-       }
-       ArrayList<DebugCounterInfo> dcilist = new ArrayList<DebugCounterInfo>();
-       // get counter and all below it
-       DebugCounterInfo dc = ALLCOUNTERS[rci.ctrIds[rci.foundUptoLevel - 1]];
-       dcilist.add(dc);
-       ArrayList<Integer> belowIds = getHierarchyBelow(moduleName, rci);
-       for (int index : belowIds) {
-           dcilist.add(ALLCOUNTERS[index]);
-       }
-       return dcilist;
-   }
-
-   @Override
-   public List<DebugCounterInfo> getAllCounterValues() {
-       List<DebugCounterInfo> dcilist = new ArrayList<DebugCounterInfo>();
-       RetCtrInfo rci = new RetCtrInfo();
-       rci.levels = "".split("/");
-
-       for (String moduleName : moduleCounters.keySet()) {
-           ArrayList<Integer> resetIds = getHierarchyBelow(moduleName, rci);
-           for (int index : resetIds) {
-               dcilist.add(ALLCOUNTERS[index]);
-           }
-       }
-       return dcilist;
-   }
-
-   @Override
-   public List<DebugCounterInfo> getModuleCounterValues(String moduleName) {
-       List<DebugCounterInfo> dcilist = new ArrayList<DebugCounterInfo>();
-       RetCtrInfo rci = new RetCtrInfo();
-       rci.levels = "".split("/");
-
-       if (moduleCounters.containsKey(moduleName)) {
-           ArrayList<Integer> resetIds = getHierarchyBelow(moduleName, rci);
-           for (int index : resetIds) {
-               dcilist.add(ALLCOUNTERS[index]);
-           }
-       }
-       return dcilist;
-   }
-
-   @Override
-   public boolean containsModuleCounterHierarchy(String moduleName,
-                                                 String counterHierarchy) {
-       if (!moduleCounters.containsKey(moduleName)) {
-        return false;
-    }
-       RetCtrInfo rci = getCounterId(moduleName, counterHierarchy);
-       return rci.allLevelsFound;
-   }
-
-   @Override
-   public boolean containsModuleName(String moduleName) {
-       return  (moduleCounters.containsKey(moduleName)) ? true : false;
-   }
-
-   @Override
-   public List<String> getModuleList() {
-       List<String> retval = new ArrayList<String>();
-       retval.addAll(moduleCounters.keySet());
-       return retval;
-   }
-
-   @Override
-   public List<String> getModuleCounterList(String moduleName) {
-       if (!moduleCounters.containsKey(moduleName)) {
-        return Collections.emptyList();
-    }
-
-       List<String> retval = new ArrayList<String>();
-       RetCtrInfo rci = new RetCtrInfo();
-       rci.levels = "".split("/");
-
-       ArrayList<Integer> cids = getHierarchyBelow(moduleName, rci);
-       for (int index : cids) {
-           retval.add(ALLCOUNTERS[index].cinfo.counterHierarchy);
-       }
-       return retval;
-   }
-
-   //*******************************
-   //   Internal Methods
-   //*******************************
-
-   protected class RetCtrInfo {
-       boolean allLevelsFound; // counter indices found all the way down the hierarchy
-       boolean hierarchical; // true if counterHierarchy is hierarchical
-       int foundUptoLevel;
-       int[]  ctrIds;
-       String[] levels;
-
-       public RetCtrInfo() {
-           ctrIds = new int[MAX_HIERARCHY];
-           for (int i = 0; i < MAX_HIERARCHY; i++) {
-               ctrIds[i] = -1;
-           }
-       }
-
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + getOuterType().hashCode();
-        result = prime * result + (allLevelsFound ? 1231 : 1237);
-        result = prime * result + Arrays.hashCode(ctrIds);
-        result = prime * result + foundUptoLevel;
-        result = prime * result + (hierarchical ? 1231 : 1237);
-        result = prime * result + Arrays.hashCode(levels);
-        return result;
-    }
-
-    @Override
-    public boolean equals(Object oth) {
-        if (!(oth instanceof RetCtrInfo)) {
-         return false;
-     }
-        RetCtrInfo other = (RetCtrInfo) oth;
-        if (other.allLevelsFound != this.allLevelsFound) {
-         return false;
-     }
-        if (other.hierarchical != this.hierarchical) {
-         return false;
-     }
-        if (other.foundUptoLevel != this.foundUptoLevel) {
-         return false;
-     }
-        if (!Arrays.equals(other.ctrIds, this.ctrIds)) {
-         return false;
-     }
-        if (!Arrays.equals(other.levels, this.levels)) {
-         return false;
-     }
-        return true;
-    }
-
-    private DebugCounter getOuterType() {
-        return DebugCounter.this;
-    }
-
-
-
-   }
-
-   protected RetCtrInfo getCounterId(String moduleName, String counterHierarchy) {
-       RetCtrInfo rci = new RetCtrInfo();
-       Map<String, CounterIndexStore> templevel = moduleCounters.get(moduleName);
-       rci.levels = counterHierarchy.split("/");
-       if (rci.levels.length > 1) {
-        rci.hierarchical = true;
-    }
-       if (templevel == null) {
-           log.error("moduleName {} does not exist in debugCounters", moduleName);
-           return rci;
-       }
-
-       /*
-       if (rci.levels.length > MAX_HIERARCHY) {
-           // chop off all array elems greater that MAX_HIERARCHY
-           String[] temp = new String[MAX_HIERARCHY];
-           System.arraycopy(rci.levels, 0, temp, 0, MAX_HIERARCHY);
-           rci.levels = temp;
-       }
-       */
-       for (int i = 0; i < rci.levels.length; i++) {
-           if (templevel != null) {
-               CounterIndexStore cis = templevel.get(rci.levels[i]);
-               if (cis == null) {
-                   // could not find counterHierarchy part at this level
-                   break;
-               } else {
-                   rci.ctrIds[i] = cis.index;
-                   templevel = cis.nextLevel;
-                   rci.foundUptoLevel++;
-                   if (i == rci.levels.length - 1) {
-                       rci.allLevelsFound = true;
-                   }
-               }
-           } else {
-               // there are no more levels, which means that some part of the
-               // counterHierarchy has no corresponding map
-               break;
-           }
-       }
-       return rci;
-   }
-
-   protected void addToModuleCounterHierarchy(String moduleName, int counterId,
-                                            RetCtrInfo rci) {
-       Map<String, CounterIndexStore> target = moduleCounters.get(moduleName);
-       if (target == null) {
-        return;
-    }
-       CounterIndexStore cis = null;
-
-       for (int i = 0; i < rci.foundUptoLevel; i++) {
-           cis = target.get(rci.levels[i]);
-           target = cis.nextLevel;
-       }
-       if (cis != null) {
-           if (cis.nextLevel == null) {
-            cis.nextLevel = new ConcurrentHashMap<String, CounterIndexStore>();
-        }
-           cis.nextLevel.put(rci.levels[rci.foundUptoLevel],
-                             new CounterIndexStore(counterId, null));
-       } else {
-           target.put(rci.levels[rci.foundUptoLevel],
-                      new CounterIndexStore(counterId, null));
-       }
-   }
-
-   // given a partial hierarchical counter, return the rest of the hierarchy
-   protected ArrayList<Integer> getHierarchyBelow(String moduleName, RetCtrInfo rci) {
-       Map<String, CounterIndexStore> target = moduleCounters.get(moduleName);
-       CounterIndexStore cis = null;
-       ArrayList<Integer> retval = new ArrayList<Integer>();
-       if (target == null) {
-        return retval;
-    }
-
-       // get to the level given
-       for (int i = 0; i < rci.foundUptoLevel; i++) {
-           cis = target.get(rci.levels[i]);
-           target = cis.nextLevel;
-       }
-
-       if (target == null || rci.foundUptoLevel == MAX_HIERARCHY) {
-           // no more levels
-           return retval;
-       } else {
-           // recursively get all ids
-           getIdsAtLevel(target, retval, rci.foundUptoLevel + 1);
-       }
-
-       return retval;
-   }
-
-   protected void getIdsAtLevel(Map<String, CounterIndexStore> hcy,
-                                ArrayList<Integer> retval, int level) {
-       if (level > MAX_HIERARCHY) {
-        return;
-    }
-       if (hcy == null || retval == null) {
-        return;
-    }
-
-       // Can return the counter names as well but for now ids are enough.
-       for (CounterIndexStore cistemp : hcy.values()) {
-           retval.add(cistemp.index); // value at this level
-           if (cistemp.nextLevel != null) {
-               getIdsAtLevel(cistemp.nextLevel, retval, level + 1);
-           }
-       }
-   }
-
-}
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/debugcounter/IDebugCounter.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/debugcounter/IDebugCounter.java
deleted file mode 100644
index 2dc0c0a..0000000
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/debugcounter/IDebugCounter.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package org.onlab.onos.of.controller.impl.debugcounter;
-
-public interface IDebugCounter {
-    /**
-     * Increments the counter by 1 thread-locally, and immediately flushes to
-     * the global counter storage. This method should be used for counters that
-     * are updated outside the OF message processing pipeline.
-     */
-    void updateCounterWithFlush();
-
-    /**
-     * Increments the counter by 1 thread-locally. Flushing to the global
-     * counter storage is delayed (happens with flushCounters() in IDebugCounterService),
-     * resulting in higher performance. This method should be used for counters
-     * updated in the OF message processing pipeline.
-     */
-    void updateCounterNoFlush();
-
-    /**
-     * Increments the counter thread-locally by the 'incr' specified, and immediately
-     * flushes to the global counter storage. This method should be used for counters
-     * that are updated outside the OF message processing pipeline.
-     */
-    void updateCounterWithFlush(int incr);
-
-    /**
-     * Increments the counter thread-locally by the 'incr' specified. Flushing to the global
-     * counter storage is delayed (happens with flushCounters() in IDebugCounterService),
-     * resulting in higher performance. This method should be used for counters
-     * updated in the OF message processing pipeline.
-     */
-    void updateCounterNoFlush(int incr);
-
-    /**
-     * Retrieve the value of the counter from the global counter store.
-     */
-    long getCounterValue();
-}
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/debugcounter/IDebugCounterService.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/debugcounter/IDebugCounterService.java
deleted file mode 100644
index 216ee74..0000000
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/debugcounter/IDebugCounterService.java
+++ /dev/null
@@ -1,262 +0,0 @@
-package org.onlab.onos.of.controller.impl.debugcounter;
-
-
-
-import java.util.List;
-
-import org.onlab.onos.of.controller.impl.debugcounter.DebugCounter.DebugCounterInfo;
-
-//CHECKSTYLE:OFF
-public interface IDebugCounterService {
-
-    /**
-     * 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
-    }
-
-    /**
-     * Debug Counter Qualifiers.
-     */
-    public static final String CTR_MDATA_WARN = "warn";
-    public static final String CTR_MDATA_ERROR = "error";
-    public static final String CTR_MDATA_DROP = "drop";
-
-    /**
-     *  A limit on the maximum number of counters that can be created.
-     */
-    public static final int MAX_COUNTERS = 5000;
-
-    /**
-     * Exception thrown when MAX_COUNTERS have been registered.
-     */
-    public class MaxCountersRegistered extends CounterException {
-        private static final long serialVersionUID = 3173747663719376745L;
-        String errormsg;
-        public MaxCountersRegistered(String errormsg) {
-            this.errormsg = errormsg;
-        }
-        @Override
-        public String getMessage() {
-            return this.errormsg;
-        }
-    }
-    /**
-     * Exception thrown when MAX_HIERARCHY has been reached.
-     */
-    public class MaxHierarchyRegistered extends CounterException {
-        private static final long serialVersionUID = 967431358683523871L;
-        private String errormsg;
-        public MaxHierarchyRegistered(String errormsg) {
-            this.errormsg = errormsg;
-        }
-        @Override
-        public String getMessage() {
-            return this.errormsg;
-        }
-    }
-    /**
-     * Exception thrown when attempting to register a hierarchical counter
-     * where higher levels of the hierarchy have not been pre-registered.
-     */
-    public class MissingHierarchicalLevel extends CounterException {
-        private static final long serialVersionUID = 517315311533995739L;
-        private String errormsg;
-        public MissingHierarchicalLevel(String errormsg) {
-            this.errormsg = errormsg;
-        }
-        @Override
-        public String getMessage() {
-            return this.errormsg;
-        }
-    }
-
-    public class CounterException extends Exception {
-        private static final long serialVersionUID = 2219781500857866035L;
-    }
-
-    /**
-     *  maximum levels of hierarchy.
-     *  Example of moduleName/counterHierarchy:
-     *           switch/00:00:00:00:01:02:03:04/pktin/drops where
-     *           moduleName ==> "switch"  and
-     *           counterHierarchy of 3 ==> "00:00:00:00:01:02:03:04/pktin/drops"
-     */
-    public static final int MAX_HIERARCHY = 3;
-
-    /**
-     * 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 moduleName and counterHierarchy.
-     *
-     * @param moduleName           the name of the module which is registering the
-     *                             counter eg. linkdiscovery or controller or switch
-     * @param counterHierarchy     the hierarchical counter name specifying all
-     *                             the hierarchical levels that come above it.
-     *                             For example: to register a drop counter for
-     *                             packet-ins from a switch, the counterHierarchy
-     *                             can be "00:00:00:00:01:02:03:04/pktin/drops"
-     *                             It is necessary that counters in hierarchical levels
-     *                             above have already been pre-registered - in this
-     *                             example: "00:00:00:00:01:02:03:04/pktin" and
-     *                             "00:00:00:00:01:02:03:04"
-     * @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. 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.
-     * @param metaData             variable arguments that qualify a counter
-     *                             eg. warn, error etc.
-     * @return                     IDebugCounter with update methods that can be
-     *                             used to update a counter.
-     * @throws MaxCountersRegistered
-     * @throws MaxHierarchyRegistered
-     * @throws MissingHierarchicalLevel
-     */
-    public IDebugCounter registerCounter(String moduleName, String counterHierarchy,
-                             String counterDescription, CounterType counterType,
-                             String... metaData)
-                throws CounterException;
-
-    /**
-     * Flush all thread-local counter values (from the current thread)
-     * to the global counter store. This method is not intended for use by any
-     * module. It's typical usage is from core and it is meant
-     * to flush those counters that are updated in the packet-processing pipeline,
-     * typically with the 'updateCounterNoFlush" methods in IDebugCounter.
-     */
-    public void flushCounters();
-
-    /**
-     * Resets the value of counters in the hierarchy to zero. Note that the reset
-     * applies to the level of counter hierarchy specified AND ALL LEVELS BELOW it
-     * in the hierarchy.
-     * For example: If a hierarchy exists like "00:00:00:00:01:02:03:04/pktin/drops"
-     *              specifying a reset hierarchy: "00:00:00:00:01:02:03:04"
-     *              will reset all counters for the switch dpid specified;
-     *              while specifying a reset hierarchy: ""00:00:00:00:01:02:03:04/pktin"
-     *              will reset the pktin counter and all levels below it (like drops)
-     *              for the switch dpid specified.
-     */
-    void resetCounterHierarchy(String moduleName, String counterHierarchy);
-
-    /**
-     * Resets the values of all counters in the system.
-     */
-    public void resetAllCounters();
-
-    /**
-     * Resets the values of all counters belonging
-     * to a module with the given '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). Newly
-     * enabled counters start from an initial value of zero.
-     *
-     * Enabling a counter in a counterHierarchy enables only THAT counter. It
-     * does not enable any other part of the counterHierarchy. For example, if
-     * a hierarchy exists like "00:00:00:00:01:02:03:04/pktin/drops", where the
-     * 'pktin' and 'drops' counters are CounterType.COUNT_ON_DEMAND, then enabling
-     * the 'pktin' counter by specifying the counterHierarchy as
-     * "00:00:00:00:01:02:03:04/pktin" does NOT enable the 'drops' counter.
-     */
-    public void enableCtrOnDemand(String moduleName, String counterHierarchy);
-
-    /**
-     * This method applies only to CounterType.COUNT_ON_DEMAND. It is used to
-     * enable counting on the counter. Note that disabling a counter results in a loss
-     * of the counter value. When re-enabled the counter will restart from zero.
-     *
-     * Disabling a counter in a counterHierarchy disables only THAT counter. It
-     * does not disable any other part of the counterHierarchy. For example, if
-     * a hierarchy exists like "00:00:00:00:01:02:03:04/pktin/drops", where the
-     * 'pktin' and 'drops' counters are CounterType.COUNT_ON_DEMAND, then disabling
-     * the 'pktin' counter by specifying the counterHierarchy as
-     * "00:00:00:00:01:02:03:04/pktin" does NOT disable the 'drops' counter.
-     */
-    public void disableCtrOnDemand(String moduleName, String counterHierarchy);
-
-    /**
-     * Get counter value and associated information for the specified counterHierarchy.
-     * Note that information on the level of counter hierarchy specified
-     * AND ALL LEVELS BELOW it in the hierarchy will be returned.
-     *
-     * For example,
-     * if a hierarchy exists like "00:00:00:00:01:02:03:04/pktin/drops", then
-     * specifying a counterHierarchy of "00:00:00:00:01:02:03:04/pktin" in the
-     * get call will return information on the 'pktin' as well as the 'drops'
-     * counters for the switch dpid specified.
-     *
-     * @return A list of DebugCounterInfo or an empty list if the counter
-     *         could not be found
-     */
-    public List<DebugCounterInfo> getCounterHierarchy(String moduleName,
-                                                      String counterHierarchy);
-
-    /**
-     * Get counter values and associated information for all counters in the
-     * system.
-     *
-     * @return the list of values/info or an empty list
-     */
-    public  List<DebugCounterInfo> getAllCounterValues();
-
-    /**
-     * Get counter values and associated information for all 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 'counterHierarchy' corresponds
-     * to a registered counterHierarchy for 'moduleName'. Note that the counter may or
-     * may not be enabled for counting, but if it is registered the method will
-     * return true.
-     *
-     * @param moduleName
-     * @param counterHierarchy
-     * @return false if moduleCounterHierarchy is not a registered counter
-     */
-    public boolean containsModuleCounterHierarchy(String moduleName,
-                                                  String counterHierarchy);
-
-    /**
-     * 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 moduleName
-     * @return false if moduleName is not a registered counter
-     */
-    public boolean containsModuleName(String moduleName);
-
-    /**
-     * Returns a list of moduleNames registered for debug counters or an empty
-     * list if no counters have been registered in the system.
-     */
-    public List<String> getModuleList();
-
-    /**
-     * Returns a list of all counters registered for a specific moduleName
-     * or a empty list.
-     */
-    public List<String> getModuleCounterList(String moduleName);
-
-
-}
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/debugcounter/NullDebugCounter.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/debugcounter/NullDebugCounter.java
deleted file mode 100644
index ae476ea..0000000
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/debugcounter/NullDebugCounter.java
+++ /dev/null
@@ -1,117 +0,0 @@
-package org.onlab.onos.of.controller.impl.debugcounter;
-
-import java.util.Collections;
-import java.util.List;
-
-import org.onlab.onos.of.controller.impl.debugcounter.DebugCounter.DebugCounterInfo;
-
-//CHECKSTYLE:OFF
-public class NullDebugCounter implements IDebugCounterService {
-
-    @Override
-    public void flushCounters() {
-
-    }
-
-    @Override
-    public void resetAllCounters() {
-
-    }
-
-    @Override
-    public void resetAllModuleCounters(String moduleName) {
-
-    }
-
-
-    @Override
-    public void resetCounterHierarchy(String moduleName, String counterHierarchy) {
-
-    }
-
-    @Override
-    public void enableCtrOnDemand(String moduleName, String counterHierarchy) {
-
-    }
-
-    @Override
-    public void disableCtrOnDemand(String moduleName, String counterHierarchy) {
-
-    }
-
-    @Override
-    public List<DebugCounterInfo> getCounterHierarchy(String moduleName,
-                                                      String counterHierarchy) {
-        return Collections.emptyList();
-    }
-
-    @Override
-    public List<DebugCounterInfo> getAllCounterValues() {
-        return Collections.emptyList();
-    }
-
-    @Override
-    public List<DebugCounterInfo> getModuleCounterValues(String moduleName) {
-        return Collections.emptyList();
-    }
-
-    @Override
-    public boolean containsModuleCounterHierarchy(String moduleName,
-                                             String counterHierarchy) {
-        return false;
-    }
-
-    @Override
-    public boolean containsModuleName(String moduleName) {
-        return false;
-    }
-
-    @Override
-    public
-            IDebugCounter
-            registerCounter(String moduleName, String counterHierarchy,
-                            String counterDescription,
-                            CounterType counterType, String... metaData)
-                                 throws MaxCountersRegistered {
-        return new NullCounterImpl();
-    }
-
-    @Override
-    public List<String> getModuleList() {
-        return Collections.emptyList();
-    }
-
-    @Override
-    public List<String> getModuleCounterList(String moduleName) {
-        return Collections.emptyList();
-    }
-
-    public static class NullCounterImpl implements IDebugCounter {
-
-        @Override
-        public void updateCounterWithFlush() {
-
-        }
-
-        @Override
-        public void updateCounterNoFlush() {
-
-        }
-
-        @Override
-        public void updateCounterWithFlush(int incr) {
-        }
-
-        @Override
-        public void updateCounterNoFlush(int incr) {
-
-        }
-
-        @Override
-        public long getCounterValue() {
-            return -1;
-        }
-
-    }
-
-}
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/AbstractOpenFlowSwitch.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/AbstractOpenFlowSwitch.java
new file mode 100644
index 0000000..7f4830d
--- /dev/null
+++ b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/AbstractOpenFlowSwitch.java
@@ -0,0 +1,279 @@
+/**
+ *    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 org.onlab.onos.of.controller.impl.internal;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.jboss.netty.channel.Channel;
+import org.onlab.onos.of.controller.Dpid;
+import org.onlab.onos.of.controller.OpenFlowSwitch;
+import org.onlab.onos.of.controller.RoleState;
+import org.onlab.onos.of.controller.impl.internal.OpenFlowControllerImpl.OpenFlowSwitchAgent;
+import org.onlab.onos.of.controller.impl.internal.RoleManager.RoleRecvStatus;
+import org.onlab.onos.of.controller.impl.internal.RoleManager.RoleReplyInfo;
+import org.projectfloodlight.openflow.protocol.OFErrorMsg;
+import org.projectfloodlight.openflow.protocol.OFExperimenter;
+import org.projectfloodlight.openflow.protocol.OFFactories;
+import org.projectfloodlight.openflow.protocol.OFFactory;
+import org.projectfloodlight.openflow.protocol.OFFeaturesReply;
+import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply;
+import org.projectfloodlight.openflow.protocol.OFRoleReply;
+import org.projectfloodlight.openflow.protocol.OFVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitch {
+
+    private static Logger log =
+            LoggerFactory.getLogger(AbstractOpenFlowSwitch.class);
+
+    private Channel channel;
+    private boolean connected;
+    private Dpid dpid;
+    private OpenFlowSwitchAgent agent;
+
+    private OFVersion ofVersion;
+
+    protected OFPortDescStatsReply ports;
+
+    protected boolean tableFull;
+
+    private final RoleManager roleMan = new RoleManager(this);
+
+    protected AbstractOpenFlowSwitch(long dpid) {
+        this.dpid = new Dpid(dpid);
+    }
+
+    //************************
+    // Channel related
+    //************************
+
+    /**
+     * Disconnects the switch by closing the TCP connection. Results in a call
+     * to the channel handler's channelDisconnected method for cleanup
+     * @throws IOException
+     */
+    public final void disconnectSwitch() {
+        this.channel.close();
+    }
+
+    /**
+     * Writes to the OFMessage to the output stream.
+     *
+     * @param m the message to be written
+     */
+    public abstract void write(OFMessage m);
+
+    /**
+     * Writes to the OFMessage list to the output stream.
+     *
+     * @param msgs the messages to be written
+     */
+    public abstract void write(List<OFMessage> msgs);
+
+
+    /**
+     * Checks if the switch is still connected.
+     * Only call while holding processMessageLock
+     *
+     * @return whether the switch is still disconnected
+     */
+    public final boolean isConnected() {
+        return this.connected;
+    }
+
+    /**
+     * Sets whether the switch is connected.
+     * Only call while holding modifySwitchLock
+     *
+     * @param connected whether the switch is connected
+     */
+    final void setConnected(boolean connected) {
+        this.connected = connected;
+    };
+
+    /**
+     * Sets the Netty Channel this switch instance is associated with.
+     * <p>
+     * Called immediately after instantiation
+     *
+     * @param channel the channel
+     */
+    public final void setChannel(Channel channel) {
+        this.channel = channel;
+    };
+
+    //************************
+    // Switch features related
+    //************************
+
+    /**
+     * Gets the datapathId of the switch.
+     *
+     * @return the switch buffers
+     */
+    public final long getId() {
+        return this.dpid.value();
+    };
+
+    /**
+     * Gets a string version of the ID for this switch.
+     *
+     * @return string version of the ID
+     */
+    public final String getStringId() {
+        return this.dpid.toString();
+    }
+
+    public final void setOFVersion(OFVersion ofV) {
+        this.ofVersion = ofV;
+    }
+
+    void setTableFull(boolean full) {
+        this.tableFull = full;
+    }
+
+    public abstract void setFeaturesReply(OFFeaturesReply featuresReply);
+
+    /**
+     * Let peoeple know if you support Nicira style role requests.
+     *
+     * @return support Nicira roles or not.
+     */
+    public abstract Boolean supportNxRole();
+
+    //************************
+    //  Message handling
+    //************************
+    /**
+     * Handle the message coming from the dataplane.
+     *
+     * @param m the actual message
+     */
+    public final void handleMessage(OFMessage m) {
+        this.agent.processMessage(m);
+    }
+
+    public abstract RoleState getRole();
+
+    final boolean addConnectedSwitch() {
+        return this.agent.addConnectedSwitch(this.getId(), this);
+    }
+
+    final boolean addActivatedMasterSwitch() {
+        return this.agent.addActivatedMasterSwitch(this.getId(), this);
+    }
+
+    final boolean addActivatedEqualSwitch() {
+        return this.agent.addActivatedEqualSwitch(this.getId(), this);
+    }
+
+    final void transitionToEqualSwitch() {
+        this.agent.transitionToEqualSwitch(this.getId());
+    }
+
+    final void transitionToMasterSwitch() {
+        this.agent.transitionToMasterSwitch(this.getId());
+    }
+
+    final void removeConnectedSwitch() {
+        this.agent.removeConnectedSwitch(this.getId());
+    }
+
+    protected OFFactory factory() {
+        return OFFactories.getFactory(ofVersion);
+    }
+
+    public void setPortDescReply(OFPortDescStatsReply portDescReply) {
+        this.ports = portDescReply;
+    }
+
+    public abstract void startDriverHandshake();
+
+    public abstract boolean isDriverHandshakeComplete();
+
+    public abstract void processDriverHandshakeMessage(OFMessage m);
+
+    public void setRole(RoleState role) {
+        try {
+            this.roleMan.sendRoleRequest(role, RoleRecvStatus.MATCHED_SET_ROLE);
+        } catch (IOException e) {
+           log.error("Unable to write to switch {}.", this.dpid);
+        }
+    }
+
+    // Role Handling
+
+    void handleRole(OFMessage m) throws SwitchStateException {
+        RoleReplyInfo rri = roleMan.extractOFRoleReply((OFRoleReply) m);
+        RoleRecvStatus rrs = roleMan.deliverRoleReply(rri);
+        if (rrs == RoleRecvStatus.MATCHED_SET_ROLE) {
+            if (rri.getRole() == RoleState.MASTER) {
+                this.transitionToMasterSwitch();
+            } else if (rri.getRole() == RoleState.EQUAL ||
+                    rri.getRole() == RoleState.MASTER) {
+                this.transitionToEqualSwitch();
+            }
+        }
+    }
+
+    void handleNiciraRole(OFMessage m) throws SwitchStateException {
+        RoleState role = this.roleMan.extractNiciraRoleReply((OFExperimenter) m);
+      if (role == null) {
+          // The message wasn't really a Nicira role reply. We just
+          // dispatch it to the OFMessage listeners in this case.
+          this.handleMessage(m);
+      }
+
+      RoleRecvStatus rrs = this.roleMan.deliverRoleReply(
+              new RoleReplyInfo(role, null, m.getXid()));
+          if (rrs == RoleRecvStatus.MATCHED_SET_ROLE) {
+              if (role == RoleState.MASTER) {
+                  this.transitionToMasterSwitch();
+              } else if (role == RoleState.EQUAL ||
+                      role == RoleState.SLAVE) {
+                  this.transitionToEqualSwitch();
+              }
+          }
+    }
+
+    boolean handleRoleError(OFErrorMsg error) {
+        try {
+            return RoleRecvStatus.OTHER_EXPECTATION != this.roleMan.deliverError(error);
+        } catch (SwitchStateException e) {
+            this.disconnectSwitch();
+        }
+        return true;
+    }
+
+    void reassertRole() {
+        if (this.getRole() == RoleState.MASTER) {
+            this.setRole(RoleState.MASTER);
+        }
+    }
+
+    void setAgent(OpenFlowSwitchAgent ag) {
+        this.agent = ag;
+    }
+
+
+
+}
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/Controller.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/Controller.java
index 1f0b36d..6ae3abb 100644
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/Controller.java
+++ b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/Controller.java
@@ -20,47 +20,22 @@
 import java.lang.management.ManagementFactory;
 import java.lang.management.RuntimeMXBean;
 import java.net.InetSocketAddress;
-import java.net.UnknownHostException;
-import java.util.Collections;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Executors;
 
-import org.onlab.onos.of.controller.impl.IOFSwitchManager;
-import org.onlab.onos.of.controller.impl.Role;
-import org.onlab.onos.of.controller.impl.annotations.LogMessageDoc;
-import org.onlab.onos.of.controller.impl.annotations.LogMessageDocs;
-import org.onlab.onos.of.controller.impl.debugcounter.DebugCounter;
-import org.onlab.onos.of.controller.impl.debugcounter.IDebugCounter;
-import org.onlab.onos.of.controller.impl.debugcounter.IDebugCounterService;
-import org.onlab.onos.of.controller.impl.debugcounter.IDebugCounterService.CounterException;
-import org.onlab.onos.of.controller.impl.debugcounter.IDebugCounterService.CounterType;
-import org.onlab.onos.of.controller.impl.internal.OFChannelHandler.RoleRecvStatus;
-import org.onlab.onos.of.controller.impl.registry.IControllerRegistry;
-import org.onlab.onos.of.controller.impl.registry.RegistryException;
-import org.onlab.onos.of.controller.impl.registry.IControllerRegistry.ControlChangeCallback;
-import org.onlab.onos.of.controller.impl.util.Dpid;
-import org.onlab.onos.of.controller.impl.util.DummySwitchForTesting;
-import org.onlab.onos.of.controller.impl.util.InstanceId;
-import org.onlab.onos.of.controller.impl.IOFSwitch;
-import org.onlab.onos.of.controller.impl.IOFSwitch.PortChangeType;
-
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Component;
 import org.jboss.netty.bootstrap.ServerBootstrap;
 import org.jboss.netty.channel.ChannelPipelineFactory;
 import org.jboss.netty.channel.group.ChannelGroup;
 import org.jboss.netty.channel.group.DefaultChannelGroup;
 import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
+import org.onlab.onos.of.controller.impl.annotations.LogMessageDoc;
+import org.onlab.onos.of.controller.impl.annotations.LogMessageDocs;
+import org.onlab.onos.of.controller.impl.internal.OpenFlowControllerImpl.OpenFlowSwitchAgent;
 import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
 import org.projectfloodlight.openflow.protocol.OFFactories;
 import org.projectfloodlight.openflow.protocol.OFFactory;
-import org.projectfloodlight.openflow.protocol.OFPortDesc;
 import org.projectfloodlight.openflow.protocol.OFVersion;
-import org.projectfloodlight.openflow.util.HexString;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -69,7 +44,6 @@
  * The main controller class.  Handles all setup and network listeners
  * - Distributed ownership control of switch through IControllerRegistryService
  */
-@Component(immediate = true)
 public class Controller {
 
     protected static final Logger log = LoggerFactory.getLogger(Controller.class);
@@ -78,189 +52,33 @@
     protected static final OFFactory FACTORY13 = OFFactories.getFactory(OFVersion.OF_13);
     protected static final OFFactory FACTORY10 = OFFactories.getFactory(OFVersion.OF_10);
 
-    // connectedSwitches cache contains all connected switch's channelHandlers
-    // including ones where this controller is a master/equal/slave controller
-    // as well as ones that have not been activated yet
-    protected ConcurrentHashMap<Long, OFChannelHandler> connectedSwitches;
-    // These caches contains only those switches that are active
-    protected ConcurrentHashMap<Long, IOFSwitch> activeMasterSwitches;
-    protected ConcurrentHashMap<Long, IOFSwitch> activeEqualSwitches;
-    // lock to synchronize on, when manipulating multiple caches above
-    private Object multiCacheLock;
+
 
     // The controllerNodeIPsCache maps Controller IDs to their IP address.
     // It's only used by handleControllerNodeIPsChanged
     protected HashMap<String, String> controllerNodeIPsCache;
 
-    // Module dependencies
-
-    protected IControllerRegistry registryService;
-    protected IDebugCounterService debugCounters;
-
 
     private IOFSwitchManager switchManager;
 
+    private ChannelGroup cg;
+
     // Configuration options
     protected int openFlowPort = 6633;
     protected int workerThreads = 0;
 
-    // defined counters
-    private Counters counters;
-
     // Start time of the controller
     protected long systemStartTime;
 
     // Flag to always flush flow table on switch reconnect (HA or otherwise)
     protected boolean alwaysClearFlowsOnSwAdd = false;
-    private InstanceId instanceId;
+    private OpenFlowSwitchAgent agent;
 
     // Perf. related configuration
     protected static final int SEND_BUFFER_SIZE = 4 * 1024 * 1024;
     protected static final int BATCH_MAX_SIZE = 100;
     protected static final boolean ALWAYS_DECODE_ETH = true;
 
-    protected boolean addConnectedSwitch(long dpid, OFChannelHandler h) {
-        if (connectedSwitches.get(dpid) != null) {
-            log.error("Trying to add connectedSwitch but found a previous "
-                    + "value for dpid: {}", dpid);
-            return false;
-        } else {
-            log.error("Added switch {}", dpid);
-            connectedSwitches.put(dpid, h);
-            return true;
-        }
-    }
-
-    private boolean validActivation(long dpid) {
-        if (connectedSwitches.get(dpid) == null) {
-            log.error("Trying to activate switch but is not in "
-                    + "connected switches: dpid {}. Aborting ..",
-                    HexString.toHexString(dpid));
-            return false;
-        }
-        if (activeMasterSwitches.get(dpid) != null ||
-                activeEqualSwitches.get(dpid) != null) {
-            log.error("Trying to activate switch but it is already "
-                    + "activated: dpid {}. Found in activeMaster: {} "
-                    + "Found in activeEqual: {}. Aborting ..", new Object[] {
-                            HexString.toHexString(dpid),
-                            (activeMasterSwitches.get(dpid) == null) ? 'N' : 'Y',
-                            (activeEqualSwitches.get(dpid) == null) ? 'N' : 'Y'});
-            counters.switchWithSameDpidActivated.updateCounterWithFlush();
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Called when a switch is activated, with this controller's role as MASTER.
-     */
-    protected boolean addActivatedMasterSwitch(long dpid, IOFSwitch sw) {
-        synchronized (multiCacheLock) {
-            if (!validActivation(dpid)) {
-                return false;
-            }
-            activeMasterSwitches.put(dpid, sw);
-        }
-        //update counters and events
-        counters.switchActivated.updateCounterWithFlush();
-
-        return true;
-    }
-
-    /**
-     * Called when a switch is activated, with this controller's role as EQUAL.
-     */
-    protected boolean addActivatedEqualSwitch(long dpid, IOFSwitch sw) {
-        synchronized (multiCacheLock) {
-            if (!validActivation(dpid)) {
-                return false;
-            }
-            activeEqualSwitches.put(dpid, sw);
-        }
-        //update counters and events
-        counters.switchActivated.updateCounterWithFlush();
-        return true;
-    }
-
-    /**
-     * Called when this controller's role for a switch transitions from equal
-     * to master. For 1.0 switches, we internally refer to the role 'slave' as
-     * 'equal' - so this transition is equivalent to 'addActivatedMasterSwitch'.
-     */
-    protected void transitionToMasterSwitch(long dpid) {
-        synchronized (multiCacheLock) {
-            IOFSwitch sw = activeEqualSwitches.remove(dpid);
-            if (sw == null) {
-                log.error("Transition to master called on sw {}, but switch "
-                        + "was not found in controller-cache", dpid);
-                return;
-            }
-            activeMasterSwitches.put(dpid, sw);
-        }
-    }
-
-
-    /**
-     * Called when this controller's role for a switch transitions to equal.
-     * For 1.0 switches, we internally refer to the role 'slave' as
-     * 'equal'.
-     */
-    protected void transitionToEqualSwitch(long dpid) {
-        synchronized (multiCacheLock) {
-            IOFSwitch sw = activeMasterSwitches.remove(dpid);
-            if (sw == null) {
-                log.error("Transition to equal called on sw {}, but switch "
-                        + "was not found in controller-cache", dpid);
-                return;
-            }
-            activeEqualSwitches.put(dpid, sw);
-        }
-
-    }
-
-    /**
-     * Clear all state in controller switch maps for a switch that has
-     * disconnected from the local controller. Also release control for
-     * that switch from the global repository. Notify switch listeners.
-     */
-    protected void removeConnectedSwitch(long dpid) {
-        releaseRegistryControl(dpid);
-        connectedSwitches.remove(dpid);
-        IOFSwitch sw = activeMasterSwitches.remove(dpid);
-        if (sw == null) {
-            sw = activeEqualSwitches.remove(dpid);
-        }
-        if (sw != null) {
-            sw.cancelAllStatisticsReplies();
-            sw.setConnected(false); // do we need this?
-        }
-        counters.switchDisconnected.updateCounterWithFlush();
-
-    }
-
-    /**
-     * Indicates that ports on the given switch have changed. Enqueue a
-     * switch update.
-     * @param dpid
-     * @param port
-     * @param changeType
-     */
-    protected void notifyPortChanged(long dpid, OFPortDesc port,
-            PortChangeType changeType) {
-        if (port == null || changeType == null) {
-            String msg = String.format("Switch port or changetType must not "
-                    + "be null in port change notification");
-            throw new NullPointerException(msg);
-        }
-        if (connectedSwitches.get(dpid) == null || getSwitch(dpid) == null) {
-            log.warn("Port change update on switch {} not connected or activated "
-                    + "... Aborting.", HexString.toHexString(dpid));
-            return;
-        }
-
-    }
-
     // ***************
     // Getters/Setters
     // ***************
@@ -268,180 +86,8 @@
 
     public synchronized void setIOFSwitchManager(IOFSwitchManager swManager) {
         this.switchManager = swManager;
-        this.registryService = swManager.getRegistry();
     }
 
-
-    public void setDebugCounter(IDebugCounterService dcs) {
-        this.debugCounters = dcs;
-    }
-
-    IDebugCounterService getDebugCounter() {
-        return this.debugCounters;
-    }
-
-    // **********************
-    // Role Handling
-    // **********************
-
-    /**
-     * created by ONOS - works with registry service.
-     */
-    protected class RoleChangeCallback implements ControlChangeCallback {
-        @Override
-        public void controlChanged(long dpidLong, boolean hasControl) {
-            Dpid dpid = new Dpid(dpidLong);
-            log.info("Role change callback for switch {}, hasControl {}",
-                    dpid, hasControl);
-
-            Role role = null;
-
-            /*
-             * issue #229
-             * Cannot rely on sw.getRole() as it can be behind due to pending
-             * role changes in the queue. Just submit it and late the
-             * RoleChanger handle duplicates.
-             */
-
-            if (hasControl) {
-                role = Role.MASTER;
-            } else {
-                role = Role.EQUAL; // treat the same as Role.SLAVE
-            }
-
-            OFChannelHandler swCh = connectedSwitches.get(dpid.value());
-            if (swCh == null) {
-                log.warn("Switch {} not found in connected switches", dpid);
-                return;
-            }
-
-            log.debug("Sending role request {} msg to {}", role, dpid);
-            swCh.sendRoleRequest(role, RoleRecvStatus.MATCHED_SET_ROLE);
-        }
-    }
-
-    /**
-     * Submit request to the registry service for mastership of the
-     * switch.
-     * @param dpid this datapath to get role for
-     */
-    public synchronized void submitRegistryRequest(long dpid) {
-        if (registryService == null) {
-            /*
-             * If we have no registry then simply assign
-             * mastership to this controller.
-             */
-            new RoleChangeCallback().controlChanged(dpid, true);
-            return;
-        }
-        OFChannelHandler h = connectedSwitches.get(dpid);
-        if (h == null) {
-            log.error("Trying to request registry control for switch {} "
-                    + "not in connected switches. Aborting.. ",
-                    HexString.toHexString(dpid));
-            connectedSwitches.get(dpid).disconnectSwitch();
-            return;
-        }
-        //Request control of the switch from the global registry
-        try {
-            h.controlRequested = Boolean.TRUE;
-            registryService.requestControl(dpid, new RoleChangeCallback());
-        } catch (RegistryException e) {
-            log.debug("Registry error: {}", e.getMessage());
-            h.controlRequested = Boolean.FALSE;
-        }
-        if (!h.controlRequested) { // XXX what is being attempted here?
-            // yield to allow other thread(s) to release control
-            // TODO AAS: this is awful and needs to be fixed
-            Thread.yield();
-            // safer to bounce the switch to reconnect here than proceeding further
-            // XXX S why? can't we just try again a little later?
-            log.debug("Closing sw:{} because we weren't able to request control " +
-                    "successfully" + dpid);
-            connectedSwitches.get(dpid).disconnectSwitch();
-        }
-    }
-
-    /**
-     * Relinquish role for the switch.
-     * @param dpidLong the controlled datapath
-     */
-    public synchronized void releaseRegistryControl(long dpidLong) {
-        OFChannelHandler h = connectedSwitches.get(dpidLong);
-        if (h == null) {
-            log.error("Trying to release registry control for switch {} "
-                    + "not in connected switches. Aborting.. ",
-                    HexString.toHexString(dpidLong));
-            return;
-        }
-        if (registryService != null && h.controlRequested) {
-            //TODO the above is not good for testing need to change controlrequest to method call.
-            registryService.releaseControl(dpidLong);
-        }
-    }
-
-
-    // FIXME: remove this method
-    public Map<Long, IOFSwitch> getSwitches() {
-        return getMasterSwitches();
-    }
-
-    // FIXME: remove this method
-    public Map<Long, IOFSwitch> getMasterSwitches() {
-        return Collections.unmodifiableMap(activeMasterSwitches);
-    }
-
-
-
-    public Set<Long> getAllSwitchDpids() {
-        Set<Long> dpids = new HashSet<Long>();
-        dpids.addAll(activeMasterSwitches.keySet());
-        dpids.addAll(activeEqualSwitches.keySet());
-        return dpids;
-    }
-
-
-    public Set<Long> getAllMasterSwitchDpids() {
-        Set<Long> dpids = new HashSet<Long>();
-        dpids.addAll(activeMasterSwitches.keySet());
-        return dpids;
-    }
-
-
-    public Set<Long> getAllEqualSwitchDpids() {
-        Set<Long> dpids = new HashSet<Long>();
-        dpids.addAll(activeEqualSwitches.keySet());
-        return dpids;
-    }
-
-
-    public IOFSwitch getSwitch(long dpid) {
-        IOFSwitch sw = null;
-        sw = activeMasterSwitches.get(dpid);
-        if (sw != null) {
-            return sw;
-        }
-        sw = activeEqualSwitches.get(dpid);
-        if (sw != null) {
-            return sw;
-        }
-        return sw;
-    }
-
-
-    public IOFSwitch getMasterSwitch(long dpid) {
-        return  activeMasterSwitches.get(dpid);
-    }
-
-
-    public IOFSwitch getEqualSwitch(long dpid) {
-        return  activeEqualSwitches.get(dpid);
-    }
-
-
-
-
-
     public OFFactory getOFMessageFactory10() {
         return FACTORY10;
     }
@@ -469,12 +115,6 @@
         return (this.systemStartTime);
     }
 
-
-    public InstanceId getInstanceId() {
-        return instanceId;
-    }
-
-
     // **************
     // Initialization
     // **************
@@ -509,7 +149,7 @@
                     new OpenflowPipelineFactory(this, null);
             bootstrap.setPipelineFactory(pfact);
             InetSocketAddress sa = new InetSocketAddress(openFlowPort);
-            final ChannelGroup cg = new DefaultChannelGroup();
+            cg = new DefaultChannelGroup();
             cg.add(bootstrap.bind(sa));
 
             log.info("Listening for switch connections on {}", sa);
@@ -544,20 +184,6 @@
             this.workerThreads = Integer.parseInt(threads);
         }
         log.debug("Number of worker threads set to {}", this.workerThreads);
-        String controllerId = configParams.get("controllerid");
-        if (controllerId != null) {
-            this.instanceId = new InstanceId(controllerId);
-        } else {
-            //Try to get the hostname of the machine and use that for controller ID
-            try {
-                String hostname = java.net.InetAddress.getLocalHost().getHostName();
-                this.instanceId = new InstanceId(hostname);
-            } catch (UnknownHostException e) {
-                log.warn("Can't get hostname, using the default");
-            }
-        }
-
-        log.debug("ControllerId set to {}", this.instanceId);
     }
 
 
@@ -567,16 +193,11 @@
     public void init(Map<String, String> configParams) {
         // These data structures are initialized here because other
         // module's startUp() might be called before ours
-        this.activeMasterSwitches = new ConcurrentHashMap<Long, IOFSwitch>();
-        this.activeEqualSwitches = new ConcurrentHashMap<Long, IOFSwitch>();
-        this.connectedSwitches = new ConcurrentHashMap<Long, OFChannelHandler>();
         this.controllerNodeIPsCache = new HashMap<String, String>();
 
         setConfigParams(configParams);
         this.systemStartTime = System.currentTimeMillis();
-        this.setDebugCounter(new DebugCounter());
-        this.counters = new Counters();
-        this.multiCacheLock = new Object();
+
 
     }
 
@@ -589,215 +210,10 @@
                     "that the system database has failed to start. " +
                     LogMessageDoc.CHECK_CONTROLLER)
     public synchronized void startupComponents() {
-        try {
-            if (registryService != null) {
-                registryService.registerController(instanceId.toString());
-            }
-        } catch (RegistryException e) {
-            log.warn("Registry service error: {}", e.getMessage());
-        }
-
-        // register counters and events
-        try {
-            this.counters.createCounters(debugCounters);
-        } catch (CounterException e) {
-            log.warn("Counters unavailable: {}", e.getMessage());
-        }
+        //TODO do something maybe
     }
 
     // **************
-    // debugCounter registrations
-    // **************
-
-    public static class Counters {
-        public static final String PREFIX = "controller";
-        public IDebugCounter switchActivated;
-        public IDebugCounter switchWithSameDpidActivated; // warn
-        public IDebugCounter switchDisconnected;
-        public IDebugCounter messageReceived;
-        public IDebugCounter switchDisconnectReadTimeout;
-        public IDebugCounter switchDisconnectHandshakeTimeout;
-        public IDebugCounter switchDisconnectIOError;
-        public IDebugCounter switchDisconnectParseError;
-        public IDebugCounter switchDisconnectSwitchStateException;
-        public IDebugCounter rejectedExecutionException;
-        public IDebugCounter switchDisconnectOtherException;
-        public IDebugCounter switchConnected;
-        public IDebugCounter unhandledMessage;
-        public IDebugCounter packetInWhileSwitchIsSlave;
-        public IDebugCounter epermErrorWhileSwitchIsMaster;
-        public IDebugCounter roleReplyTimeout;
-        public IDebugCounter roleReplyReceived; // expected RoleReply received
-        public IDebugCounter roleReplyErrorUnsupported;
-        public IDebugCounter switchCounterRegistrationFailed;
-
-        void createCounters(IDebugCounterService debugCounters) throws CounterException {
-
-            switchActivated =
-                debugCounters.registerCounter(
-                            PREFIX, "switch-activated",
-                            "A switch connected to this controller is now " +
-                            "in MASTER role",
-                            CounterType.ALWAYS_COUNT);
-
-            switchWithSameDpidActivated = // warn
-                debugCounters.registerCounter(
-                            PREFIX, "switch-with-same-dpid-activated",
-                            "A switch with the same DPID as another switch " +
-                            "connected to the controller. This can be " +
-                            "caused by multiple switches configured with " +
-                            "the same DPID or by a switch reconnecting very " +
-                            "quickly.",
-                            CounterType.COUNT_ON_DEMAND,
-                            IDebugCounterService.CTR_MDATA_WARN);
-
-            switchDisconnected =
-                debugCounters.registerCounter(
-                            PREFIX, "switch-disconnected",
-                            "FIXME: switch has disconnected",
-                            CounterType.ALWAYS_COUNT);
-
-        //------------------------
-        // channel handler counters. Factor them out ??
-            messageReceived =
-                debugCounters.registerCounter(
-                            PREFIX, "message-received",
-                            "Number of OpenFlow messages received. Some of " +
-                            "these might be throttled",
-                            CounterType.ALWAYS_COUNT);
-
-            switchDisconnectReadTimeout =
-                debugCounters.registerCounter(
-                            PREFIX, "switch-disconnect-read-timeout",
-                            "Number of times a switch was disconnected due " +
-                            "due the switch failing to send OpenFlow " +
-                            "messages or responding to OpenFlow ECHOs",
-                            CounterType.ALWAYS_COUNT,
-                            IDebugCounterService.CTR_MDATA_ERROR);
-            switchDisconnectHandshakeTimeout =
-                debugCounters.registerCounter(
-                            PREFIX, "switch-disconnect-handshake-timeout",
-                            "Number of times a switch was disconnected " +
-                            "because it failed to complete the handshake " +
-                            "in time.",
-                            CounterType.ALWAYS_COUNT,
-                            IDebugCounterService.CTR_MDATA_ERROR);
-            switchDisconnectIOError =
-                debugCounters.registerCounter(
-                            PREFIX, "switch-disconnect-io-error",
-                            "Number of times a switch was disconnected " +
-                            "due to IO errors on the switch connection.",
-                            CounterType.ALWAYS_COUNT,
-                            IDebugCounterService.CTR_MDATA_ERROR);
-            switchDisconnectParseError =
-                debugCounters.registerCounter(
-                            PREFIX, "switch-disconnect-parse-error",
-                           "Number of times a switch was disconnected " +
-                           "because it sent an invalid packet that could " +
-                           "not be parsed",
-                           CounterType.ALWAYS_COUNT,
-                           IDebugCounterService.CTR_MDATA_ERROR);
-
-            switchDisconnectSwitchStateException =
-                debugCounters.registerCounter(
-                            PREFIX, "switch-disconnect-switch-state-exception",
-                            "Number of times a switch was disconnected " +
-                            "because it sent messages that were invalid " +
-                            "given the switch connection's state.",
-                            CounterType.ALWAYS_COUNT,
-                            IDebugCounterService.CTR_MDATA_ERROR);
-            rejectedExecutionException =
-                debugCounters.registerCounter(
-                            PREFIX, "rejected-execution-exception",
-                            "TODO",
-                            CounterType.ALWAYS_COUNT,
-                            IDebugCounterService.CTR_MDATA_ERROR);
-
-            switchDisconnectOtherException =
-                debugCounters.registerCounter(
-                            PREFIX,  "switch-disconnect-other-exception",
-                            "Number of times a switch was disconnected " +
-                            "due to an exceptional situation not covered " +
-                            "by other counters",
-                            CounterType.ALWAYS_COUNT,
-                            IDebugCounterService.CTR_MDATA_ERROR);
-
-            switchConnected =
-                debugCounters.registerCounter(
-                            PREFIX, "switch-connected",
-                            "Number of times a new switch connection was " +
-                            "established",
-                            CounterType.ALWAYS_COUNT);
-
-            unhandledMessage =
-                debugCounters.registerCounter(
-                            PREFIX, "unhandled-message",
-                            "Number of times an OpenFlow message was " +
-                            "received that the controller ignored because " +
-                            "it was inapproriate given the switch " +
-                            "connection's state.",
-                            CounterType.ALWAYS_COUNT,
-                            IDebugCounterService.CTR_MDATA_WARN);
-                            // might be less than warning
-
-            packetInWhileSwitchIsSlave =
-                debugCounters.registerCounter(
-                            PREFIX, "packet-in-while-switch-is-slave",
-                            "Number of times a packet in was received " +
-                            "from a switch that was in SLAVE role. " +
-                            "Possibly inidicates inconsistent roles.",
-                            CounterType.ALWAYS_COUNT);
-            epermErrorWhileSwitchIsMaster =
-                debugCounters.registerCounter(
-                            PREFIX, "eperm-error-while-switch-is-master",
-                            "Number of times a permission error was " +
-                            "received while the switch was in MASTER role. " +
-                            "Possibly inidicates inconsistent roles.",
-                            CounterType.ALWAYS_COUNT,
-                            IDebugCounterService.CTR_MDATA_WARN);
-
-            roleReplyTimeout =
-                debugCounters.registerCounter(
-                            PREFIX, "role-reply-timeout",
-                            "Number of times a role request message did not " +
-                            "receive the expected reply from a switch",
-                            CounterType.ALWAYS_COUNT,
-                            IDebugCounterService.CTR_MDATA_WARN);
-
-            roleReplyReceived = // expected RoleReply received
-                debugCounters.registerCounter(
-                            PREFIX, "role-reply-received",
-                            "Number of times the controller received the " +
-                            "expected role reply message from a switch",
-                            CounterType.ALWAYS_COUNT);
-
-            roleReplyErrorUnsupported =
-                debugCounters.registerCounter(
-                            PREFIX, "role-reply-error-unsupported",
-                            "Number of times the controller received an " +
-                            "error from a switch in response to a role " +
-                            "request indicating that the switch does not " +
-                            "support roles.",
-                            CounterType.ALWAYS_COUNT);
-
-            switchCounterRegistrationFailed =
-                    debugCounters.registerCounter(PREFIX,
-                                "switch-counter-registration-failed",
-                                "Number of times the controller failed to " +
-                                "register per-switch debug counters",
-                                CounterType.ALWAYS_COUNT,
-                                IDebugCounterService.CTR_MDATA_WARN);
-
-
-        }
-    }
-
-    public Counters getCounters() {
-        return this.counters;
-    }
-
-
-    // **************
     // Utility methods
     // **************
 
@@ -820,20 +236,24 @@
      * @param desc
      * @return switch instance
      */
-    protected IOFSwitch getOFSwitchInstance(OFDescStatsReply desc, OFVersion ofv) {
-        if (switchManager == null) {
-            return new DummySwitchForTesting();
-        }
-        return switchManager.getSwitchImpl(desc.getMfrDesc(), desc.getHwDesc(),
+    protected AbstractOpenFlowSwitch getOFSwitchInstance(OFDescStatsReply desc, OFVersion ofv) {
+        AbstractOpenFlowSwitch sw =  switchManager.getSwitchImpl(desc.getMfrDesc(), desc.getHwDesc(),
                                             desc.getSwDesc(), ofv);
+        sw.setAgent(agent);
+        return sw;
     }
 
-    @Activate
-    public void activate() {
+    public void start(OpenFlowSwitchAgent ag) {
         log.info("Initialising OpenFlow Lib and IO");
+        this.agent = ag;
         this.init(new HashMap<String, String>());
         this.startupComponents();
         this.run();
     }
 
+
+    public void stop() {
+        cg.close();
+    }
+
 }
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/IOFSwitchManager.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/IOFSwitchManager.java
similarity index 61%
rename from of/ctl/src/main/java/org/onlab/onos/of/controller/impl/IOFSwitchManager.java
rename to of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/IOFSwitchManager.java
index 0acb321..4b2f7c3 100644
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/IOFSwitchManager.java
+++ b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/IOFSwitchManager.java
@@ -1,8 +1,7 @@
-package org.onlab.onos.of.controller.impl;
+package org.onlab.onos.of.controller.impl.internal;
 
 import org.projectfloodlight.openflow.protocol.OFVersion;
 
-import org.onlab.onos.of.controller.impl.registry.IControllerRegistry;
 
 /**
  * Interface to passed to controller class in order to allow
@@ -22,12 +21,6 @@
      * @param ofv openflow version
      * @return A switch of type IOFSwitch.
      */
-    public IOFSwitch getSwitchImpl(String mfr, String hwDesc, String swDesc, OFVersion ofv);
-
-    /**
-     * Returns the mastership registry used during controller-switch role election.
-     * @return the registry
-     */
-    public IControllerRegistry getRegistry();
+    public AbstractOpenFlowSwitch getSwitchImpl(String mfr, String hwDesc, String swDesc, OFVersion ofv);
 
 }
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/OFChannelHandler.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/OFChannelHandler.java
index 667a051..5db1fc3 100644
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/OFChannelHandler.java
+++ b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/OFChannelHandler.java
@@ -4,21 +4,11 @@
 import java.io.IOException;
 import java.nio.channels.ClosedChannelException;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.RejectedExecutionException;
 
-import org.onlab.onos.of.controller.impl.IOFSwitch;
-import org.onlab.onos.of.controller.impl.IOFSwitch.PortChangeEvent;
-import org.onlab.onos.of.controller.impl.Role;
-import org.onlab.onos.of.controller.impl.annotations.LogMessageDoc;
-import org.onlab.onos.of.controller.impl.annotations.LogMessageDocs;
-import org.onlab.onos.of.controller.impl.debugcounter.IDebugCounterService.CounterException;
-import org.onlab.onos.of.controller.impl.internal.Controller.Counters;
-import org.onlab.onos.of.controller.impl.internal.OFChannelHandler.ChannelState.RoleReplyInfo;
-
 import org.jboss.netty.channel.Channel;
 import org.jboss.netty.channel.ChannelHandlerContext;
 import org.jboss.netty.channel.ChannelStateEvent;
@@ -27,12 +17,14 @@
 import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler;
 import org.jboss.netty.handler.timeout.IdleStateEvent;
 import org.jboss.netty.handler.timeout.ReadTimeoutException;
+import org.onlab.onos.of.controller.RoleState;
+import org.onlab.onos.of.controller.impl.annotations.LogMessageDoc;
+import org.onlab.onos.of.controller.impl.annotations.LogMessageDocs;
 import org.projectfloodlight.openflow.exceptions.OFParseError;
 import org.projectfloodlight.openflow.protocol.OFAsyncGetReply;
 import org.projectfloodlight.openflow.protocol.OFBadRequestCode;
 import org.projectfloodlight.openflow.protocol.OFBarrierReply;
 import org.projectfloodlight.openflow.protocol.OFBarrierRequest;
-import org.projectfloodlight.openflow.protocol.OFControllerRole;
 import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
 import org.projectfloodlight.openflow.protocol.OFDescStatsRequest;
 import org.projectfloodlight.openflow.protocol.OFEchoReply;
@@ -49,15 +41,12 @@
 import org.projectfloodlight.openflow.protocol.OFHello;
 import org.projectfloodlight.openflow.protocol.OFHelloElem;
 import org.projectfloodlight.openflow.protocol.OFMessage;
-import org.projectfloodlight.openflow.protocol.OFNiciraControllerRole;
-import org.projectfloodlight.openflow.protocol.OFNiciraControllerRoleReply;
 import org.projectfloodlight.openflow.protocol.OFPacketIn;
 import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply;
 import org.projectfloodlight.openflow.protocol.OFPortDescStatsRequest;
 import org.projectfloodlight.openflow.protocol.OFPortStatus;
 import org.projectfloodlight.openflow.protocol.OFQueueGetConfigReply;
 import org.projectfloodlight.openflow.protocol.OFRoleReply;
-import org.projectfloodlight.openflow.protocol.OFRoleRequest;
 import org.projectfloodlight.openflow.protocol.OFSetConfig;
 import org.projectfloodlight.openflow.protocol.OFStatsReply;
 import org.projectfloodlight.openflow.protocol.OFStatsReplyFlags;
@@ -66,11 +55,10 @@
 import org.projectfloodlight.openflow.protocol.OFVersion;
 import org.projectfloodlight.openflow.protocol.errormsg.OFBadRequestErrorMsg;
 import org.projectfloodlight.openflow.protocol.errormsg.OFFlowModFailedErrorMsg;
-import org.projectfloodlight.openflow.protocol.errormsg.OFRoleRequestFailedErrorMsg;
 import org.projectfloodlight.openflow.types.U32;
-import org.projectfloodlight.openflow.types.U64;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+
 /**
  * Channel handler deals with the switch connection and dispatches
  * switch messages to the appropriate locations.
@@ -79,18 +67,13 @@
     private static final Logger log = LoggerFactory.getLogger(OFChannelHandler.class);
     private static final long DEFAULT_ROLE_TIMEOUT_MS = 2 * 1000; // 10 sec
     private final Controller controller;
-    private final Counters counters;
-    private IOFSwitch sw;
+    private AbstractOpenFlowSwitch sw;
     private long thisdpid; // channelHandler cached value of connected switch id
     private Channel channel;
     // State needs to be volatile because the HandshakeTimeoutHandler
     // needs to check if the handshake is complete
     private volatile ChannelState state;
 
-    // All role messaging is handled by the roleChanger. The channel state machine
-    // coordinates between the roleChanger and the controller-global-registry-service
-    // to determine controller roles per switch.
-    private RoleChanger roleChanger;
     // Used to coordinate between the controller and the cleanup thread(?)
     // for access to the global registry on a per switch basis.
     volatile Boolean controlRequested;
@@ -125,8 +108,6 @@
      */
     OFChannelHandler(Controller controller) {
         this.controller = controller;
-        this.counters = controller.getCounters();
-        this.roleChanger = new RoleChanger(DEFAULT_ROLE_TIMEOUT_MS);
         this.state = ChannelState.INIT;
         this.pendingPortStatusMsg = new CopyOnWriteArrayList<OFPortStatus>();
         factory13 = controller.getOFMessageFactory13();
@@ -135,392 +116,14 @@
         duplicateDpidFound = Boolean.FALSE;
     }
 
-    //*******************
-    //  Role Handling
-    //*******************
 
-    /**
-     * When we remove a pending role request we use this enum to indicate how we
-     * arrived at the decision. When we send a role request to the switch, we
-     * also use  this enum to indicate what we expect back from the switch, so the
-     * role changer can match the reply to our expectation.
-     */
-    public enum RoleRecvStatus {
-        /** The switch returned an error indicating that roles are not.
-         * supported*/
-        UNSUPPORTED,
-        /** The request timed out. */
-        NO_REPLY,
-        /** The reply was old, there is a newer request pending. */
-        OLD_REPLY,
-        /**
-         *  The reply's role matched the role that this controller set in the
-         *  request message - invoked either initially at startup or to reassert
-         *  current role.
-         */
-        MATCHED_CURRENT_ROLE,
-        /**
-         *  The reply's role matched the role that this controller set in the
-         *  request message - this is the result of a callback from the
-         *  global registry, followed by a role request sent to the switch.
-         */
-        MATCHED_SET_ROLE,
-        /**
-         * The reply's role was a response to the query made by this controller.
-         */
-        REPLY_QUERY,
-        /** We received a role reply message from the switch
-         *  but the expectation was unclear, or there was no expectation.
-         */
-        OTHER_EXPECTATION,
-    }
-
-    /**
-     * Forwards to RoleChanger. See there.
-     * @param role
-     */
-    public void sendRoleRequest(Role role, RoleRecvStatus expectation) {
-        try {
-            roleChanger.sendRoleRequest(role, expectation);
-        } catch (IOException e) {
-            log.error("Disconnecting switch {} due to IO Error: {}",
-                    getSwitchInfoString(), e.getMessage());
-            channel.close();
-        }
-    }
 
     // XXX S consider if necessary
     public void disconnectSwitch() {
         sw.disconnectSwitch();
     }
 
-    /**
-     * A utility class to handle role requests and replies for this channel.
-     * After a role request is submitted the role changer keeps track of the
-     * pending request, collects the reply (if any) and times out the request
-     * if necessary.
-     *
-     * To simplify role handling we only keep track of the /last/ pending
-     * role reply send to the switch. If multiple requests are pending and
-     * we receive replies for earlier requests we ignore them. However, this
-     * way of handling pending requests implies that we could wait forever if
-     * a new request is submitted before the timeout triggers. If necessary
-     * we could work around that though.
-     */
-    private class RoleChanger {
-        // indicates that a request is currently pending
-        // needs to be volatile to allow correct double-check idiom
-        private volatile boolean requestPending;
-        // the transaction Id of the pending request
-        private int pendingXid;
-        // the role that's pending
-        private Role pendingRole;
-        // system time in MS when we send the request
-        private long roleSubmitTime;
-        // the timeout to use
-        private final long roleTimeoutMs;
-        // the expectation set by the caller for the returned role
-        private RoleRecvStatus expectation;
 
-        public RoleChanger(long roleTimeoutMs) {
-            this.requestPending = false;
-            this.roleSubmitTime = 0;
-            this.pendingXid = -1;
-            this.pendingRole = null;
-            this.roleTimeoutMs = roleTimeoutMs;
-            this.expectation = RoleRecvStatus.MATCHED_CURRENT_ROLE;
-        }
-
-        /**
-         * Send NX role request message to the switch requesting the specified
-         * role.
-         *
-         * @param sw switch to send the role request message to
-         * @param role role to request
-         */
-        private int sendNxRoleRequest(Role role) throws IOException {
-            // Convert the role enum to the appropriate role to send
-            OFNiciraControllerRole roleToSend = OFNiciraControllerRole.ROLE_OTHER;
-            switch (role) {
-            case MASTER:
-                roleToSend = OFNiciraControllerRole.ROLE_MASTER;
-                break;
-            case SLAVE:
-            case EQUAL:
-            default:
-                // ensuring that the only two roles sent to 1.0 switches with
-                // Nicira role support, are MASTER and SLAVE
-                roleToSend = OFNiciraControllerRole.ROLE_SLAVE;
-                log.warn("Sending Nx Role.SLAVE to switch {}.", sw);
-            }
-            int xid = sw.getNextTransactionId();
-            OFExperimenter roleRequest = factory10
-                    .buildNiciraControllerRoleRequest()
-                    .setXid(xid)
-                    .setRole(roleToSend)
-                    .build();
-            sw.write(Collections.<OFMessage>singletonList(roleRequest));
-            return xid;
-        }
-
-        private int sendOF13RoleRequest(Role role) throws IOException {
-            // Convert the role enum to the appropriate role to send
-            OFControllerRole roleToSend = OFControllerRole.ROLE_NOCHANGE;
-            switch (role) {
-            case EQUAL:
-                roleToSend = OFControllerRole.ROLE_EQUAL;
-                break;
-            case MASTER:
-                roleToSend = OFControllerRole.ROLE_MASTER;
-                break;
-            case SLAVE:
-                roleToSend = OFControllerRole.ROLE_SLAVE;
-                break;
-            default:
-                log.warn("Sending default role.noChange to switch {}."
-                        + " Should only be used for queries.", sw);
-            }
-
-            int xid = sw.getNextTransactionId();
-            OFRoleRequest rrm = factory13
-                    .buildRoleRequest()
-                    .setRole(roleToSend)
-                    .setXid(xid)
-                    .setGenerationId(sw.getNextGenerationId())
-                    .build();
-            sw.write(rrm);
-            return xid;
-        }
-
-        /**
-         * Send a role request with the given role to the switch and update
-         * the pending request and timestamp.
-         * Sends an OFPT_ROLE_REQUEST to an OF1.3 switch, OR
-         * Sends an NX_ROLE_REQUEST to an OF1.0 switch if configured to support it
-         * in the IOFSwitch driver. If not supported, this method sends nothing
-         * and returns 'false'. The caller should take appropriate action.
-         *
-         * One other optimization we do here is that for OF1.0 switches with
-         * Nicira role message support, we force the Role.EQUAL to become
-         * Role.SLAVE, as there is no defined behavior for the Nicira role OTHER.
-         * We cannot expect it to behave like SLAVE. We don't have this problem with
-         * OF1.3 switches, because Role.EQUAL is well defined and we can simulate
-         * SLAVE behavior by using ASYNC messages.
-         *
-         * @param role
-         * @throws IOException
-         * @returns false if and only if the switch does not support role-request
-         * messages, according to the switch driver; true otherwise.
-         */
-        synchronized boolean sendRoleRequest(Role role, RoleRecvStatus exp)
-                throws IOException {
-            this.expectation = exp;
-
-            if (ofVersion == OFVersion.OF_10) {
-                Boolean supportsNxRole = (Boolean)
-                        sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE);
-                if (!supportsNxRole) {
-                    log.debug("Switch driver indicates no support for Nicira "
-                            + "role request messages. Not sending ...");
-                    state.handleUnsentRoleMessage(OFChannelHandler.this, role,
-                            expectation);
-                    return false;
-                }
-                // OF1.0 switch with support for NX_ROLE_REQUEST vendor extn.
-                // make Role.EQUAL become Role.SLAVE
-                role = (role == Role.EQUAL) ? Role.SLAVE : role;
-                pendingXid = sendNxRoleRequest(role);
-                pendingRole = role;
-                roleSubmitTime = System.currentTimeMillis();
-                requestPending = true;
-            } else {
-                // OF1.3 switch, use OFPT_ROLE_REQUEST message
-                pendingXid = sendOF13RoleRequest(role);
-                pendingRole = role;
-                roleSubmitTime = System.currentTimeMillis();
-                requestPending = true;
-            }
-            return true;
-        }
-
-        /**
-         * Deliver a received role reply.
-         *
-         * Check if a request is pending and if the received reply matches the
-         * the expected pending reply (we check both role and xid) we set
-         * the role for the switch/channel.
-         *
-         * If a request is pending but doesn't match the reply we ignore it, and
-         * return
-         *
-         * If no request is pending we disconnect with a SwitchStateException
-         *
-         * @param RoleReplyInfo information about role-reply in format that
-         *                      controller can understand.
-         * @throws SwitchStateException if no request is pending
-         */
-        synchronized RoleRecvStatus deliverRoleReply(RoleReplyInfo rri)
-                throws SwitchStateException {
-            if (!requestPending) {
-                Role currentRole = (sw != null) ? sw.getRole() : null;
-                if (currentRole != null) {
-                    if (currentRole == rri.getRole()) {
-                        // Don't disconnect if the role reply we received is
-                        // for the same role we are already in.
-                        log.debug("Received unexpected RoleReply from "
-                                + "Switch: {} in State: {}. "
-                                + "Role in reply is same as current role of this "
-                                + "controller for this sw. Ignoring ...",
-                                getSwitchInfoString(), state.toString());
-                        return RoleRecvStatus.OTHER_EXPECTATION;
-                    } else {
-                        String msg = String.format("Switch: [%s], State: [%s], "
-                                + "received unexpected RoleReply[%s]. "
-                                + "No roles are pending, and this controller's "
-                                + "current role:[%s] does not match reply. "
-                                + "Disconnecting switch ... ",
-                                OFChannelHandler.this.getSwitchInfoString(),
-                                OFChannelHandler.this.state.toString(),
-                                rri, currentRole);
-                        throw new SwitchStateException(msg);
-                    }
-                }
-                log.debug("Received unexpected RoleReply {} from "
-                        + "Switch: {} in State: {}. "
-                        + "This controller has no current role for this sw. "
-                        + "Ignoring ...", new Object[] {rri,
-                                getSwitchInfoString(), state});
-                return RoleRecvStatus.OTHER_EXPECTATION;
-            }
-
-            int xid = (int) rri.getXid();
-            Role role = rri.getRole();
-            // XXX S should check generation id meaningfully and other cases of expectations
-            // U64 genId = rri.getGenId();
-
-            if (pendingXid != xid) {
-                log.debug("Received older role reply from " +
-                        "switch {} ({}). Ignoring. " +
-                        "Waiting for {}, xid={}",
-                        new Object[] {getSwitchInfoString(), rri,
-                        pendingRole, pendingXid });
-                return RoleRecvStatus.OLD_REPLY;
-            }
-
-            if (pendingRole == role) {
-                log.debug("Received role reply message from {} that matched "
-                        + "expected role-reply {} with expectations {}",
-                        new Object[] {getSwitchInfoString(), role, expectation});
-                counters.roleReplyReceived.updateCounterWithFlush();
-                //setSwitchRole(role, RoleRecvStatus.RECEIVED_REPLY); dont want to set state here
-                if (expectation == RoleRecvStatus.MATCHED_CURRENT_ROLE ||
-                        expectation == RoleRecvStatus.MATCHED_SET_ROLE) {
-                    return expectation;
-                } else {
-                    return RoleRecvStatus.OTHER_EXPECTATION;
-                }
-            }
-
-            // if xids match but role's don't, perhaps its a query (OF1.3)
-            if (expectation == RoleRecvStatus.REPLY_QUERY) {
-                return expectation;
-            }
-
-            return RoleRecvStatus.OTHER_EXPECTATION;
-        }
-
-        /**
-         * Called if we receive an  error message. If the xid matches the
-         * pending request we handle it otherwise we ignore it.
-         *
-         * Note: since we only keep the last pending request we might get
-         * error messages for earlier role requests that we won't be able
-         * to handle
-         */
-        synchronized RoleRecvStatus deliverError(OFErrorMsg error)
-                throws SwitchStateException {
-            if (!requestPending) {
-                log.debug("Received an error msg from sw {}, but no pending "
-                        + "requests in role-changer; not handling ...",
-                        getSwitchInfoString());
-                return RoleRecvStatus.OTHER_EXPECTATION;
-            }
-            if (pendingXid != error.getXid()) {
-                if (error.getErrType() == OFErrorType.ROLE_REQUEST_FAILED) {
-                    log.debug("Received an error msg from sw {} for a role request,"
-                            + " but not for pending request in role-changer; "
-                            + " ignoring error {} ...",
-                            getSwitchInfoString(), error);
-                }
-                return RoleRecvStatus.OTHER_EXPECTATION;
-            }
-            // it is an error related to a currently pending role request message
-            if (error.getErrType() == OFErrorType.BAD_REQUEST) {
-                counters.roleReplyErrorUnsupported.updateCounterWithFlush();
-                log.error("Received a error msg {} from sw {} in state {} for "
-                        + "pending role request {}. Switch driver indicates "
-                        + "role-messaging is supported. Possible issues in "
-                        + "switch driver configuration?", new Object[] {
-                                ((OFBadRequestErrorMsg) error).toString(),
-                                getSwitchInfoString(), state, pendingRole
-                        });
-                return RoleRecvStatus.UNSUPPORTED;
-            }
-
-            if (error.getErrType() == OFErrorType.ROLE_REQUEST_FAILED) {
-                OFRoleRequestFailedErrorMsg rrerr =
-                        (OFRoleRequestFailedErrorMsg) error;
-                switch (rrerr.getCode()) {
-                case BAD_ROLE:
-                    // switch says that current-role-req has bad role?
-                    // for now we disconnect
-                    // fall-thru
-                case STALE:
-                    // switch says that current-role-req has stale gen-id?
-                    // for now we disconnect
-                    // fall-thru
-                case UNSUP:
-                    // switch says that current-role-req has role that
-                    // cannot be supported? for now we disconnect
-                    String msgx = String.format("Switch: [%s], State: [%s], "
-                            + "received Error to for pending role request [%s]. "
-                            + "Error:[%s]. Disconnecting switch ... ",
-                            OFChannelHandler.this.getSwitchInfoString(),
-                            OFChannelHandler.this.state.toString(),
-                            pendingRole, rrerr);
-                    throw new SwitchStateException(msgx);
-                default:
-                    break;
-                }
-            }
-
-            // This error message was for a role request message but we dont know
-            // how to handle errors for nicira role request messages
-            return RoleRecvStatus.OTHER_EXPECTATION;
-        }
-
-        /**
-         * Check if a pending role request has timed out.
-         */
-        void checkTimeout() {
-            if (!requestPending) {
-                return;
-            }
-            synchronized (this) {
-                if (!requestPending) {
-                    return;
-                }
-                long now = System.currentTimeMillis();
-                if (now - roleSubmitTime > roleTimeoutMs) {
-                    // timeout triggered.
-                    counters.roleReplyTimeout.updateCounterWithFlush();
-                    //setSwitchRole(pendingRole, RoleRecvStatus.NO_REPLY);
-                    // XXX S come back to this
-                }
-            }
-        }
-
-    }
 
     //*************************
     //  Channel State Machine
@@ -628,8 +231,7 @@
                 log.info("Received features reply for switch at {} with dpid {}",
                         h.getSwitchInfoString(), h.thisdpid);
                 //update the controller about this connected switch
-                boolean success = h.controller.addConnectedSwitch(
-                        h.thisdpid, h);
+                boolean success = h.sw.addConnectedSwitch();
                 if (!success) {
                     disconnectDuplicate(h);
                     return;
@@ -825,41 +427,16 @@
                 h.sw.setConnected(true);
                 h.sw.setChannel(h.channel);
 
-                try {
-                    h.sw.setDebugCounterService(h.controller.getDebugCounter());
-                } catch (CounterException e) {
-                    h.counters.switchCounterRegistrationFailed
-                    .updateCounterNoFlush();
-                    log.warn("Could not register counters for switch {} ",
-                            h.getSwitchInfoString(), e);
-                }
 
                 log.info("Switch {} bound to class {}, description {}",
                         new Object[] {h.sw, h.sw.getClass(), drep });
                 //Put switch in EQUAL mode until we hear back from the global registry
                 log.debug("Setting new switch {} to EQUAL and sending Role request",
                         h.sw.getStringId());
-                h.setSwitchRole(Role.EQUAL);
-                try {
-                    boolean supportsRRMsg = h.roleChanger.sendRoleRequest(Role.EQUAL,
-                            RoleRecvStatus.MATCHED_CURRENT_ROLE);
-                    if (!supportsRRMsg) {
-                        log.warn("Switch {} does not support role request messages "
-                                + "of any kind. No role messages were sent. "
-                                + "This controller instance SHOULD become MASTER "
-                                + "from the registry process. ",
-                                h.getSwitchInfoString());
-                    }
-                    h.setState(WAIT_INITIAL_ROLE);
-                    // request control of switch from global registry -
-                    // necessary even if this is the only controller the
-                    // switch is connected to.
-                    h.controller.submitRegistryRequest(h.sw.getId());
-                } catch (IOException e) {
-                    log.error("Exception when sending role request: {} ",
-                            e.getMessage());
-                    // FIXME shouldn't we disconnect?
-                }
+                h.setSwitchRole(RoleState.EQUAL);
+                h.sw.startDriverHandshake();
+                h.setState(WAIT_SWITCH_DRIVER_SUB_HANDSHAKE);
+
             }
 
             @Override
@@ -880,133 +457,6 @@
             }
         },
 
-        /**
-         * We are waiting for a role reply message in response to a role request
-         * sent after hearing back from the registry service -- OR -- we are
-         * just waiting to hear back from the registry service in the case that
-         * the switch does not support role messages. If completed successfully,
-         * the controller's role for this switch will be set here.
-         * Before we move to the state corresponding to the role, we allow the
-         * switch specific driver to complete its configuration. This configuration
-         * typically depends on the role the controller is playing for this switch.
-         * And so we set the switch role (for 'this' controller) before we start
-         * the driver-sub-handshake.
-         * Next State: WAIT_SWITCH_DRIVER_SUB_HANDSHAKE
-         */
-        WAIT_INITIAL_ROLE(false) {
-            @Override
-            void processOFError(OFChannelHandler h, OFErrorMsg m)
-                    throws SwitchStateException {
-                // role changer will ignore the error if it isn't for it
-                RoleRecvStatus rrstatus = h.roleChanger.deliverError(m);
-                if (rrstatus == RoleRecvStatus.OTHER_EXPECTATION) {
-                    logError(h, m);
-                }
-            }
-
-            @Override
-            void processOFExperimenter(OFChannelHandler h, OFExperimenter m)
-                    throws IOException, SwitchStateException {
-                Role role = extractNiciraRoleReply(h, m);
-                // If role == null it means the vendor (experimenter) message
-                // wasn't really a Nicira role reply. We ignore this case.
-                if (role != null) {
-                    RoleReplyInfo rri = new RoleReplyInfo(role, null, m.getXid());
-                    RoleRecvStatus rrs = h.roleChanger.deliverRoleReply(rri);
-                    if (rrs == RoleRecvStatus.MATCHED_SET_ROLE) {
-                        setRoleAndStartDriverHandshake(h, rri.getRole());
-                    } // else do nothing - wait for the correct expected reply
-                } else {
-                    unhandledMessageReceived(h, m);
-                }
-            }
-
-            @Override
-            void processOFRoleReply(OFChannelHandler h, OFRoleReply m)
-                    throws SwitchStateException, IOException {
-                RoleReplyInfo rri = extractOFRoleReply(h, m);
-                RoleRecvStatus rrs = h.roleChanger.deliverRoleReply(rri);
-                if (rrs == RoleRecvStatus.MATCHED_SET_ROLE) {
-                    setRoleAndStartDriverHandshake(h, rri.getRole());
-                } // else do nothing - wait for the correct expected reply
-            }
-
-            @Override
-            void handleUnsentRoleMessage(OFChannelHandler h, Role role,
-                    RoleRecvStatus expectation) throws IOException {
-                // typically this is triggered for a switch where role messages
-                // are not supported - we confirm that the role being set is
-                // master and move to the next state
-                if (expectation == RoleRecvStatus.MATCHED_SET_ROLE) {
-                    if (role == Role.MASTER) {
-                        setRoleAndStartDriverHandshake(h, role);
-                    } else {
-                        log.error("Expected MASTER role from registry for switch "
-                                + "which has no support for role-messages."
-                                + "Received {}. It is possible that this switch "
-                                + "is connected to other controllers, in which "
-                                + "case it should support role messages - not "
-                                + "moving forward.", role);
-                    }
-                } // else do nothing - wait to hear back from registry
-
-            }
-
-            private void setRoleAndStartDriverHandshake(OFChannelHandler h,
-                    Role role) throws IOException {
-                h.setSwitchRole(role);
-                h.sw.startDriverHandshake();
-                if (h.sw.isDriverHandshakeComplete()) {
-                    Role mySwitchRole = h.sw.getRole();
-                    if (mySwitchRole == Role.MASTER) {
-                        log.info("Switch-driver sub-handshake complete. "
-                                + "Activating switch {} with Role: MASTER",
-                                h.getSwitchInfoString());
-                        handlePendingPortStatusMessages(h); //before activation
-                        boolean success = h.controller.addActivatedMasterSwitch(
-                                h.sw.getId(), h.sw);
-                        if (!success) {
-                            disconnectDuplicate(h);
-                            return;
-                        }
-                        h.setState(MASTER);
-                    } else {
-                        log.info("Switch-driver sub-handshake complete. "
-                                + "Activating switch {} with Role: EQUAL",
-                                h.getSwitchInfoString());
-                        handlePendingPortStatusMessages(h); //before activation
-                        boolean success = h.controller.addActivatedEqualSwitch(
-                                h.sw.getId(), h.sw);
-                        if (!success) {
-                            disconnectDuplicate(h);
-                            return;
-                        }
-                        h.setState(EQUAL);
-                    }
-                } else {
-                    h.setState(WAIT_SWITCH_DRIVER_SUB_HANDSHAKE);
-                }
-            }
-
-            @Override
-            void processOFFeaturesReply(OFChannelHandler h, OFFeaturesReply  m)
-                    throws IOException, SwitchStateException {
-                illegalMessageReceived(h, m);
-            }
-
-            @Override
-            void processOFStatisticsReply(OFChannelHandler h, OFStatsReply m)
-                    throws SwitchStateException {
-                illegalMessageReceived(h, m);
-            }
-
-            @Override
-            void processOFPortStatus(OFChannelHandler h, OFPortStatus m)
-                    throws IOException, SwitchStateException {
-                h.pendingPortStatusMsg.add(m);
-
-            }
-        },
 
         /**
          * We are waiting for the respective switch driver to complete its
@@ -1026,39 +476,27 @@
 
             @Override
             void processOFMessage(OFChannelHandler h, OFMessage m)
-                    throws IOException {
+                    throws IOException, SwitchStateException {
                 if (m.getType() == OFType.ECHO_REQUEST) {
                     processOFEchoRequest(h, (OFEchoRequest) m);
+                } else if (m.getType() == OFType.ROLE_REPLY) {
+                    h.sw.handleRole(m);
+                } else if (m.getType() == OFType.ERROR) {
+                    if (!h.sw.handleRoleError((OFErrorMsg)m)) {
+                        h.sw.processDriverHandshakeMessage(m);
+                        if (h.sw.isDriverHandshakeComplete()) {
+                            h.setState(ACTIVE);
+                        }
+                    }
                 } else {
-                    // FIXME: other message to handle here?
-                    h.sw.processDriverHandshakeMessage(m);
-                    if (h.sw.isDriverHandshakeComplete()) {
-                        // consult the h.sw role and goto that state
-                        Role mySwitchRole = h.sw.getRole();
-                        if (mySwitchRole == Role.MASTER) {
-                            log.info("Switch-driver sub-handshake complete. "
-                                    + "Activating switch {} with Role: MASTER",
-                                    h.getSwitchInfoString());
-                            handlePendingPortStatusMessages(h); //before activation
-                            boolean success = h.controller.addActivatedMasterSwitch(
-                                    h.sw.getId(), h.sw);
-                            if (!success) {
-                                disconnectDuplicate(h);
-                                return;
-                            }
-                            h.setState(MASTER);
-                        } else {
-                            log.info("Switch-driver sub-handshake complete. "
-                                    + "Activating switch {} with Role: EQUAL",
-                                    h.getSwitchInfoString());
-                            handlePendingPortStatusMessages(h); //before activation
-                            boolean success = h.controller.addActivatedEqualSwitch(
-                                    h.sw.getId(), h.sw);
-                            if (!success) {
-                                disconnectDuplicate(h);
-                                return;
-                            }
-                            h.setState(EQUAL);
+                    if (m.getType() == OFType.EXPERIMENTER && 
+                            ((OFExperimenter) m).getExperimenter() == 
+                            RoleManager.NICIRA_EXPERIMENTER) {
+                        h.sw.handleNiciraRole(m);
+                    } else {
+                        h.sw.processDriverHandshakeMessage(m);
+                        if (h.sw.isDriverHandshakeComplete()) {
+                            h.setState(ACTIVE);
                         }
                     }
                 }
@@ -1084,7 +522,7 @@
          * if we send a role request for SLAVE /and/ receive the role reply for
          * SLAVE.
          */
-        MASTER(true) {
+        ACTIVE(true) {
             @LogMessageDoc(level = "WARN",
                     message = "Received permission error from switch {} while"
                             + "being master. Reasserting master role.",
@@ -1097,13 +535,6 @@
             @Override
             void processOFError(OFChannelHandler h, OFErrorMsg m)
                     throws IOException, SwitchStateException {
-                // first check if the error msg is in response to a role-request message
-                RoleRecvStatus rrstatus = h.roleChanger.deliverError(m);
-                if (rrstatus != RoleRecvStatus.OTHER_EXPECTATION) {
-                    // rolechanger has handled the error message - we are done
-                    return;
-                }
-
                 // if we get here, then the error message is for something else
                 if (m.getErrType() == OFErrorType.BAD_REQUEST &&
                         ((OFBadRequestErrorMsg) m).getCode() ==
@@ -1116,13 +547,10 @@
                     // if two controllers are master (even if its only for
                     // a brief period). We might need to see if these errors
                     // persist before we reassert
-                    h.counters.epermErrorWhileSwitchIsMaster.updateCounterWithFlush();
                     log.warn("Received permission error from switch {} while" +
                             "being master. Reasserting master role.",
                             h.getSwitchInfoString());
-                    //h.controller.reassertRole(h, Role.MASTER);
-                    // XXX S reassert in role changer or reconsider if all this
-                    // stuff is really needed
+                    h.sw.reassertRole();
                 } else if (m.getErrType() == OFErrorType.FLOW_MOD_FAILED &&
                         ((OFFlowModFailedErrorMsg) m).getCode() ==
                         OFFlowModFailedCode.ALL_TABLES_FULL) {
@@ -1136,35 +564,19 @@
             @Override
             void processOFStatisticsReply(OFChannelHandler h,
                     OFStatsReply m) {
-                h.sw.deliverStatisticsReply(m);
+                h.sw.handleMessage(m);
             }
 
             @Override
             void processOFExperimenter(OFChannelHandler h, OFExperimenter m)
                     throws IOException, SwitchStateException {
-                Role role = extractNiciraRoleReply(h, m);
-                if (role == null) {
-                    // The message wasn't really a Nicira role reply. We just
-                    // dispatch it to the OFMessage listeners in this case.
-                    h.dispatchMessage(m);
-                    return;
-                }
-
-                RoleRecvStatus rrs = h.roleChanger.deliverRoleReply(
-                        new RoleReplyInfo(role, null, m.getXid()));
-                if (rrs == RoleRecvStatus.MATCHED_SET_ROLE) {
-                    checkAndSetRoleTransition(h, role);
-                }
+                h.sw.handleNiciraRole(m);
             }
 
             @Override
             void processOFRoleReply(OFChannelHandler h, OFRoleReply m)
                     throws SwitchStateException, IOException {
-                RoleReplyInfo rri = extractOFRoleReply(h, m);
-                RoleRecvStatus rrs = h.roleChanger.deliverRoleReply(rri);
-                if (rrs == RoleRecvStatus.MATCHED_SET_ROLE) {
-                    checkAndSetRoleTransition(h, rri.getRole());
-                }
+                h.sw.handleRole(m);
             }
 
             @Override
@@ -1192,95 +604,6 @@
                 h.dispatchMessage(m);
             }
 
-        },
-
-        /**
-         * This controller is in EQUAL role for this switch. We enter this state
-         * after some /other/ controller instance wins mastership-role over this
-         * switch. The EQUAL role can be considered the same as the SLAVE role
-         * if this controller does NOT send commands or packets to the switch.
-         * This should always be true for OF1.0 switches. XXX S need to enforce.
-         *
-         * For OF1.3 switches, choosing this state as EQUAL instead of SLAVE,
-         * gives us the flexibility that if an app wants to send commands/packets
-         * to switches, it can, even thought it is running on a controller instance
-         * that is not in a MASTER role for this switch. Of course, it is the job
-         * of the app to ensure that commands/packets sent by this (EQUAL) controller
-         * instance does not clash/conflict with commands/packets sent by the MASTER
-         * controller for this switch. Neither the controller instances, nor the
-         * switch provides any kind of resolution mechanism should conflicts occur.
-         */
-        EQUAL(true) {
-            @Override
-            void processOFError(OFChannelHandler h, OFErrorMsg m)
-                    throws IOException, SwitchStateException {
-                // role changer will ignore the error if it isn't for it
-                RoleRecvStatus rrstatus = h.roleChanger.deliverError(m);
-                if (rrstatus == RoleRecvStatus.OTHER_EXPECTATION) {
-                    logError(h, m);
-                    h.dispatchMessage(m);
-                }
-            }
-
-            @Override
-            void processOFStatisticsReply(OFChannelHandler h,
-                    OFStatsReply m) {
-                h.sw.deliverStatisticsReply(m);
-            }
-
-            @Override
-            void processOFExperimenter(OFChannelHandler h, OFExperimenter m)
-                    throws IOException, SwitchStateException {
-                Role role = extractNiciraRoleReply(h, m);
-                // If role == null it means the message wasn't really a
-                // Nicira role reply. We ignore it in this state.
-                if (role != null) {
-                    RoleRecvStatus rrs = h.roleChanger.deliverRoleReply(
-                            new RoleReplyInfo(role, null, m.getXid()));
-                    if (rrs == RoleRecvStatus.MATCHED_SET_ROLE) {
-                        checkAndSetRoleTransition(h, role);
-                    }
-                } else {
-                    unhandledMessageReceived(h, m);
-                }
-            }
-
-            @Override
-            void processOFRoleReply(OFChannelHandler h, OFRoleReply m)
-                    throws SwitchStateException, IOException {
-                RoleReplyInfo rri = extractOFRoleReply(h, m);
-                RoleRecvStatus rrs = h.roleChanger.deliverRoleReply(rri);
-                if (rrs == RoleRecvStatus.MATCHED_SET_ROLE) {
-                    checkAndSetRoleTransition(h, rri.getRole());
-                }
-            }
-
-            // XXX S needs more handlers for 1.3 switches in equal role
-
-            @Override
-            void processOFPortStatus(OFChannelHandler h, OFPortStatus m)
-                    throws IOException, SwitchStateException {
-                handlePortStatusMessage(h, m, true);
-            }
-
-            @Override
-            @LogMessageDoc(level = "WARN",
-            message = "Received PacketIn from switch {} while "
-                    + "being slave. Reasserting slave role.",
-                    explanation = "The switch has receive a PacketIn despite being "
-                            + "in slave role indicating inconsistent controller roles",
-                            recommendation = "This situation can occurs transiently during role"
-                                    + " changes. If, however, the condition persists or happens"
-                                    + " frequently this indicates a role inconsistency. "
-                                    + LogMessageDoc.CHECK_CONTROLLER)
-            void processOFPacketIn(OFChannelHandler h, OFPacketIn m) throws IOException {
-                // we don't expect packetIn while slave, reassert we are slave
-                h.counters.packetInWhileSwitchIsSlave.updateCounterNoFlush();
-                log.warn("Received PacketIn from switch {} while" +
-                        "being slave. Reasserting slave role.", h.sw);
-                //h.controller.reassertRole(h, Role.SLAVE);
-                // XXX reassert in role changer
-            }
         };
 
         private final boolean handshakeComplete;
@@ -1345,7 +668,6 @@
          */
         protected void unhandledMessageReceived(OFChannelHandler h,
                 OFMessage m) {
-            h.counters.unhandledMessage.updateCounterNoFlush();
             if (log.isDebugEnabled()) {
                 String msg = getSwitchStateMessage(h, m,
                         "Ignoring unexpected message");
@@ -1398,108 +720,7 @@
             h.channel.disconnect();
         }
 
-        /**
-         * Extract the role from an OFVendor message.
-         *
-         * Extract the role from an OFVendor message if the message is a
-         * Nicira role reply. Otherwise return null.
-         *
-         * @param h The channel handler receiving the message
-         * @param vendorMessage The vendor message to parse.
-         * @return The role in the message if the message is a Nicira role
-         * reply, null otherwise.
-         * @throws SwitchStateException If the message is a Nicira role reply
-         * but the numeric role value is unknown.
-         */
-        protected Role extractNiciraRoleReply(OFChannelHandler h,
-                OFExperimenter experimenterMsg) throws SwitchStateException {
-            int vendor = (int) experimenterMsg.getExperimenter();
-            if (vendor != 0x2320) {
-                return null;
-            }
-            OFNiciraControllerRoleReply nrr =
-                    (OFNiciraControllerRoleReply) experimenterMsg;
 
-            Role role = null;
-            OFNiciraControllerRole ncr = nrr.getRole();
-            switch(ncr) {
-            case ROLE_MASTER:
-                role = Role.MASTER;
-                break;
-            case ROLE_OTHER:
-                role = Role.EQUAL;
-                break;
-            case ROLE_SLAVE:
-                role = Role.SLAVE;
-                break;
-            default: //handled below
-            }
-
-            if (role == null) {
-                String msg = String.format("Switch: [%s], State: [%s], "
-                        + "received NX_ROLE_REPLY with invalid role "
-                        + "value %s",
-                        h.getSwitchInfoString(),
-                        this.toString(),
-                        nrr.getRole());
-                throw new SwitchStateException(msg);
-            }
-            return role;
-        }
-
-        /**
-         * Helper class returns role reply information in the format understood
-         * by the controller.
-         */
-        protected static class RoleReplyInfo {
-            private Role role;
-            private U64 genId;
-            private long xid;
-
-            RoleReplyInfo(Role role, U64 genId, long xid) {
-                this.role = role;
-                this.genId = genId;
-                this.xid = xid;
-            }
-            public Role getRole() { return role; }
-            public U64 getGenId() { return genId; }
-            public long getXid() { return xid; }
-            @Override
-            public String toString() {
-                return "[Role:" + role + " GenId:" + genId + " Xid:" + xid + "]";
-            }
-        }
-
-        /**
-         * Extract the role information from an OF1.3 Role Reply Message.
-         * @param h
-         * @param rrmsg
-         * @return RoleReplyInfo object
-         * @throws SwitchStateException
-         */
-        protected RoleReplyInfo extractOFRoleReply(OFChannelHandler h,
-                OFRoleReply rrmsg) throws SwitchStateException {
-            OFControllerRole cr = rrmsg.getRole();
-            Role role = null;
-            switch(cr) {
-            case ROLE_EQUAL:
-                role = Role.EQUAL;
-                break;
-            case ROLE_MASTER:
-                role = Role.MASTER;
-                break;
-            case ROLE_SLAVE:
-                role = Role.SLAVE;
-                break;
-            case ROLE_NOCHANGE: // switch should send current role
-            default:
-                String msg = String.format("Unknown controller role %s "
-                        + "received from switch %s", cr, h.sw);
-                throw new SwitchStateException(msg);
-            }
-
-            return new RoleReplyInfo(role, rrmsg.getGenerationId(), rrmsg.getXid());
-        }
 
         /**
          * Handles all pending port status messages before a switch is declared
@@ -1567,52 +788,9 @@
                 throw new SwitchStateException(msg);
             }
 
-            Collection<PortChangeEvent> changes = h.sw.processOFPortStatus(m);
-            if (doNotify) {
-                for (PortChangeEvent ev: changes) {
-                    h.controller.notifyPortChanged(h.sw.getId(), ev.port, ev.type);
-                }
-            }
+            h.sw.handleMessage(m);
         }
 
-        /**
-         * Checks if the role received (from the role-reply msg) is different
-         * from the existing role in the IOFSwitch object for this controller.
-         * If so, it transitions the controller to the new role. Note that
-         * the caller should have already verified that the role-reply msg
-         * received was in response to a role-request msg sent out by this
-         * controller after hearing from the registry service.
-         *
-         * @param h the ChannelHandler that received the message
-         * @param role the role in the recieved role reply message
-         */
-        protected void checkAndSetRoleTransition(OFChannelHandler h, Role role) {
-            // we received a role-reply in response to a role message
-            // sent after hearing from the registry service. It is
-            // possible that the role of this controller instance for
-            // this switch has changed:
-            // for 1.0 switch: from MASTER to SLAVE
-            // for 1.3 switch: from MASTER to EQUAL
-            if ((h.sw.getRole() == Role.MASTER && role == Role.SLAVE) ||
-                    (h.sw.getRole() == Role.MASTER && role == Role.EQUAL)) {
-                // the mastership has changed
-                h.sw.setRole(role);
-                h.setState(EQUAL);
-                h.controller.transitionToEqualSwitch(h.sw.getId());
-                return;
-            }
-
-            // or for both 1.0 and 1.3 switches from EQUAL to MASTER.
-            // note that for 1.0, even though we mean SLAVE,
-            // internally we call the role EQUAL.
-            if (h.sw.getRole() == Role.EQUAL && role == Role.MASTER) {
-                // the mastership has changed
-                h.sw.setRole(role);
-                h.setState(MASTER);
-                h.controller.transitionToMasterSwitch(h.sw.getId());
-                return;
-            }
-        }
 
         /**
          * Process an OF message received on the channel and
@@ -1635,7 +813,6 @@
          */
         void processOFMessage(OFChannelHandler h, OFMessage m)
                 throws IOException, SwitchStateException {
-            h.roleChanger.checkTimeout();
             switch(m.getType()) {
             case HELLO:
                 processOFHello(h, (OFHello) m);
@@ -1812,10 +989,6 @@
             unhandledMessageReceived(h, m);
         }
 
-        void handleUnsentRoleMessage(OFChannelHandler h, Role role,
-                RoleRecvStatus expectation) throws IOException {
-            // do nothing in most states
-        }
     }
 
 
@@ -1830,7 +1003,6 @@
             + "specified IP address")
     public void channelConnected(ChannelHandlerContext ctx,
             ChannelStateEvent e) throws Exception {
-        counters.switchConnected.updateCounterWithFlush();
         channel = e.getChannel();
         log.info("New switch connection from {}",
                 channel.getRemoteAddress());
@@ -1853,7 +1025,7 @@
                 // switch was a duplicate-dpid, calling the method below would clear
                 // all state for the original switch (with the same dpid),
                 // which we obviously don't want.
-                controller.removeConnectedSwitch(thisdpid);
+                sw.removeConnectedSwitch();
             } else {
                 // A duplicate was disconnected on this ChannelHandler,
                 // this is the same switch reconnecting, but the original state was
@@ -1914,12 +1086,10 @@
             // switch timeout
             log.error("Disconnecting switch {} due to read timeout",
                     getSwitchInfoString());
-            counters.switchDisconnectReadTimeout.updateCounterWithFlush();
             ctx.getChannel().close();
         } else if (e.getCause() instanceof HandshakeTimeoutException) {
             log.error("Disconnecting switch {}: failed to complete handshake",
                     getSwitchInfoString());
-            counters.switchDisconnectHandshakeTimeout.updateCounterWithFlush();
             ctx.getChannel().close();
         } else if (e.getCause() instanceof ClosedChannelException) {
             log.debug("Channel for sw {} already closed", getSwitchInfoString());
@@ -1930,7 +1100,6 @@
                 // still print stack trace if debug is enabled
                 log.debug("StackTrace for previous Exception: ", e.getCause());
             }
-            counters.switchDisconnectIOError.updateCounterWithFlush();
             ctx.getChannel().close();
         } else if (e.getCause() instanceof SwitchStateException) {
             log.error("Disconnecting switch {} due to switch state error: {}",
@@ -1939,23 +1108,19 @@
                 // still print stack trace if debug is enabled
                 log.debug("StackTrace for previous Exception: ", e.getCause());
             }
-            counters.switchDisconnectSwitchStateException.updateCounterWithFlush();
             ctx.getChannel().close();
         } else if (e.getCause() instanceof OFParseError) {
             log.error("Disconnecting switch "
                     + getSwitchInfoString() +
                     " due to message parse failure",
                     e.getCause());
-            counters.switchDisconnectParseError.updateCounterWithFlush();
             ctx.getChannel().close();
         } else if (e.getCause() instanceof RejectedExecutionException) {
             log.warn("Could not process message: queue full");
-            counters.rejectedExecutionException.updateCounterWithFlush();
         } else {
             log.error("Error while processing message from switch "
                     + getSwitchInfoString()
                     + "state " + this.state, e.getCause());
-            counters.switchDisconnectOtherException.updateCounterWithFlush();
             ctx.getChannel().close();
         }
     }
@@ -1986,12 +1151,10 @@
 
 
             for (OFMessage ofm : msglist) {
-                counters.messageReceived.updateCounterNoFlush();
                 // Do the actual packet processing
                 state.processOFMessage(this, ofm);
             }
         } else {
-            counters.messageReceived.updateCounterNoFlush();
             state.processOFMessage(this, (OFMessage) e.getMessage());
         }
     }
@@ -2080,7 +1243,7 @@
         channel.write(Collections.singletonList(m));
     }
 
-    private void setSwitchRole(Role role) {
+    private void setSwitchRole(RoleState role) {
         sw.setRole(role);
     }
 
@@ -2146,9 +1309,4 @@
         return state;
     }
 
-    void useRoleChangerWithOtherTimeoutForTesting(long roleTimeoutMs) {
-        roleChanger = new RoleChanger(roleTimeoutMs);
-    }
-
-
 }
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/OpenFlowControllerImpl.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/OpenFlowControllerImpl.java
new file mode 100644
index 0000000..976e347
--- /dev/null
+++ b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/OpenFlowControllerImpl.java
@@ -0,0 +1,263 @@
+package org.onlab.onos.of.controller.impl.internal;
+
+import java.util.ArrayList;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.onos.of.controller.Dpid;
+import org.onlab.onos.of.controller.OpenFlowController;
+import org.onlab.onos.of.controller.OpenFlowSwitch;
+import org.onlab.onos.of.controller.OpenFlowSwitchListener;
+import org.onlab.onos.of.controller.PacketListener;
+import org.onlab.onos.of.controller.RoleState;
+import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.util.HexString;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Component(immediate = true)
+@Service
+public class OpenFlowControllerImpl implements OpenFlowController {
+
+    protected ConcurrentHashMap<Long, OpenFlowSwitch> connectedSwitches;
+    protected ConcurrentHashMap<Long, OpenFlowSwitch> activeMasterSwitches;
+    protected ConcurrentHashMap<Long, OpenFlowSwitch> activeEqualSwitches;
+
+    protected OpenFlowSwitchAgent agent = new OpenFlowSwitchAgent();
+    protected ArrayList<OpenFlowSwitchListener> ofEventListener;
+
+    private final Controller ctrl = new Controller();
+
+    @Activate
+    public void activate() {
+        ctrl.start(agent);
+    }
+
+    @Deactivate
+    public void deactivate() {
+        ctrl.stop();
+    }
+
+    @Override
+    public Iterable<OpenFlowSwitch> getSwitches() {
+        return connectedSwitches.values();
+    }
+
+    @Override
+    public Iterable<OpenFlowSwitch> getMasterSwitches() {
+        return activeMasterSwitches.values();
+    }
+
+    @Override
+    public Iterable<OpenFlowSwitch> getEqualSwitches() {
+        return activeEqualSwitches.values();
+    }
+
+    @Override
+    public OpenFlowSwitch getSwitch(Dpid dpid) {
+        return connectedSwitches.get(dpid.value());
+    }
+
+    @Override
+    public OpenFlowSwitch getMasterSwitch(Dpid dpid) {
+        return activeMasterSwitches.get(dpid.value());
+    }
+
+    @Override
+    public OpenFlowSwitch getEqualSwitch(Dpid dpid) {
+        return activeEqualSwitches.get(dpid.value());    }
+
+    @Override
+    public void addListener(OpenFlowSwitchListener listener) {
+        if (!ofEventListener.contains(listener)) {
+            this.ofEventListener.add(listener);
+        }
+    }
+
+    @Override
+    public void removeListener(OpenFlowSwitchListener listener) {
+        this.ofEventListener.remove(listener);
+    }
+
+    @Override
+    public void addPacketListener(int priority, PacketListener listener) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void removePacketListener(PacketListener listener) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void write(Dpid dpid, OFMessage msg) {
+        this.getSwitch(dpid).write(msg);
+    }
+
+    @Override
+    public void processPacket(OFMessage msg) {
+    }
+
+    @Override
+    public void setRole(Dpid dpid, RoleState role) {
+        switch (role) {
+        case MASTER:
+            agent.transitionToMasterSwitch(dpid.value());
+            break;
+        case EQUAL:
+            agent.transitionToEqualSwitch(dpid.value());
+            break;
+        case SLAVE:
+            //agent.transitionToSlaveSwitch(dpid.value());
+            break;
+        default:
+            //WTF role is this?
+        }
+
+    }
+
+    public class OpenFlowSwitchAgent {
+
+        private final Logger log = LoggerFactory.getLogger(OpenFlowSwitchAgent.class);
+        private Lock switchLock = new ReentrantLock();
+
+        public boolean addConnectedSwitch(long dpid, AbstractOpenFlowSwitch sw) {
+            if (connectedSwitches.get(dpid) != null) {
+                log.error("Trying to add connectedSwitch but found a previous "
+                        + "value for dpid: {}", dpid);
+                return false;
+            } else {
+                log.error("Added switch {}", dpid);
+                connectedSwitches.put(dpid, sw);
+                for (OpenFlowSwitchListener l : ofEventListener) {
+                    l.switchAdded(new Dpid(dpid));
+                }
+                return true;
+            }
+        }
+
+        private boolean validActivation(long dpid) {
+            if (connectedSwitches.get(dpid) == null) {
+                log.error("Trying to activate switch but is not in "
+                        + "connected switches: dpid {}. Aborting ..",
+                        HexString.toHexString(dpid));
+                return false;
+            }
+            if (activeMasterSwitches.get(dpid) != null ||
+                    activeEqualSwitches.get(dpid) != null) {
+                log.error("Trying to activate switch but it is already "
+                        + "activated: dpid {}. Found in activeMaster: {} "
+                        + "Found in activeEqual: {}. Aborting ..", new Object[] {
+                                HexString.toHexString(dpid),
+                                (activeMasterSwitches.get(dpid) == null) ? 'N' : 'Y',
+                                (activeEqualSwitches.get(dpid) == null) ? 'N' : 'Y'});
+                return false;
+            }
+            return true;
+        }
+
+        /**
+         * Called when a switch is activated, with this controller's role as MASTER.
+         */
+        protected boolean addActivatedMasterSwitch(long dpid, AbstractOpenFlowSwitch sw) {
+            switchLock.lock();
+            try {
+                if (!validActivation(dpid)) {
+                    return false;
+                }
+                activeMasterSwitches.put(dpid, sw);
+                return true;
+            } finally {
+                switchLock.unlock();
+            }
+    }
+
+        /**
+         * Called when a switch is activated, with this controller's role as EQUAL.
+         */
+        protected boolean addActivatedEqualSwitch(long dpid, AbstractOpenFlowSwitch sw) {
+            switchLock.lock();
+            try {
+                    if (!validActivation(dpid)) {
+                        return false;
+                    }
+                    activeEqualSwitches.put(dpid, sw);
+                    return true;
+            } finally {
+                switchLock.unlock();
+            }
+        }
+
+        /**
+         * Called when this controller's role for a switch transitions from equal
+         * to master. For 1.0 switches, we internally refer to the role 'slave' as
+         * 'equal' - so this transition is equivalent to 'addActivatedMasterSwitch'.
+         */
+        protected void transitionToMasterSwitch(long dpid) {
+            switchLock.lock();
+            try {
+                OpenFlowSwitch sw = activeEqualSwitches.remove(dpid);
+                if (sw == null) {
+                    log.error("Transition to master called on sw {}, but switch "
+                            + "was not found in controller-cache", dpid);
+                    return;
+                }
+                activeMasterSwitches.put(dpid, sw);
+            } finally {
+                switchLock.unlock();
+            }
+        }
+
+
+        /**
+         * Called when this controller's role for a switch transitions to equal.
+         * For 1.0 switches, we internally refer to the role 'slave' as
+         * 'equal'.
+         */
+        protected void transitionToEqualSwitch(long dpid) {
+            switchLock.lock();
+            try {
+                OpenFlowSwitch sw = activeMasterSwitches.remove(dpid);
+                if (sw == null) {
+                    log.error("Transition to equal called on sw {}, but switch "
+                            + "was not found in controller-cache", dpid);
+                    return;
+                }
+                activeEqualSwitches.put(dpid, sw);
+            } finally {
+                switchLock.unlock();
+            }
+
+        }
+
+        /**
+         * Clear all state in controller switch maps for a switch that has
+         * disconnected from the local controller. Also release control for
+         * that switch from the global repository. Notify switch listeners.
+         */
+        public void removeConnectedSwitch(long dpid) {
+            connectedSwitches.remove(dpid);
+            OpenFlowSwitch sw = activeMasterSwitches.remove(dpid);
+            if (sw == null) {
+                sw = activeEqualSwitches.remove(dpid);
+            }
+            for (OpenFlowSwitchListener l : ofEventListener) {
+                l.switchRemoved(new Dpid(dpid));
+            }
+        }
+
+        public void processMessage(OFMessage m) {
+            processPacket(m);
+        }
+    }
+
+
+
+}
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/RoleManager.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/RoleManager.java
new file mode 100644
index 0000000..f31487a
--- /dev/null
+++ b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/internal/RoleManager.java
@@ -0,0 +1,708 @@
+package org.onlab.onos.of.controller.impl.internal;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.onlab.onos.of.controller.RoleState;
+import org.projectfloodlight.openflow.protocol.OFControllerRole;
+import org.projectfloodlight.openflow.protocol.OFErrorMsg;
+import org.projectfloodlight.openflow.protocol.OFErrorType;
+import org.projectfloodlight.openflow.protocol.OFExperimenter;
+import org.projectfloodlight.openflow.protocol.OFFactories;
+import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFNiciraControllerRole;
+import org.projectfloodlight.openflow.protocol.OFNiciraControllerRoleReply;
+import org.projectfloodlight.openflow.protocol.OFRoleReply;
+import org.projectfloodlight.openflow.protocol.OFRoleRequest;
+import org.projectfloodlight.openflow.protocol.OFVersion;
+import org.projectfloodlight.openflow.protocol.errormsg.OFBadRequestErrorMsg;
+import org.projectfloodlight.openflow.protocol.errormsg.OFRoleRequestFailedErrorMsg;
+import org.projectfloodlight.openflow.types.U64;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * A utility class to handle role requests and replies for this channel.
+ * After a role request is submitted the role changer keeps track of the
+ * pending request, collects the reply (if any) and times out the request
+ * if necessary.
+ *
+ * To simplify role handling we only keep track of the /last/ pending
+ * role reply send to the switch. If multiple requests are pending and
+ * we receive replies for earlier requests we ignore them. However, this
+ * way of handling pending requests implies that we could wait forever if
+ * a new request is submitted before the timeout triggers. If necessary
+ * we could work around that though.
+ */
+class RoleManager {
+    protected static final long NICIRA_EXPERIMENTER = 0x2320;
+
+    private static Logger log = LoggerFactory.getLogger(RoleManager.class);
+    // indicates that a request is currently pending
+    // needs to be volatile to allow correct double-check idiom
+    private volatile boolean requestPending;
+    // the transaction Id of the pending request
+    private int pendingXid;
+    // the role that's pending
+    private RoleState pendingRole;
+
+    // the expectation set by the caller for the returned role
+    private RoleRecvStatus expectation;
+    private AtomicInteger xidCounter;
+    private AbstractOpenFlowSwitch sw;
+
+
+    public RoleManager(AbstractOpenFlowSwitch sw) {
+        this.requestPending = false;
+        this.pendingXid = -1;
+        this.pendingRole = null;
+        this.xidCounter = new AtomicInteger(0);
+        this.expectation = RoleRecvStatus.MATCHED_CURRENT_ROLE;
+        this.sw = sw;
+    }
+
+    /**
+     * Send NX role request message to the switch requesting the specified
+     * role.
+     *
+     * @param sw switch to send the role request message to
+     * @param role role to request
+     */
+    private int sendNxRoleRequest(RoleState role) throws IOException {
+        // Convert the role enum to the appropriate role to send
+        OFNiciraControllerRole roleToSend = OFNiciraControllerRole.ROLE_OTHER;
+        switch (role) {
+        case MASTER:
+            roleToSend = OFNiciraControllerRole.ROLE_MASTER;
+            break;
+        case SLAVE:
+        case EQUAL:
+        default:
+            // ensuring that the only two roles sent to 1.0 switches with
+            // Nicira role support, are MASTER and SLAVE
+            roleToSend = OFNiciraControllerRole.ROLE_SLAVE;
+            log.warn("Sending Nx Role.SLAVE to switch {}.", sw);
+        }
+        int xid = xidCounter.getAndIncrement();
+        OFExperimenter roleRequest = OFFactories.getFactory(OFVersion.OF_10)
+                .buildNiciraControllerRoleRequest()
+                .setXid(xid)
+                .setRole(roleToSend)
+                .build();
+        sw.write(Collections.<OFMessage>singletonList(roleRequest));
+        return xid;
+    }
+
+    private int sendOF13RoleRequest(RoleState role) throws IOException {
+        // Convert the role enum to the appropriate role to send
+        OFControllerRole roleToSend = OFControllerRole.ROLE_NOCHANGE;
+        switch (role) {
+        case EQUAL:
+            roleToSend = OFControllerRole.ROLE_EQUAL;
+            break;
+        case MASTER:
+            roleToSend = OFControllerRole.ROLE_MASTER;
+            break;
+        case SLAVE:
+            roleToSend = OFControllerRole.ROLE_SLAVE;
+            break;
+        default:
+            log.warn("Sending default role.noChange to switch {}."
+                    + " Should only be used for queries.", sw);
+        }
+
+        int xid = xidCounter.getAndIncrement();
+        OFRoleRequest rrm = OFFactories.getFactory(OFVersion.OF_13)
+                .buildRoleRequest()
+                .setRole(roleToSend)
+                .setXid(xid)
+                //FIXME fix below when we actually use generation ids
+                .setGenerationId(U64.ZERO)
+                .build();
+        sw.write(rrm);
+        return xid;
+    }
+
+    /**
+     * Send a role request with the given role to the switch and update
+     * the pending request and timestamp.
+     * Sends an OFPT_ROLE_REQUEST to an OF1.3 switch, OR
+     * Sends an NX_ROLE_REQUEST to an OF1.0 switch if configured to support it
+     * in the IOFSwitch driver. If not supported, this method sends nothing
+     * and returns 'false'. The caller should take appropriate action.
+     *
+     * One other optimization we do here is that for OF1.0 switches with
+     * Nicira role message support, we force the Role.EQUAL to become
+     * Role.SLAVE, as there is no defined behavior for the Nicira role OTHER.
+     * We cannot expect it to behave like SLAVE. We don't have this problem with
+     * OF1.3 switches, because Role.EQUAL is well defined and we can simulate
+     * SLAVE behavior by using ASYNC messages.
+     *
+     * @param role
+     * @throws IOException
+     * @returns false if and only if the switch does not support role-request
+     * messages, according to the switch driver; true otherwise.
+     */
+    synchronized boolean sendRoleRequest(RoleState role, RoleRecvStatus exp)
+            throws IOException {
+        this.expectation = exp;
+
+        if (sw.factory().getVersion() == OFVersion.OF_10) {
+            Boolean supportsNxRole = (Boolean)
+                    sw.supportNxRole();
+            if (!supportsNxRole) {
+                log.debug("Switch driver indicates no support for Nicira "
+                        + "role request messages. Not sending ...");
+                handleUnsentRoleMessage(role,
+                        expectation);
+                return false;
+            }
+            // OF1.0 switch with support for NX_ROLE_REQUEST vendor extn.
+            // make Role.EQUAL become Role.SLAVE
+            role = (role == RoleState.EQUAL) ? RoleState.SLAVE : role;
+            pendingXid = sendNxRoleRequest(role);
+            pendingRole = role;
+            requestPending = true;
+        } else {
+            // OF1.3 switch, use OFPT_ROLE_REQUEST message
+            pendingXid = sendOF13RoleRequest(role);
+            pendingRole = role;
+            requestPending = true;
+        }
+        return true;
+    }
+
+    private void handleUnsentRoleMessage(RoleState role,
+            RoleRecvStatus exp) throws IOException {
+        // typically this is triggered for a switch where role messages
+        // are not supported - we confirm that the role being set is
+        // master
+        if (exp != RoleRecvStatus.MATCHED_SET_ROLE) {
+
+            log.error("Expected MASTER role from registry for switch "
+                    + "which has no support for role-messages."
+                    + "Received {}. It is possible that this switch "
+                    + "is connected to other controllers, in which "
+                    + "case it should support role messages - not "
+                    + "moving forward.", role);
+
+        }
+
+    }
+
+    /**
+     * Deliver a received role reply.
+     *
+     * Check if a request is pending and if the received reply matches the
+     * the expected pending reply (we check both role and xid) we set
+     * the role for the switch/channel.
+     *
+     * If a request is pending but doesn't match the reply we ignore it, and
+     * return
+     *
+     * If no request is pending we disconnect with a SwitchStateException
+     *
+     * @param RoleReplyInfo information about role-reply in format that
+     *                      controller can understand.
+     * @throws SwitchStateException if no request is pending
+     */
+    synchronized RoleRecvStatus deliverRoleReply(RoleReplyInfo rri)
+            throws SwitchStateException {
+        if (!requestPending) {
+            RoleState currentRole = (sw != null) ? sw.getRole() : null;
+            if (currentRole != null) {
+                if (currentRole == rri.getRole()) {
+                    // Don't disconnect if the role reply we received is
+                    // for the same role we are already in.
+                    log.debug("Received unexpected RoleReply from "
+                            + "Switch: {}. "
+                            + "Role in reply is same as current role of this "
+                            + "controller for this sw. Ignoring ...",
+                            sw.getStringId());
+                    return RoleRecvStatus.OTHER_EXPECTATION;
+                } else {
+                    String msg = String.format("Switch: [%s], "
+                            + "received unexpected RoleReply[%s]. "
+                            + "No roles are pending, and this controller's "
+                            + "current role:[%s] does not match reply. "
+                            + "Disconnecting switch ... ",
+                            sw.getStringId(),
+                            rri, currentRole);
+                    throw new SwitchStateException(msg);
+                }
+            }
+            log.debug("Received unexpected RoleReply {} from "
+                    + "Switch: {}. "
+                    + "This controller has no current role for this sw. "
+                    + "Ignoring ...", new Object[] {rri,
+                            sw.getStringId(), });
+            return RoleRecvStatus.OTHER_EXPECTATION;
+        }
+
+        int xid = (int) rri.getXid();
+        RoleState role = rri.getRole();
+        // XXX S should check generation id meaningfully and other cases of expectations
+        // U64 genId = rri.getGenId();
+
+        if (pendingXid != xid) {
+            log.debug("Received older role reply from " +
+                    "switch {} ({}). Ignoring. " +
+                    "Waiting for {}, xid={}",
+                    new Object[] {sw.getStringId(), rri,
+                    pendingRole, pendingXid });
+            return RoleRecvStatus.OLD_REPLY;
+        }
+
+        if (pendingRole == role) {
+            log.debug("Received role reply message from {} that matched "
+                    + "expected role-reply {} with expectations {}",
+                    new Object[] {sw.getStringId(), role, expectation});
+
+            //setSwitchRole(role, RoleRecvStatus.RECEIVED_REPLY); dont want to set state here
+            if (expectation == RoleRecvStatus.MATCHED_CURRENT_ROLE ||
+                    expectation == RoleRecvStatus.MATCHED_SET_ROLE) {
+                return expectation;
+            } else {
+                return RoleRecvStatus.OTHER_EXPECTATION;
+            }
+        }
+
+        // if xids match but role's don't, perhaps its a query (OF1.3)
+        if (expectation == RoleRecvStatus.REPLY_QUERY) {
+            return expectation;
+        }
+
+        return RoleRecvStatus.OTHER_EXPECTATION;
+    }
+
+    /**
+     * Called if we receive an  error message. If the xid matches the
+     * pending request we handle it otherwise we ignore it.
+     *
+     * Note: since we only keep the last pending request we might get
+     * error messages for earlier role requests that we won't be able
+     * to handle
+     */
+    synchronized RoleRecvStatus deliverError(OFErrorMsg error)
+            throws SwitchStateException {
+        if (!requestPending) {
+            log.debug("Received an error msg from sw {}, but no pending "
+                    + "requests in role-changer; not handling ...",
+                   sw.getStringId());
+            return RoleRecvStatus.OTHER_EXPECTATION;
+        }
+        if (pendingXid != error.getXid()) {
+            if (error.getErrType() == OFErrorType.ROLE_REQUEST_FAILED) {
+                log.debug("Received an error msg from sw {} for a role request,"
+                        + " but not for pending request in role-changer; "
+                        + " ignoring error {} ...",
+                        sw.getStringId(), error);
+            }
+            return RoleRecvStatus.OTHER_EXPECTATION;
+        }
+        // it is an error related to a currently pending role request message
+        if (error.getErrType() == OFErrorType.BAD_REQUEST) {
+            log.error("Received a error msg {} from sw {} for "
+                    + "pending role request {}. Switch driver indicates "
+                    + "role-messaging is supported. Possible issues in "
+                    + "switch driver configuration?", new Object[] {
+                            ((OFBadRequestErrorMsg) error).toString(),
+                            sw.getStringId(), pendingRole
+                    });
+            return RoleRecvStatus.UNSUPPORTED;
+        }
+
+        if (error.getErrType() == OFErrorType.ROLE_REQUEST_FAILED) {
+            OFRoleRequestFailedErrorMsg rrerr =
+                    (OFRoleRequestFailedErrorMsg) error;
+            switch (rrerr.getCode()) {
+            case BAD_ROLE:
+                // switch says that current-role-req has bad role?
+                // for now we disconnect
+                // fall-thru
+            case STALE:
+                // switch says that current-role-req has stale gen-id?
+                // for now we disconnect
+                // fall-thru
+            case UNSUP:
+                // switch says that current-role-req has role that
+                // cannot be supported? for now we disconnect
+                String msgx = String.format("Switch: [%s], "
+                        + "received Error to for pending role request [%s]. "
+                        + "Error:[%s]. Disconnecting switch ... ",
+                        sw.getStringId(),
+                        pendingRole, rrerr);
+                throw new SwitchStateException(msgx);
+            default:
+                break;
+            }
+        }
+
+        // This error message was for a role request message but we dont know
+        // how to handle errors for nicira role request messages
+        return RoleRecvStatus.OTHER_EXPECTATION;
+    }
+
+    /**
+     * Extract the role from an OFVendor message.
+     *
+     * Extract the role from an OFVendor message if the message is a
+     * Nicira role reply. Otherwise return null.
+     *
+     * @param h The channel handler receiving the message
+     * @param vendorMessage The vendor message to parse.
+     * @return The role in the message if the message is a Nicira role
+     * reply, null otherwise.
+     * @throws SwitchStateException If the message is a Nicira role reply
+     * but the numeric role value is unknown.
+     */
+    protected RoleState extractNiciraRoleReply(OFExperimenter experimenterMsg)
+            throws SwitchStateException {
+        int vendor = (int) experimenterMsg.getExperimenter();
+        if (vendor != 0x2320) {
+            return null;
+        }
+        OFNiciraControllerRoleReply nrr =
+                (OFNiciraControllerRoleReply) experimenterMsg;
+
+        RoleState role = null;
+        OFNiciraControllerRole ncr = nrr.getRole();
+        switch(ncr) {
+        case ROLE_MASTER:
+            role = RoleState.MASTER;
+            break;
+        case ROLE_OTHER:
+            role = RoleState.EQUAL;
+            break;
+        case ROLE_SLAVE:
+            role = RoleState.SLAVE;
+            break;
+        default: //handled below
+        }
+
+        if (role == null) {
+            String msg = String.format("Switch: [%s], "
+                    + "received NX_ROLE_REPLY with invalid role "
+                    + "value %s",
+                    sw.getStringId(),
+                    nrr.getRole());
+            throw new SwitchStateException(msg);
+        }
+        return role;
+    }
+
+    /**
+     * When we remove a pending role request we use this enum to indicate how we
+     * arrived at the decision. When we send a role request to the switch, we
+     * also use  this enum to indicate what we expect back from the switch, so the
+     * role changer can match the reply to our expectation.
+     */
+    public enum RoleRecvStatus {
+        /** The switch returned an error indicating that roles are not.
+         * supported*/
+        UNSUPPORTED,
+        /** The request timed out. */
+        NO_REPLY,
+        /** The reply was old, there is a newer request pending. */
+        OLD_REPLY,
+        /**
+         *  The reply's role matched the role that this controller set in the
+         *  request message - invoked either initially at startup or to reassert
+         *  current role.
+         */
+        MATCHED_CURRENT_ROLE,
+        /**
+         *  The reply's role matched the role that this controller set in the
+         *  request message - this is the result of a callback from the
+         *  global registry, followed by a role request sent to the switch.
+         */
+        MATCHED_SET_ROLE,
+        /**
+         * The reply's role was a response to the query made by this controller.
+         */
+        REPLY_QUERY,
+        /** We received a role reply message from the switch
+         *  but the expectation was unclear, or there was no expectation.
+         */
+        OTHER_EXPECTATION,
+    }
+
+    /**
+     * Helper class returns role reply information in the format understood
+     * by the controller.
+     */
+    protected static class RoleReplyInfo {
+        private RoleState role;
+        private U64 genId;
+        private long xid;
+
+        RoleReplyInfo(RoleState role, U64 genId, long xid) {
+            this.role = role;
+            this.genId = genId;
+            this.xid = xid;
+        }
+        public RoleState getRole() { return role; }
+        public U64 getGenId() { return genId; }
+        public long getXid() { return xid; }
+        @Override
+        public String toString() {
+            return "[Role:" + role + " GenId:" + genId + " Xid:" + xid + "]";
+        }
+    }
+
+    /**
+     * Extract the role information from an OF1.3 Role Reply Message.
+     * @param h
+     * @param rrmsg
+     * @return RoleReplyInfo object
+     * @throws SwitchStateException
+     */
+    protected RoleReplyInfo extractOFRoleReply(OFRoleReply rrmsg)
+            throws SwitchStateException {
+        OFControllerRole cr = rrmsg.getRole();
+        RoleState role = null;
+        switch(cr) {
+        case ROLE_EQUAL:
+            role = RoleState.EQUAL;
+            break;
+        case ROLE_MASTER:
+            role = RoleState.MASTER;
+            break;
+        case ROLE_SLAVE:
+            role = RoleState.SLAVE;
+            break;
+        case ROLE_NOCHANGE: // switch should send current role
+        default:
+            String msg = String.format("Unknown controller role %s "
+                    + "received from switch %s", cr, sw);
+            throw new SwitchStateException(msg);
+        }
+
+        return new RoleReplyInfo(role, rrmsg.getGenerationId(), rrmsg.getXid());
+    }
+
+}
+
+
+///**
+// * We are waiting for a role reply message in response to a role request
+// * sent after hearing back from the registry service -- OR -- we are
+// * just waiting to hear back from the registry service in the case that
+// * the switch does not support role messages. If completed successfully,
+// * the controller's role for this switch will be set here.
+// * Before we move to the state corresponding to the role, we allow the
+// * switch specific driver to complete its configuration. This configuration
+// * typically depends on the role the controller is playing for this switch.
+// * And so we set the switch role (for 'this' controller) before we start
+// * the driver-sub-handshake.
+// * Next State: WAIT_SWITCH_DRIVER_SUB_HANDSHAKE
+// */
+//WAIT_INITIAL_ROLE(false) {
+//    @Override
+//    void processOFError(OFChannelHandler h, OFErrorMsg m)
+//            throws SwitchStateException {
+//        // role changer will ignore the error if it isn't for it
+//        RoleRecvStatus rrstatus = h.roleChanger.deliverError(m);
+//        if (rrstatus == RoleRecvStatus.OTHER_EXPECTATION) {
+//            logError(h, m);
+//        }
+//    }
+//
+//    @Override
+//    void processOFExperimenter(OFChannelHandler h, OFExperimenter m)
+//            throws IOException, SwitchStateException {
+//        Role role = extractNiciraRoleReply(h, m);
+//        // If role == null it means the vendor (experimenter) message
+//        // wasn't really a Nicira role reply. We ignore this case.
+//        if (role != null) {
+//            RoleReplyInfo rri = new RoleReplyInfo(role, null, m.getXid());
+//            RoleRecvStatus rrs = h.roleChanger.deliverRoleReply(rri);
+//            if (rrs == RoleRecvStatus.MATCHED_SET_ROLE) {
+//                setRoleAndStartDriverHandshake(h, rri.getRole());
+//            } // else do nothing - wait for the correct expected reply
+//        } else {
+//            unhandledMessageReceived(h, m);
+//        }
+//    }
+//
+//    @Override
+//    void processOFRoleReply(OFChannelHandler h, OFRoleReply m)
+//            throws SwitchStateException, IOException {
+//        RoleReplyInfo rri = extractOFRoleReply(h, m);
+//        RoleRecvStatus rrs = h.roleChanger.deliverRoleReply(rri);
+//        if (rrs == RoleRecvStatus.MATCHED_SET_ROLE) {
+//            setRoleAndStartDriverHandshake(h, rri.getRole());
+//        } // else do nothing - wait for the correct expected reply
+//    }
+//
+//    @Override
+//    void handleUnsentRoleMessage(OFChannelHandler h, Role role,
+//            RoleRecvStatus expectation) throws IOException {
+//        // typically this is triggered for a switch where role messages
+//        // are not supported - we confirm that the role being set is
+//        // master and move to the next state
+//        if (expectation == RoleRecvStatus.MATCHED_SET_ROLE) {
+//            if (role == Role.MASTER) {
+//                setRoleAndStartDriverHandshake(h, role);
+//            } else {
+//                log.error("Expected MASTER role from registry for switch "
+//                        + "which has no support for role-messages."
+//                        + "Received {}. It is possible that this switch "
+//                        + "is connected to other controllers, in which "
+//                        + "case it should support role messages - not "
+//                        + "moving forward.", role);
+//            }
+//        } // else do nothing - wait to hear back from registry
+//
+//    }
+//
+//    private void setRoleAndStartDriverHandshake(OFChannelHandler h,
+//            Role role) throws IOException {
+//        h.setSwitchRole(role);
+//        h.sw.startDriverHandshake();
+//        if (h.sw.isDriverHandshakeComplete()) {
+//            Role mySwitchRole = h.sw.getRole();
+//            if (mySwitchRole == Role.MASTER) {
+//                log.info("Switch-driver sub-handshake complete. "
+//                        + "Activating switch {} with Role: MASTER",
+//                        h.sw.getStringId());
+//                handlePendingPortStatusMessages(h); //before activation
+//                boolean success = h.sw.addActivatedMasterSwitch();
+//                if (!success) {
+//                    disconnectDuplicate(h);
+//                    return;
+//                }
+//                h.setState(MASTER);
+//            } else {
+//                log.info("Switch-driver sub-handshake complete. "
+//                        + "Activating switch {} with Role: EQUAL",
+//                        h.sw.getStringId());
+//                handlePendingPortStatusMessages(h); //before activation
+//                boolean success = h.sw.addActivatedEqualSwitch();
+//                if (!success) {
+//                    disconnectDuplicate(h);
+//                    return;
+//                }
+//                h.setState(EQUAL);
+//            }
+//        } else {
+//            h.setState(WAIT_SWITCH_DRIVER_SUB_HANDSHAKE);
+//        }
+//    }
+//
+//    @Override
+//    void processOFFeaturesReply(OFChannelHandler h, OFFeaturesReply  m)
+//            throws IOException, SwitchStateException {
+//        illegalMessageReceived(h, m);
+//    }
+//
+//    @Override
+//    void processOFStatisticsReply(OFChannelHandler h, OFStatsReply m)
+//            throws SwitchStateException {
+//        illegalMessageReceived(h, m);
+//    }
+//
+//    @Override
+//    void processOFPortStatus(OFChannelHandler h, OFPortStatus m)
+//            throws IOException, SwitchStateException {
+//        h.pendingPortStatusMsg.add(m);
+//
+//    }
+//},
+
+
+
+
+
+
+
+///**
+// * This controller is in EQUAL role for this switch. We enter this state
+// * after some /other/ controller instance wins mastership-role over this
+// * switch. The EQUAL role can be considered the same as the SLAVE role
+// * if this controller does NOT send commands or packets to the switch.
+// * This should always be true for OF1.0 switches. XXX S need to enforce.
+// *
+// * For OF1.3 switches, choosing this state as EQUAL instead of SLAVE,
+// * gives us the flexibility that if an app wants to send commands/packets
+// * to switches, it can, even thought it is running on a controller instance
+// * that is not in a MASTER role for this switch. Of course, it is the job
+// * of the app to ensure that commands/packets sent by this (EQUAL) controller
+// * instance does not clash/conflict with commands/packets sent by the MASTER
+// * controller for this switch. Neither the controller instances, nor the
+// * switch provides any kind of resolution mechanism should conflicts occur.
+// */
+//EQUAL(true) {
+//    @Override
+//    void processOFError(OFChannelHandler h, OFErrorMsg m)
+//            throws IOException, SwitchStateException {
+//        // role changer will ignore the error if it isn't for it
+//        RoleRecvStatus rrstatus = h.roleChanger.deliverError(m);
+//        if (rrstatus == RoleRecvStatus.OTHER_EXPECTATION) {
+//            logError(h, m);
+//            h.dispatchMessage(m);
+//        }
+//    }
+//
+//    @Override
+//    void processOFStatisticsReply(OFChannelHandler h,
+//            OFStatsReply m) {
+//        h.sw.handleMessage(m);
+//    }
+//
+//    @Override
+//    void processOFExperimenter(OFChannelHandler h, OFExperimenter m)
+//            throws IOException, SwitchStateException {
+//        Role role = extractNiciraRoleReply(h, m);
+//        // If role == null it means the message wasn't really a
+//        // Nicira role reply. We ignore it in this state.
+//        if (role != null) {
+//            RoleRecvStatus rrs = h.roleChanger.deliverRoleReply(
+//                    new RoleReplyInfo(role, null, m.getXid()));
+//            if (rrs == RoleRecvStatus.MATCHED_SET_ROLE) {
+//                checkAndSetRoleTransition(h, role);
+//            }
+//        } else {
+//            unhandledMessageReceived(h, m);
+//        }
+//    }
+//
+//    @Override
+//    void processOFRoleReply(OFChannelHandler h, OFRoleReply m)
+//            throws SwitchStateException, IOException {
+//        RoleReplyInfo rri = extractOFRoleReply(h, m);
+//        RoleRecvStatus rrs = h.roleChanger.deliverRoleReply(rri);
+//        if (rrs == RoleRecvStatus.MATCHED_SET_ROLE) {
+//            checkAndSetRoleTransition(h, rri.getRole());
+//        }
+//    }
+//
+//    // XXX S needs more handlers for 1.3 switches in equal role
+//
+//    @Override
+//    void processOFPortStatus(OFChannelHandler h, OFPortStatus m)
+//            throws IOException, SwitchStateException {
+//        handlePortStatusMessage(h, m, true);
+//    }
+//
+//    @Override
+//    @LogMessageDoc(level = "WARN",
+//    message = "Received PacketIn from switch {} while "
+//            + "being slave. Reasserting slave role.",
+//            explanation = "The switch has receive a PacketIn despite being "
+//                    + "in slave role indicating inconsistent controller roles",
+//                    recommendation = "This situation can occurs transiently during role"
+//                            + " changes. If, however, the condition persists or happens"
+//                            + " frequently this indicates a role inconsistency. "
+//                            + LogMessageDoc.CHECK_CONTROLLER)
+//    void processOFPacketIn(OFChannelHandler h, OFPacketIn m) throws IOException {
+//        // we don't expect packetIn while slave, reassert we are slave
+//        h.counters.packetInWhileSwitchIsSlave.updateCounterNoFlush();
+//        log.warn("Received PacketIn from switch {} while" +
+//                "being slave. Reasserting slave role.", h.sw);
+//        //h.controller.reassertRole(h, Role.SLAVE);
+//        // XXX reassert in role changer
+//    }
+//};
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/registry/ControllerRegistryEntry.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/registry/ControllerRegistryEntry.java
deleted file mode 100644
index 5e83348..0000000
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/registry/ControllerRegistryEntry.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package org.onlab.onos.of.controller.impl.registry;
-
-
-
-public class ControllerRegistryEntry implements Comparable<ControllerRegistryEntry> {
-    //
-    // TODO: Refactor the implementation and decide whether controllerId
-    // is needed. If "yes", we might need to consider it inside the
-    // compareTo(), equals() and hashCode() implementations.
-    //
-    private final String controllerId;
-    private final int sequenceNumber;
-
-    public ControllerRegistryEntry(String controllerId, int sequenceNumber) {
-        this.controllerId = controllerId;
-        this.sequenceNumber = sequenceNumber;
-    }
-
-    public String getControllerId() {
-        return controllerId;
-    }
-
-    /**
-     * Compares this object with the specified object for order.
-     * NOTE: the test is based on ControllerRegistryEntry sequence numbers,
-     * and doesn't include the controllerId.
-     *
-     * @param o the object to be compared.
-     * @return a negative integer, zero, or a positive integer as this object
-     * is less than, equal to, or greater than the specified object.
-     */
-    @Override
-    public int compareTo(ControllerRegistryEntry o) {
-        return this.sequenceNumber - o.sequenceNumber;
-    }
-
-    /**
-     * Test whether some other object is "equal to" this one.
-     * NOTE: the test is based on ControllerRegistryEntry sequence numbers,
-     * and doesn't include the controllerId.
-     *
-     * @param obj the reference object with which to compare.
-     * @return true if this object is the same as the obj argument; false
-     * otherwise.
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if (obj instanceof ControllerRegistryEntry) {
-            ControllerRegistryEntry other = (ControllerRegistryEntry) obj;
-            return this.sequenceNumber == other.sequenceNumber;
-        }
-        return false;
-    }
-
-    /**
-     * Get the hash code for the object.
-     * NOTE: the computation is based on ControllerRegistryEntry sequence
-     * numbers, and doesn't include the controller ID.
-     *
-     * @return a hash code value for this object.
-     */
-    @Override
-    public int hashCode() {
-        return Integer.valueOf(this.sequenceNumber).hashCode();
-    }
-}
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/registry/IControllerRegistry.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/registry/IControllerRegistry.java
deleted file mode 100644
index 21b1709..0000000
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/registry/IControllerRegistry.java
+++ /dev/null
@@ -1,155 +0,0 @@
-package org.onlab.onos.of.controller.impl.registry;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-import org.onlab.onos.of.controller.impl.util.InstanceId;
-
-/**
- * A registry service that allows ONOS to register controllers and switches in a
- * way that is global to the entire ONOS cluster. The registry is the arbiter
- * for allowing controllers to control switches.
- * <p/>
- * The OVS/OF1.{2,3} fault tolerance model is a switch connects to multiple
- * controllers, and the controllers send role requests to tell the switch their
- * role in controlling the switch.
- * <p/>
- * The ONOS fault tolerance model allows only a single controller to have
- * control of a switch (MASTER role) at once. Controllers therefore need a
- * mechanism that enables them to decide who should control a each switch. The
- * registry service provides this mechanism.
- */
-public interface IControllerRegistry {
-
-    /**
-     * Callback interface for control change events.
-     */
-    public interface ControlChangeCallback {
-        /**
-         * Called whenever the control changes from the point of view of the
-         * registry. The callee can check whether they have control or not using
-         * the hasControl parameter.
-         *
-         * @param dpid The switch that control has changed for
-         * @param hasControl Whether the listener now has control or not
-         */
-        void controlChanged(long dpid, boolean hasControl);
-    }
-
-    /**
-     * Request for control of a switch. This method does not block. When control
-     * for a switch changes, the controlChanged method on the callback object
-     * will be called. This happens any time the control changes while the
-     * request is still active (until releaseControl is called)
-     *
-     * @param dpid Switch to request control for
-     * @param cb Callback that will be used to notify caller of control changes
-     * @throws RegistryException Errors contacting the registry service
-     */
-    public void requestControl(long dpid, ControlChangeCallback cb)
-            throws RegistryException;
-
-    /**
-     * Stop trying to take control of a switch. This removes the entry for this
-     * controller requesting this switch in the registry. If the controller had
-     * control when this is called, another controller will now gain control of
-     * the switch. This call doesn't block.
-     *
-     * @param dpid Switch to release control of
-     */
-    public void releaseControl(long dpid);
-
-    /**
-     * Check whether the controller has control of the switch This call doesn't
-     * block.
-     *
-     * @param dpid Switch to check control of
-     * @return true if controller has control of the switch.
-     */
-    public boolean hasControl(long dpid);
-
-    /**
-     * Check whether this instance is the leader for the cluster. This call
-     * doesn't block.
-     *
-     * @return true if the instance is the leader for the cluster, otherwise
-     *         false.
-     */
-    public boolean isClusterLeader();
-
-    /**
-     * Gets the unique ID used to identify this ONOS instance in the cluster.
-     *
-     * @return Instance ID.
-     */
-    public InstanceId getOnosInstanceId();
-
-    /**
-     * Register a controller to the ONOS cluster. Must be called before the
-     * registry can be used to take control of any switches.
-     *
-     * @param controllerId A unique string ID identifying this controller in the
-     *        cluster
-     * @throws RegistryException for errors connecting to registry service,
-     *         controllerId already registered
-     */
-    public void registerController(String controllerId)
-            throws RegistryException;
-
-    /**
-     * Get all controllers in the cluster.
-     *
-     * @return Collection of controller IDs
-     * @throws RegistryException on error
-     */
-    public Collection<String> getAllControllers() throws RegistryException;
-
-    /**
-     * Get all switches in the cluster, along with which controller is in
-     * control of them (if any) and any other controllers that have requested
-     * control.
-     *
-     * @return Map of all switches.
-     */
-    public Map<String, List<ControllerRegistryEntry>> getAllSwitches();
-
-    /**
-     * Get the controller that has control of a given switch.
-     *
-     * @param dpid Switch to find controller for
-     * @return controller ID
-     * @throws RegistryException Errors contacting registry service
-     */
-    public String getControllerForSwitch(long dpid) throws RegistryException;
-
-    /**
-     * Get all switches controlled by a given controller.
-     *
-     * @param controllerId ID of the controller
-     * @return Collection of dpids
-     */
-    public Collection<Long> getSwitchesControlledByController(String controllerId);
-
-    /**
-     * Get a unique Id Block.
-     *
-     * @return Id Block.
-     */
-    public IdBlock allocateUniqueIdBlock();
-
-    /**
-     * Get next unique id and retrieve a new range of ids if needed.
-     *
-     * @param range range to use for the identifier
-     * @return Id Block.
-     */
-    public IdBlock allocateUniqueIdBlock(long range);
-
-    /**
-     * Get a globally unique ID.
-     *
-     * @return a globally unique ID.
-     */
-    public long getNextUniqueId();
-}
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/registry/IdBlock.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/registry/IdBlock.java
deleted file mode 100644
index 406a60d..0000000
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/registry/IdBlock.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package org.onlab.onos.of.controller.impl.registry;
-
-public class IdBlock {
-    private final long start;
-    private final long end;
-    private final long size;
-
-    public IdBlock(long start, long end, long size) {
-        this.start = start;
-        this.end = end;
-        this.size = size;
-    }
-
-    public long getStart() {
-        return start;
-    }
-
-    public long getEnd() {
-        return end;
-    }
-
-    public long getSize() {
-        return size;
-    }
-
-    @Override
-    public String toString() {
-        return "IdBlock [start=" + start + ", end=" + end + ", size=" + size
-                + "]";
-    }
-}
-
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/registry/RegistryException.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/registry/RegistryException.java
deleted file mode 100644
index 029f028..0000000
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/registry/RegistryException.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package org.onlab.onos.of.controller.impl.registry;
-
-public class RegistryException extends Exception {
-
-    private static final long serialVersionUID = -8276300722010217913L;
-
-    public RegistryException(String message) {
-        super(message);
-    }
-
-    public RegistryException(String message, Throwable cause) {
-        super(message, cause);
-    }
-
-}
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/util/DummySwitchForTesting.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/util/DummySwitchForTesting.java
deleted file mode 100644
index 2d925f8..0000000
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/util/DummySwitchForTesting.java
+++ /dev/null
@@ -1,360 +0,0 @@
-package org.onlab.onos.of.controller.impl.util;
-
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Future;
-
-import org.jboss.netty.channel.Channel;
-import org.projectfloodlight.openflow.protocol.OFActionType;
-import org.projectfloodlight.openflow.protocol.OFCapabilities;
-import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
-import org.projectfloodlight.openflow.protocol.OFFeaturesReply;
-import org.projectfloodlight.openflow.protocol.OFMessage;
-import org.projectfloodlight.openflow.protocol.OFPortDesc;
-import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply;
-import org.projectfloodlight.openflow.protocol.OFPortStatus;
-import org.projectfloodlight.openflow.protocol.OFStatsReply;
-import org.projectfloodlight.openflow.protocol.OFStatsRequest;
-import org.projectfloodlight.openflow.protocol.OFVersion;
-import org.projectfloodlight.openflow.types.DatapathId;
-import org.projectfloodlight.openflow.types.U64;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.onlab.onos.of.controller.impl.IOFSwitch;
-import org.onlab.onos.of.controller.impl.Role;
-import org.onlab.onos.of.controller.impl.debugcounter.IDebugCounterService;
-import org.onlab.onos.of.controller.impl.debugcounter.IDebugCounterService.CounterException;
-
-public class DummySwitchForTesting implements IOFSwitch {
-
-    protected static final Logger log = LoggerFactory.getLogger(DummySwitchForTesting.class);
-
-    private Channel channel;
-    private boolean connected = false;
-    private OFVersion ofv = OFVersion.OF_10;
-
-    private Collection<OFPortDesc> ports;
-
-    private DatapathId datapathId;
-
-    private Set<OFCapabilities> capabilities;
-
-    private int buffers;
-
-    private byte tables;
-
-    private String stringId;
-
-    private Role role;
-
-    @Override
-    public void disconnectSwitch() {
-        this.channel.close();
-    }
-
-    @Override
-    public void write(OFMessage m) throws IOException {
-        this.channel.write(m);
-
-    }
-
-    @Override
-    public void write(List<OFMessage> msglist) throws IOException {
-        for (OFMessage m : msglist) {
-            this.channel.write(m);
-        }
-
-    }
-
-    @Override
-    public Date getConnectedSince() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public int getNextTransactionId() {
-        return 0;
-    }
-
-    @Override
-    public boolean isConnected() {
-        return this.connected;
-    }
-
-    @Override
-    public void setConnected(boolean connected) {
-        this.connected  = connected;
-
-    }
-
-    @Override
-    public void flush() {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void setChannel(Channel channel) {
-        this.channel = channel;
-
-    }
-
-    @Override
-    public long getId() {
-        if (this.stringId == null) {
-            throw new RuntimeException("Features reply has not yet been set");
-        }
-        return this.datapathId.getLong();
-    }
-
-    @Override
-    public String getStringId() {
-        // TODO Auto-generated method stub
-        return "DummySwitch";
-    }
-
-    @Override
-    public int getNumBuffers() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public Set<OFCapabilities> getCapabilities() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public byte getNumTables() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public OFDescStatsReply getSwitchDescription() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public void cancelFeaturesReply(int transactionId) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public Set<OFActionType> getActions() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public void setOFVersion(OFVersion version) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public OFVersion getOFVersion() {
-        return this.ofv;
-    }
-
-    @Override
-    public Collection<OFPortDesc> getEnabledPorts() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Collection<Integer> getEnabledPortNumbers() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public OFPortDesc getPort(int portNumber) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public OFPortDesc getPort(String portName) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public OrderedCollection<PortChangeEvent> processOFPortStatus(
-            OFPortStatus ps) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Collection<OFPortDesc> getPorts() {
-        return ports;
-    }
-
-    @Override
-    public boolean portEnabled(int portName) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public OrderedCollection<PortChangeEvent> setPorts(
-            Collection<OFPortDesc> p) {
-        this.ports = p;
-        return null;
-    }
-
-    @Override
-    public Map<Object, Object> getAttributes() {
-        return null;
-    }
-
-    @Override
-    public boolean hasAttribute(String name) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public Object getAttribute(String name) {
-        return Boolean.FALSE;
-    }
-
-    @Override
-    public void setAttribute(String name, Object value) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public Object removeAttribute(String name) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public void deliverStatisticsReply(OFMessage reply) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void cancelStatisticsReply(int transactionId) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void cancelAllStatisticsReplies() {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public Future<List<OFStatsReply>> getStatistics(OFStatsRequest<?> request)
-            throws IOException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public void clearAllFlowMods() {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public Role getRole() {
-        return this.role;
-    }
-
-    @Override
-    public void setRole(Role role) {
-        this.role = role;
-    }
-
-    @Override
-    public U64 getNextGenerationId() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public void setDebugCounterService(IDebugCounterService debugCounter)
-            throws CounterException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void startDriverHandshake() throws IOException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public boolean isDriverHandshakeComplete() {
-        return true;
-    }
-
-    @Override
-    public void processDriverHandshakeMessage(OFMessage m) {
-
-    }
-
-    @Override
-    public void setTableFull(boolean isFull) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void setFeaturesReply(OFFeaturesReply featuresReply) {
-        if (featuresReply == null) {
-            log.error("Error setting featuresReply for switch: {}", getStringId());
-            return;
-        }
-        this.datapathId = featuresReply.getDatapathId();
-        this.capabilities = featuresReply.getCapabilities();
-        this.buffers = (int) featuresReply.getNBuffers();
-        this.tables = (byte) featuresReply.getNTables();
-        this.stringId = this.datapathId.toString();
-
-    }
-
-    @Override
-    public void setPortDescReply(OFPortDescStatsReply portDescReply) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void handleMessage(OFMessage m) {
-        log.info("Got packet {} but I am dumb so I don't know what to do.", m);
-    }
-
-    @Override
-    public boolean portEnabled(String portName) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public OrderedCollection<PortChangeEvent> comparePorts(
-            Collection<OFPortDesc> p) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-}
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/util/EnumBitmaps.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/util/EnumBitmaps.java
deleted file mode 100644
index c7734c0..0000000
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/util/EnumBitmaps.java
+++ /dev/null
@@ -1,149 +0,0 @@
-package org.onlab.onos.of.controller.impl.util;
-
-import java.util.EnumSet;
-import java.util.Set;
-
-/**
- * A utility class to convert between integer based bitmaps for (OpenFlow)
- * flags and Enum and EnumSet based representations.
- *
- * The enum used to represent individual flags needs to implement the
- * BitmapableEnum interface.
- *
- * Example:
- * {@code
- *   int bitmap = 0x11; // OFPPC_PORT_DOWN | OFPPC_NO_STP
- *   EnumSet<OFPortConfig> s = toEnumSet(OFPortConfig.class, bitmap);
- *   // s will contain OFPPC_PORT_DOWN and OFPPC_NO_STP
- * }
- *
- * {@code
- *    EnumSet<OFPortConfig> s = EnumSet.of(OFPPC_NO_STP, OFPPC_PORT_DOWN);
- *    int bitmap = toBitmap(s); // returns 0x11
- * }
- *
- */
-public final class EnumBitmaps {
-
-
-    private EnumBitmaps() { }
-
-    /**
-     * Enums used to represent individual flags needs to implement this
-     * interface.
-     */
-    public interface BitmapableEnum {
-        /** Return the value in the bitmap that the enum constant represents.
-         * The returned value must have only a single bit set. E.g.,1 << 3
-         */
-        int getValue();
-    }
-
-
-    /**
-     * Convert an integer bitmap to an EnumSet.
-     *
-     * See class description for example
-     * @param type The Enum class to use. Must implement BitmapableEnum
-     * @param bitmap The integer bitmap
-     * @return A newly allocated EnumSet representing the bits set in the
-     * bitmap
-     * @throws NullPointerException if type is null
-     * @throws IllegalArgumentException if any enum constant from type has
-     * more than one bit set.
-     * @throws IllegalArgumentException if the bitmap has any bits set not
-     * represented by an enum constant.
-     */
-    public static <E extends Enum<E> & BitmapableEnum>
-            EnumSet<E> toEnumSet(Class<E> type, int bitmap) {
-        if (type == null) {
-            throw new NullPointerException("Given enum type must not be null");
-        }
-        EnumSet<E> s = EnumSet.noneOf(type);
-        // allSetBitmap will eventually have all valid bits for the given
-        // type set.
-        int allSetBitmap = 0;
-        for (E element: type.getEnumConstants()) {
-            if (Integer.bitCount(element.getValue()) != 1) {
-                String msg = String.format("The %s (%x) constant of the " +
-                        "enum %s is supposed to represent a bitmap entry but " +
-                        "has more than one bit set.",
-                        element.toString(), element.getValue(), type.getName());
-                throw new IllegalArgumentException(msg);
-            }
-            allSetBitmap |= element.getValue();
-            if ((bitmap & element.getValue()) != 0) {
-                s.add(element);
-            }
-        }
-        if (((~allSetBitmap) & bitmap) != 0) {
-            // check if only valid flags are set in the given bitmap
-            String msg = String.format("The bitmap %x for enum %s has " +
-                    "bits set that are presented by any enum constant",
-                    bitmap, type.getName());
-            throw new IllegalArgumentException(msg);
-        }
-        return s;
-    }
-
-    /**
-     * Return the bitmap mask with all possible bits set. E.g., If a bitmap
-     * has the individual flags 0x1, 0x2, and 0x8 (note the missing 0x4) then
-     * the mask will be 0xb (1011 binary)
-     *
-     * @param type The Enum class to use. Must implement BitmapableEnum
-     * @throws NullPointerException if type is null
-     * @throws IllegalArgumentException if any enum constant from type has
-     * more than one bit set
-     * @return an integer with all possible bits for the given bitmap enum
-     * type set.
-     */
-    public static <E extends Enum<E> & BitmapableEnum>
-            int getMask(Class<E> type) {
-        if (type == null) {
-            throw new NullPointerException("Given enum type must not be null");
-        }
-        // allSetBitmap will eventually have all valid bits for the given
-        // type set.
-        int allSetBitmap = 0;
-        for (E element: type.getEnumConstants()) {
-            if (Integer.bitCount(element.getValue()) != 1) {
-                String msg = String.format("The %s (%x) constant of the " +
-                        "enum %s is supposed to represent a bitmap entry but " +
-                        "has more than one bit set.",
-                        element.toString(), element.getValue(), type.getName());
-                throw new IllegalArgumentException(msg);
-            }
-            allSetBitmap |= element.getValue();
-        }
-        return allSetBitmap;
-    }
-
-    /**
-     * Convert the given EnumSet to the integer bitmap representation.
-     * @param set The EnumSet to convert. The enum must implement
-     * BitmapableEnum
-     * @return the integer bitmap
-     * @throws IllegalArgumentException if an enum constant from the set (!) has
-     * more than one bit set
-     * @throws NullPointerException if the set is null
-     */
-    public static <E extends Enum<E> & BitmapableEnum>
-            int toBitmap(Set<E> set) {
-        if (set == null) {
-            throw new NullPointerException("Given set must not be null");
-        }
-        int bitmap = 0;
-        for (E element: set) {
-            if (Integer.bitCount(element.getValue()) != 1) {
-                String msg = String.format("The %s (%x) constant in the set " +
-                        "is supposed to represent a bitmap entry but " +
-                        "has more than one bit set.",
-                        element.toString(), element.getValue());
-                throw new IllegalArgumentException(msg);
-            }
-            bitmap |= element.getValue();
-        }
-        return bitmap;
-    }
-}
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/util/FilterIterator.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/util/FilterIterator.java
deleted file mode 100644
index 319aae8..0000000
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/util/FilterIterator.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/**
- *    Copyright 2012, 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 org.onlab.onos.of.controller.impl.util;
-
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-/**
- * An iterator that will filter values from an iterator and return only
- * those values that match the predicate.
- */
-public abstract class FilterIterator<T> implements Iterator<T> {
-    protected Iterator<T> subIterator;
-    protected T next;
-
-    /**
-     * Construct a filter iterator from the given sub iterator.
-     *
-     * @param subIterator the sub iterator over which we'll filter
-     */
-    public FilterIterator(Iterator<T> subIterator) {
-        super();
-        this.subIterator = subIterator;
-    }
-
-    /**
-     * Check whether the given value should be returned by the
-     * filter.
-     *
-     * @param value the value to check
-     * @return true if the value should be included
-     */
-    protected abstract boolean matches(T value);
-
-    // ***********
-    // Iterator<T>
-    // ***********
-
-    @Override
-    public boolean hasNext() {
-        if (next != null) {
-            return true;
-        }
-
-        while (subIterator.hasNext()) {
-            next = subIterator.next();
-            if (matches(next)) {
-                return true;
-            }
-        }
-        next = null;
-        return false;
-    }
-
-    @Override
-    public T next() {
-        if (hasNext()) {
-            T cur = next;
-            next = null;
-            return cur;
-        }
-        throw new NoSuchElementException();
-    }
-
-    @Override
-    public void remove() {
-        throw new UnsupportedOperationException();
-    }
-
-}
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/util/InstanceId.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/util/InstanceId.java
deleted file mode 100644
index 4a7892e..0000000
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/util/InstanceId.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package org.onlab.onos.of.controller.impl.util;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkArgument;
-
-/**
- * The class representing an ONOS Instance ID.
- *
- * This class is immutable.
- */
-public final class InstanceId {
-    private final String id;
-
-    /**
-     * Constructor from a string value.
-     *
-     * @param id the value to use.
-     */
-    public InstanceId(String id) {
-        this.id = checkNotNull(id);
-        checkArgument(!id.isEmpty(), "Empty ONOS Instance ID");
-    }
-
-    @Override
-    public int hashCode() {
-        return id.hashCode();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == this) {
-            return true;
-        }
-
-        if (!(obj instanceof InstanceId)) {
-            return false;
-        }
-
-        InstanceId that = (InstanceId) obj;
-        return this.id.equals(that.id);
-    }
-
-    @Override
-    public String toString() {
-        return id;
-    }
-}
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/util/IterableIterator.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/util/IterableIterator.java
deleted file mode 100644
index a59b244..0000000
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/util/IterableIterator.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- *    Copyright 2012 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 org.onlab.onos.of.controller.impl.util;
-
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-/**
- * Iterator over all values in an iterator of iterators.
- *
- * @param <T> the type of elements returned by this iterator
- */
-public class IterableIterator<T> implements Iterator<T> {
-    Iterator<? extends Iterable<T>> subIterator;
-    Iterator<T> current = null;
-
-    public IterableIterator(Iterator<? extends Iterable<T>> subIterator) {
-        super();
-        this.subIterator = subIterator;
-    }
-
-    @Override
-    public boolean hasNext() {
-        if (current == null) {
-            if (subIterator.hasNext()) {
-                current = subIterator.next().iterator();
-            } else {
-                return false;
-            }
-        }
-        while (!current.hasNext() && subIterator.hasNext()) {
-            current = subIterator.next().iterator();
-        }
-
-        return current.hasNext();
-    }
-
-    @Override
-    public T next() {
-        if (hasNext()) {
-            return current.next();
-        }
-        throw new NoSuchElementException();
-    }
-
-    @Override
-    public void remove() {
-        if (hasNext()) {
-            current.remove();
-        }
-        throw new NoSuchElementException();
-    }
-}
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/util/LRUHashMap.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/util/LRUHashMap.java
deleted file mode 100644
index 866794f..0000000
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/util/LRUHashMap.java
+++ /dev/null
@@ -1,38 +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 org.onlab.onos.of.controller.impl.util;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-public class LRUHashMap<K, V> extends LinkedHashMap<K, V> {
-
-    private static final long serialVersionUID = 1L;
-
-    private final int capacity;
-
-    public LRUHashMap(int capacity) {
-        super(capacity + 1, 0.75f, true);
-        this.capacity = capacity;
-    }
-
-    protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
-        return size() > capacity;
-    }
-
-}
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/util/LinkedHashSetWrapper.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/util/LinkedHashSetWrapper.java
deleted file mode 100644
index 1778d06..0000000
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/util/LinkedHashSetWrapper.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package org.onlab.onos.of.controller.impl.util;
-
-import java.util.Collection;
-import java.util.LinkedHashSet;
-
-import com.google.common.collect.ForwardingCollection;
-
-/**
- * A simple wrapper / forwarder that forwards all calls to a LinkedHashSet.
- * This wrappers sole reason for existence is to implement the
- * OrderedCollection marker interface.
- *
- */
-public class LinkedHashSetWrapper<E>
-        extends ForwardingCollection<E> implements OrderedCollection<E> {
-    private final Collection<E> delegate;
-
-    public LinkedHashSetWrapper() {
-        super();
-        this.delegate = new LinkedHashSet<E>();
-    }
-
-    public LinkedHashSetWrapper(Collection<? extends E> c) {
-        super();
-        this.delegate = new LinkedHashSet<E>(c);
-    }
-
-    @Override
-    protected Collection<E> delegate() {
-        return this.delegate;
-    }
-}
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/util/MultiIterator.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/util/MultiIterator.java
deleted file mode 100644
index 7b709e9..0000000
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/util/MultiIterator.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- *    Copyright 2012 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 org.onlab.onos.of.controller.impl.util;
-
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-/**
- * Iterator over all values in an iterator of iterators.
- *
- * @param <T> the type of elements returned by this iterator
- */
-public class MultiIterator<T> implements Iterator<T> {
-    Iterator<Iterator<T>> subIterator;
-    Iterator<T> current = null;
-
-    public MultiIterator(Iterator<Iterator<T>> subIterator) {
-        super();
-        this.subIterator = subIterator;
-    }
-
-    @Override
-    public boolean hasNext() {
-        if (current == null) {
-            if (subIterator.hasNext()) {
-                current = subIterator.next();
-            } else {
-                return false;
-            }
-        }
-        while (!current.hasNext() && subIterator.hasNext()) {
-            current = subIterator.next();
-        }
-
-        return current.hasNext();
-    }
-
-    @Override
-    public T next() {
-        if (hasNext()) {
-            return current.next();
-        }
-        throw new NoSuchElementException();
-    }
-
-    @Override
-    public void remove() {
-        if (hasNext()) {
-            current.remove();
-        }
-        throw new NoSuchElementException();
-    }
-}
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/util/OrderedCollection.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/util/OrderedCollection.java
deleted file mode 100644
index 9dce568..0000000
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/util/OrderedCollection.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package org.onlab.onos.of.controller.impl.util;
-
-import java.util.Collection;
-
-/**
- * A marker interface indicating that this Collection defines a particular
- * iteration order. The details about the iteration order are specified by
- * the concrete implementation.
- *
- * @param <E>
- */
-public interface OrderedCollection<E> extends Collection<E> {
-
-}
diff --git a/of/ctl/src/test/java/org/onlab/onos/of/controller/impl/internal/ControllerTest.java b/of/ctl/src/test/java/org/onlab/onos/of/controller/impl/internal/ControllerTest.java
deleted file mode 100644
index 5de3647..0000000
--- a/of/ctl/src/test/java/org/onlab/onos/of/controller/impl/internal/ControllerTest.java
+++ /dev/null
@@ -1,167 +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 org.onlab.onos.of.controller.impl.internal;
-
-import junit.framework.TestCase;
-import org.onlab.onos.of.controller.impl.IOFSwitch;
-
-import org.easymock.EasyMock;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-
-public class ControllerTest extends TestCase {
-
-    private Controller controller;
-    private IOFSwitch sw;
-    private OFChannelHandler h;
-
-    @Override
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-        sw = EasyMock.createMock(IOFSwitch.class);
-        h = EasyMock.createMock(OFChannelHandler.class);
-        controller = new Controller();
-        ControllerRunThread t = new ControllerRunThread();
-        t.start();
-        /*
-         * Making sure the thread is properly started before making calls
-         * to controller class.
-         */
-        Thread.sleep(200);
-    }
-
-    /**
-     * Starts the base mocks used in these tests.
-     */
-    private void startMocks() {
-        EasyMock.replay(sw, h);
-    }
-
-    /**
-     * Reset the mocks to a known state.
-     * Automatically called after tests.
-     */
-    @After
-    private void resetMocks() {
-        EasyMock.reset(sw);
-    }
-
-    /**
-     * Fetches the controller instance.
-     * @return the controller
-     */
-    public Controller getController() {
-        return controller;
-    }
-
-    /**
-     * Run the controller's main loop so that updates are processed.
-     */
-    protected class ControllerRunThread extends Thread {
-        @Override
-        public void run() {
-            controller.openFlowPort = 0; // Don't listen
-            controller.activate();
-        }
-    }
-
-    /**
-     * Verify that we are able to add a switch that just connected.
-     * If it already exists then this should fail
-     *
-     * @throws Exception error
-     */
-    @Test
-    public void testAddConnectedSwitches() throws Exception {
-        startMocks();
-        assertTrue(controller.addConnectedSwitch(0, h));
-        assertFalse(controller.addConnectedSwitch(0, h));
-    }
-
-    /**
-     * Add active master but cannot re-add active master.
-     * @throws Exception an error occurred.
-     */
-    @Test
-    public void testAddActivatedMasterSwitch() throws Exception {
-        startMocks();
-        controller.addConnectedSwitch(0, h);
-        assertTrue(controller.addActivatedMasterSwitch(0, sw));
-        assertFalse(controller.addActivatedMasterSwitch(0, sw));
-    }
-
-    /**
-     * Tests that an activated switch can be added but cannot be re-added.
-     *
-     * @throws Exception an error occurred
-     */
-    @Test
-    public void testAddActivatedEqualSwitch() throws Exception {
-        startMocks();
-        controller.addConnectedSwitch(0, h);
-        assertTrue(controller.addActivatedEqualSwitch(0, sw));
-        assertFalse(controller.addActivatedEqualSwitch(0, sw));
-    }
-
-    /**
-     * Move an equal switch to master.
-     * @throws Exception an error occurred
-     */
-    @Test
-    public void testTranstitionToMaster() throws Exception {
-        startMocks();
-        controller.addConnectedSwitch(0, h);
-        controller.addActivatedEqualSwitch(0, sw);
-        controller.transitionToMasterSwitch(0);
-        assertNotNull(controller.getMasterSwitch(0));
-    }
-
-    /**
-     * Transition a master switch to equal state.
-     * @throws Exception an error occurred
-     */
-    @Test
-    public void testTranstitionToEqual() throws Exception {
-        startMocks();
-        controller.addConnectedSwitch(0, h);
-        controller.addActivatedMasterSwitch(0, sw);
-        controller.transitionToEqualSwitch(0);
-        assertNotNull(controller.getEqualSwitch(0));
-    }
-
-    /**
-     * Remove the switch from the controller instance.
-     * @throws Exception an error occurred
-     */
-    @Test
-    public void testRemoveSwitch() throws Exception {
-        sw.cancelAllStatisticsReplies();
-        EasyMock.expectLastCall().once();
-        sw.setConnected(false);
-        EasyMock.expectLastCall().once();
-        startMocks();
-        controller.addConnectedSwitch(0, h);
-        controller.addActivatedMasterSwitch(0, sw);
-        controller.removeConnectedSwitch(0);
-        assertNull(controller.getSwitch(0));
-        EasyMock.verify(sw, h);
-    }
-}
diff --git a/of/ctl/src/test/java/org/onlab/onos/of/controller/impl/internal/OFChannelHandlerTest.java b/of/ctl/src/test/java/org/onlab/onos/of/controller/impl/internal/OFChannelHandlerTest.java
deleted file mode 100644
index f267923..0000000
--- a/of/ctl/src/test/java/org/onlab/onos/of/controller/impl/internal/OFChannelHandlerTest.java
+++ /dev/null
@@ -1,1569 +0,0 @@
-package org.onlab.onos.of.controller.impl.internal;
-
-import static org.easymock.EasyMock.capture;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.expectLastCall;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.reset;
-import static org.easymock.EasyMock.verify;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.onlab.onos.of.controller.impl.IOFSwitch;
-import org.onlab.onos.of.controller.impl.Role;
-import org.onlab.onos.of.controller.impl.debugcounter.DebugCounter;
-import org.onlab.onos.of.controller.impl.debugcounter.IDebugCounterService;
-import org.onlab.onos.of.controller.impl.internal.OFChannelHandler.RoleRecvStatus;
-
-import org.easymock.Capture;
-import org.easymock.CaptureType;
-import org.jboss.netty.channel.Channel;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.channel.ChannelPipeline;
-import org.jboss.netty.channel.ChannelStateEvent;
-import org.jboss.netty.channel.ExceptionEvent;
-import org.jboss.netty.channel.MessageEvent;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
-import org.projectfloodlight.openflow.protocol.OFExperimenter;
-import org.projectfloodlight.openflow.protocol.OFFactories;
-import org.projectfloodlight.openflow.protocol.OFFactory;
-import org.projectfloodlight.openflow.protocol.OFFeaturesReply;
-import org.projectfloodlight.openflow.protocol.OFGetConfigReply;
-import org.projectfloodlight.openflow.protocol.OFHelloElem;
-import org.projectfloodlight.openflow.protocol.OFMessage;
-import org.projectfloodlight.openflow.protocol.OFNiciraControllerRole;
-import org.projectfloodlight.openflow.protocol.OFPacketIn;
-import org.projectfloodlight.openflow.protocol.OFPacketInReason;
-import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply;
-import org.projectfloodlight.openflow.protocol.OFSetConfig;
-import org.projectfloodlight.openflow.protocol.OFStatsReply;
-import org.projectfloodlight.openflow.protocol.OFStatsRequest;
-import org.projectfloodlight.openflow.protocol.OFStatsType;
-import org.projectfloodlight.openflow.protocol.OFType;
-import org.projectfloodlight.openflow.protocol.OFVersion;
-import org.projectfloodlight.openflow.types.DatapathId;
-import org.projectfloodlight.openflow.types.U32;
-
-/**
- * Channel handler deals with the switch connection and dispatches
- * switch messages to the appropriate locations. These Unit Testing cases
- * test the channeler state machine and role changer. In the first release,
- * we will focus on OF version 1.0. we will add the testing case for
- * version 1.3 later.
- */
-public class OFChannelHandlerTest {
-    private Controller controller;
-    private IDebugCounterService debugCounterService;
-    private OFChannelHandler handler;
-    private Channel channel;
-    private ChannelHandlerContext ctx;
-    private MessageEvent messageEvent;
-    private ChannelStateEvent channelStateEvent;
-    private ChannelPipeline pipeline;
-    private Capture<ExceptionEvent> exceptionEventCapture;
-    private Capture<List<OFMessage>> writeCapture;
-    private OFFeaturesReply featuresReply;
-    private Set<Integer> seenXids = null;
-    private IOFSwitch swImplBase;
-    private OFVersion ofVersion = OFVersion.OF_10;
-    private OFFactory factory13;
-    private OFFactory factory10;
-    private OFFactory factory;
-
-    @Before
-    public void setUp() throws Exception {
-        controller = createMock(Controller.class);
-        ctx = createMock(ChannelHandlerContext.class);
-        channelStateEvent = createMock(ChannelStateEvent.class);
-        channel = createMock(Channel.class);
-        messageEvent = createMock(MessageEvent.class);
-        exceptionEventCapture = new Capture<ExceptionEvent>(CaptureType.ALL);
-        pipeline = createMock(ChannelPipeline.class);
-        writeCapture = new Capture<List<OFMessage>>(CaptureType.ALL);
-        swImplBase = createMock(IOFSwitch.class);
-        seenXids = null;
-        factory13 = OFFactories.getFactory(OFVersion.OF_13);
-        factory10 = OFFactories.getFactory(OFVersion.OF_10);
-        factory = (ofVersion == OFVersion.OF_13) ? factory13 : factory10;
-
-        // TODO: should mock IDebugCounterService and make sure
-        // the expected counters are updated.
-        debugCounterService = new DebugCounter();
-        Controller.Counters counters =
-                new Controller.Counters();
-        counters.createCounters(debugCounterService);
-        expect(controller.getCounters()).andReturn(counters).anyTimes();
-        expect(controller.getOFMessageFactory10()).andReturn(factory10)
-            .anyTimes();
-        expect(controller.getOFMessageFactory13()).andReturn(factory13)
-            .anyTimes();
-        expect(controller.addConnectedSwitch(2000, handler)).andReturn(true)
-            .anyTimes();
-        replay(controller);
-        handler = new OFChannelHandler(controller);
-        verify(controller);
-        reset(controller);
-
-        resetChannel();
-
-        // replay controller. Reset it if you need more specific behavior
-        replay(controller);
-
-        // replay switch. Reset it if you need more specific behavior
-        replay(swImplBase);
-
-        // Mock ctx and channelStateEvent
-        expect(ctx.getChannel()).andReturn(channel).anyTimes();
-        expect(channelStateEvent.getChannel()).andReturn(channel).anyTimes();
-        replay(ctx, channelStateEvent);
-
-        /* 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
-         */
-        pipeline.sendUpstream(capture(exceptionEventCapture));
-        expectLastCall().anyTimes();
-        replay(pipeline);
-        featuresReply = (OFFeaturesReply) buildOFMessage(OFType.FEATURES_REPLY);
-    }
-
-    @After
-    public void tearDown() {
-        /* ensure no exception was thrown */
-        if (exceptionEventCapture.hasCaptured()) {
-            Throwable ex = exceptionEventCapture.getValue().getCause();
-            throw new AssertionError("Unexpected exception: " +
-                    ex.getClass().getName() + "(" + ex + ")");
-        }
-        assertFalse("Unexpected messages have been captured",
-                writeCapture.hasCaptured());
-        // verify all mocks.
-        verify(channel);
-        verify(messageEvent);
-        verify(controller);
-        verify(ctx);
-        verify(channelStateEvent);
-        verify(pipeline);
-        verify(swImplBase);
-
-    }
-
-    /**
-     * Reset the channel mock and set basic method call expectations.
-     *
-     **/
-    void resetChannel() {
-        reset(channel);
-        expect(channel.getPipeline()).andReturn(pipeline).anyTimes();
-        expect(channel.getRemoteAddress()).andReturn(null).anyTimes();
-    }
-
-    /**
-     * reset, setup, and replay the messageEvent mock for the given
-     * messages.
-     */
-    void setupMessageEvent(List<OFMessage> messages) {
-        reset(messageEvent);
-        expect(messageEvent.getMessage()).andReturn(messages).atLeastOnce();
-        replay(messageEvent);
-    }
-
-    /**
-     * 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 {
-        verify(controller);
-        reset(controller);
-
-        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 {
-        setupMessageEvent(messages);
-
-        expect(controller.addConnectedSwitch(1000, handler))
-        .andReturn(true).anyTimes();
-        replay(controller);
-
-        handler.messageReceived(ctx, messageEvent);
-        verify(controller);
-    }
-
-    /**
-     * 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().getCause();
-        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<Integer>();
-        }
-        for (OFMessage m: msgs)  {
-            int xid = (int) m.getXid();
-            assertTrue("Xid in messags is 0", xid != 0);
-            assertFalse("Xid " + xid + " has already been used",
-                    seenXids.contains(xid));
-            seenXids.add(xid);
-        }
-    }
-
-
-
-    public void testInitState() throws Exception {
-        OFMessage m = buildOFMessage(OFType.HELLO);
-
-        expect(messageEvent.getMessage()).andReturn(null);
-        replay(channel, messageEvent);
-
-        // We don't expect to receive /any/ messages in init state since
-        // channelConnected moves us to a different state
-        sendMessageToHandlerWithControllerReset(Collections.singletonList(m));
-
-        verifyExceptionCaptured(SwitchStateException.class);
-        assertEquals(OFChannelHandler.ChannelState.INIT,
-                handler.getStateForTesting());
-    }
-
-    /**
-     * move the channel from scratch to WAIT_HELLO state.
-     *
-     */
-    @Test
-    public void moveToWaitHello() throws Exception {
-        resetChannel();
-        channel.write(capture(writeCapture));
-        expectLastCall().andReturn(null).once();
-        replay(channel);
-        // replay unused mocks
-        replay(messageEvent);
-
-        handler.channelConnected(ctx, channelStateEvent);
-
-        List<OFMessage> msgs = getMessagesFromCapture();
-        assertEquals(1, msgs.size());
-        assertEquals(OFType.HELLO, msgs.get(0).getType());
-        assertEquals(OFChannelHandler.ChannelState.WAIT_HELLO,
-                handler.getStateForTesting());
-        //Should verify that the Hello received from the controller
-        //is ALWAYS OF1.3 hello regardless of the switch version
-        assertEquals(OFVersion.OF_13, msgs.get(0).getVersion());
-        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();
-        channel.write(capture(writeCapture));
-        expectLastCall().andReturn(null).atLeastOnce();
-        replay(channel);
-
-        OFMessage hello = buildOFMessage(OFType.HELLO);
-        sendMessageToHandlerWithControllerReset(Collections.singletonList(hello));
-
-        List<OFMessage> msgs = getMessagesFromCapture();
-        assertEquals(1, msgs.size());
-        assertEquals(OFType.FEATURES_REQUEST, msgs.get(0).getType());
-        if (ofVersion == OFVersion.OF_10) {
-            assertEquals(OFVersion.OF_10, msgs.get(0).getVersion());
-        }
-        verifyUniqueXids(msgs);
-
-        assertEquals(OFChannelHandler.ChannelState.WAIT_FEATURES_REPLY,
-                handler.getStateForTesting());
-    }
-
-    /**
-     * Move the channel from scratch to WAIT_CONFIG_REPLY state.
-     * Builds on moveToWaitFeaturesReply.
-     * adds testing for WAIT_FEATURES_REPLY state.
-     */
-    @Test
-    public void moveToWaitConfigReply() throws Exception {
-        moveToWaitFeaturesReply();
-
-        resetChannel();
-        channel.write(capture(writeCapture));
-        expectLastCall().andReturn(null).atLeastOnce();
-        replay(channel);
-
-        sendMessageToHandlerWithControllerReset(Collections.<OFMessage>singletonList(featuresReply));
-        List<OFMessage> msgs = getMessagesFromCapture();
-        assertEquals(3, msgs.size());
-        assertEquals(OFType.SET_CONFIG, msgs.get(0).getType());
-        OFSetConfig sc = (OFSetConfig) msgs.get(0);
-        assertEquals((short) 0xffff, sc.getMissSendLen());
-        assertEquals(OFType.BARRIER_REQUEST, msgs.get(1).getType());
-        assertEquals(OFType.GET_CONFIG_REQUEST, msgs.get(2).getType());
-        verifyUniqueXids(msgs);
-        assertEquals(OFChannelHandler.ChannelState.WAIT_CONFIG_REPLY,
-                handler.getStateForTesting());
-    }
-
-    /**
-     * Move the channel from scratch to WAIT_DESCRIPTION_STAT_REPLY state.
-     * Builds on moveToWaitConfigReply().
-     * adds testing for WAIT_CONFIG_REPLY state.
-     */
-    @Test
-    public void moveToWaitDescriptionStatReply() throws Exception {
-        moveToWaitConfigReply();
-        resetChannel();
-        channel.write(capture(writeCapture));
-        expectLastCall().andReturn(null).atLeastOnce();
-        replay(channel);
-
-        OFGetConfigReply cr = (OFGetConfigReply) buildOFMessage(OFType.GET_CONFIG_REPLY);
-
-        sendMessageToHandlerWithControllerReset(Collections.<OFMessage>singletonList(cr));
-
-        List<OFMessage> msgs = getMessagesFromCapture();
-        assertEquals(1, msgs.size());
-        assertEquals(OFType.STATS_REQUEST, msgs.get(0).getType());
-        OFStatsRequest<?> sr = (OFStatsRequest<?>) msgs.get(0);
-        assertEquals(OFStatsType.DESC, sr.getStatsType());
-        verifyUniqueXids(msgs);
-        assertEquals(OFChannelHandler.ChannelState.WAIT_DESCRIPTION_STAT_REPLY,
-                handler.getStateForTesting());
-    }
-
-
-    private OFStatsReply createDescriptionStatsReply() throws IOException {
-        OFStatsReply sr = (OFStatsReply) buildOFMessage(OFType.STATS_REPLY);
-        return sr;
-    }
-
-    /**
-     * Move the channel from scratch to WAIT_INITIAL_ROLE state.
-     * for a switch that does not have a sub-handshake.
-     * Builds on moveToWaitDescriptionStatReply().
-     * adds testing for WAIT_DESCRIPTION_STAT_REPLY state.
-     *
-     */
-    @Test
-    public void moveToWaitInitialRole()
-            throws Exception {
-        moveToWaitDescriptionStatReply();
-
-        long xid = 2000;
-
-        // build the stats reply
-        OFStatsReply sr = createDescriptionStatsReply();
-
-        resetChannel();
-        replay(channel);
-
-        setupMessageEvent(Collections.<OFMessage>singletonList(sr));
-
-        // mock controller
-        reset(controller);
-        reset(swImplBase);
-
-        expect(controller.getOFSwitchInstance((OFDescStatsReply) sr, ofVersion))
-        .andReturn(swImplBase).anyTimes();
-        expect(controller.getDebugCounter())
-        .andReturn(debugCounterService).anyTimes();
-        controller.submitRegistryRequest(1000);
-        expectLastCall().once();
-        replay(controller);
-
-        //TODO: With the description stats message you are sending in the test,
-        //you will end up with an OFSwitchImplBase object
-        //which by default does NOT support the nicira role messages.
-        //If you wish to test the case where Nicira role messages are supported,
-        //then make a comment here that states that this is different
-        //from the default behavior of switchImplbase /or/
-        //send the right desc-stats (for example send what is expected from OVS 1.0)
-
-        if (ofVersion == OFVersion.OF_10) {
-            expect(swImplBase.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE))
-            .andReturn(true).once();
-
-            swImplBase.write(capture(writeCapture));
-            expectLastCall().anyTimes();
-        }
-
-        swImplBase.setOFVersion(ofVersion);
-        expectLastCall().once();
-        swImplBase.setConnected(true);
-        expectLastCall().once();
-        swImplBase.setChannel(channel);
-        expectLastCall().once();
-        swImplBase.setDebugCounterService(controller.getDebugCounter());
-        expectLastCall().once();
-        expect(swImplBase.getStringId())
-        .andReturn(null).anyTimes();
-        swImplBase.setRole(Role.EQUAL);
-        expectLastCall().once();
-
-        expect(swImplBase.getNextTransactionId())
-        .andReturn((int) xid).anyTimes();
-        expect(swImplBase.getId())
-        .andReturn(1000L).once();
-
-        swImplBase.setFeaturesReply(featuresReply);
-        expectLastCall().once();
-        swImplBase.setPortDescReply((OFPortDescStatsReply) null);
-        replay(swImplBase);
-
-        // send the description stats reply
-        handler.messageReceived(ctx, messageEvent);
-
-        List<OFMessage> msgs = getMessagesFromCapture();
-        assertEquals(1, msgs.size());
-        assertEquals(OFType.EXPERIMENTER, msgs.get(0).getType());
-        verifyNiciraMessage((OFExperimenter) msgs.get(0));
-
-        verify(controller);
-        assertEquals(OFChannelHandler.ChannelState.WAIT_INITIAL_ROLE,
-                handler.getStateForTesting());
-    }
-
-    /**
-     * Move the channel from scratch to.
-     *  WAIT_SWITCH_DRIVER_SUB_HANDSHAKE state.
-     * Builds on moveToWaitInitialRole().
-     */
-    @Test
-    public void moveToWaitSubHandshake()
-            throws Exception {
-        moveToWaitInitialRole();
-
-        int xid = 2000;
-        resetChannel();
-        replay(channel);
-
-        reset(swImplBase);
-        // Set the role
-        setupSwitchSendRoleRequestAndVerify(true, xid, Role.SLAVE);
-        assertEquals(OFChannelHandler.ChannelState.WAIT_INITIAL_ROLE,
-                handler.getStateForTesting());
-
-        // build the stats reply
-        OFStatsReply sr = createDescriptionStatsReply();
-        OFMessage rr = getRoleReply(xid, Role.SLAVE);
-        setupMessageEvent(Collections.<OFMessage>singletonList(rr));
-
-        // mock controller
-        reset(controller);
-        reset(swImplBase);
-
-        expect(controller.getOFSwitchInstance((OFDescStatsReply) sr, ofVersion))
-        .andReturn(swImplBase).anyTimes();
-        expect(controller.getDebugCounter())
-        .andReturn(debugCounterService).anyTimes();
-
-        replay(controller);
-
-        expect(swImplBase.getStringId())
-        .andReturn(null).anyTimes();
-        swImplBase.setRole(Role.SLAVE);
-        expectLastCall().once();
-        expect(swImplBase.getNextTransactionId())
-        .andReturn(xid).anyTimes();
-        swImplBase.startDriverHandshake();
-        expectLastCall().once();
-
-        //when this flag is false, state machine will move to
-        //WAIT_SWITCH_DRIVER_SUB_HANDSHAKE state
-        expect(swImplBase.isDriverHandshakeComplete())
-        .andReturn(false).once();
-
-        replay(swImplBase);
-
-        // send the description stats reply
-        handler.messageReceived(ctx, messageEvent);
-
-        assertEquals(OFChannelHandler.ChannelState.WAIT_SWITCH_DRIVER_SUB_HANDSHAKE,
-                handler.getStateForTesting());
-    }
-
-    /**
-     * Move the channel from scratch to WAIT_INITIAL_ROLE state,
-     * then move the channel to EQUAL state based on the switch Role.
-     * This test basically test the switch with role support.
-     * Builds on moveToWaitInitialRole().
-     *
-     * In WAIT_INITIAL_ROLE state, when any messages (except ECHO_REQUEST
-     * and PORT_STATUS), state machine will transit to MASTER or
-     * EQUAL state based on the switch role.
-     */
-    @Test
-    public void moveToSlaveWithHandshakeComplete()
-            throws Exception {
-
-        moveToWaitInitialRole();
-
-        int xid = 2000;
-        resetChannel();
-        replay(channel);
-
-        reset(swImplBase);
-        // Set the role
-        setupSwitchSendRoleRequestAndVerify(true, xid, Role.SLAVE);
-        assertEquals(OFChannelHandler.ChannelState.WAIT_INITIAL_ROLE,
-                handler.getStateForTesting());
-
-        // build the stats reply
-        OFStatsReply sr = createDescriptionStatsReply();
-        OFMessage rr = getRoleReply(xid, Role.SLAVE);
-        setupMessageEvent(Collections.<OFMessage>singletonList(rr));
-
-        // mock controller
-        reset(controller);
-        reset(swImplBase);
-
-        expect(controller.getOFSwitchInstance((OFDescStatsReply) sr, ofVersion))
-        .andReturn(swImplBase).anyTimes();
-
-        expect(controller.getDebugCounter())
-        .andReturn(debugCounterService).anyTimes();
-
-        expect(controller.addActivatedEqualSwitch(1000, swImplBase))
-        .andReturn(true).once();
-        replay(controller);
-
-        expect(swImplBase.getStringId())
-        .andReturn(null).anyTimes();
-        //consult the role in sw to determine the next state.
-        //in this testing case, we are testing that channel handler
-        // will move to EQUAL state when switch role is in SLAVE.
-        expect(swImplBase.getRole()).andReturn(Role.SLAVE).once();
-        swImplBase.setRole(Role.SLAVE);
-        expectLastCall().once();
-
-        expect(swImplBase.getNextTransactionId())
-        .andReturn(xid).anyTimes();
-        expect(swImplBase.getId())
-        .andReturn(1000L).once();
-        swImplBase.startDriverHandshake();
-        expectLastCall().once();
-
-        //when this flag is true, don't need to move interim state
-        //WAIT_SWITCH_DRIVER_SUB_HANDSHAKE. channel handler will
-        //move to corresponding state after consulting the role in sw
-        //This is essentially the same test as the one above,
-        //except for this line
-        expect(swImplBase.isDriverHandshakeComplete())
-        .andReturn(true).once();
-
-        replay(swImplBase);
-
-        // send the description stats reply
-        handler.messageReceived(ctx, messageEvent);
-
-        assertEquals(OFChannelHandler.ChannelState.EQUAL,
-                handler.getStateForTesting());
-    }
-
-    /**
-     * Move the channel from scratch to WAIT_INITIAL_ROLE state,
-     * then to MASTERL state based on the switch Role.
-     * This test basically test the switch with role support.
-     * Builds on moveToWaitInitialRole().
-     *
-     * In WAIT_INITIAL_ROLE state, when any messages (except ECHO_REQUEST
-     * and PORT_STATUS), state machine will transit to MASTER or
-     * EQUAL state based on the switch role.
-     */
-    @Test
-    public void moveToMasterWithHandshakeComplete()
-            throws Exception {
-
-        moveToWaitInitialRole();
-
-        int xid = 2000;
-        resetChannel();
-        replay(channel);
-
-        reset(swImplBase);
-        // Set the role
-        setupSwitchSendRoleRequestAndVerify(true, xid, Role.MASTER);
-        assertEquals(OFChannelHandler.ChannelState.WAIT_INITIAL_ROLE,
-                handler.getStateForTesting());
-
-        // build the stats reply
-        OFStatsReply sr = createDescriptionStatsReply();
-        OFMessage rr = getRoleReply(xid, Role.MASTER);
-        setupMessageEvent(Collections.<OFMessage>singletonList(rr));
-
-        // mock controller
-        reset(controller);
-        reset(swImplBase);
-
-        expect(controller.getOFSwitchInstance((OFDescStatsReply) sr, ofVersion))
-        .andReturn(swImplBase).anyTimes();
-
-        expect(controller.getDebugCounter())
-        .andReturn(debugCounterService).anyTimes();
-
-        expect(controller.addActivatedMasterSwitch(1000, swImplBase))
-        .andReturn(true).once();
-        replay(controller);
-
-        expect(swImplBase.getStringId())
-        .andReturn(null).anyTimes();
-        expect(swImplBase.getRole()).andReturn(Role.MASTER).once();
-        swImplBase.setRole(Role.MASTER);
-        expectLastCall().once();
-
-        expect(swImplBase.getNextTransactionId())
-        .andReturn(xid).anyTimes();
-        expect(swImplBase.getId())
-        .andReturn(1000L).once();
-        swImplBase.startDriverHandshake();
-        expectLastCall().once();
-        expect(swImplBase.isDriverHandshakeComplete())
-        .andReturn(true).once();
-
-        replay(swImplBase);
-
-
-        // send the description stats reply
-        handler.messageReceived(ctx, messageEvent);
-
-        assertEquals(OFChannelHandler.ChannelState.MASTER,
-                handler.getStateForTesting());
-    }
-
-    /**
-     * Move the channel from scratch to
-     *  WAIT_SWITCH_DRIVER_SUB_HANDSHAKE state.
-     * Builds on moveToWaitSubHandshake().
-     */
-    @Test
-    public void moveToEqualViaWaitSubHandshake()
-            throws Exception {
-        moveToWaitSubHandshake();
-
-        long xid = 2000;
-        resetChannel();
-        replay(channel);
-
-        // build the stats reply
-        OFStatsReply sr = createDescriptionStatsReply();
-
-        setupMessageEvent(Collections.<OFMessage>singletonList(sr));
-
-        // mock controller
-        reset(controller);
-        reset(swImplBase);
-
-        expect(controller.getOFSwitchInstance((OFDescStatsReply) sr, ofVersion))
-        .andReturn(swImplBase).anyTimes();
-        expect(controller.getDebugCounter())
-        .andReturn(debugCounterService).anyTimes();
-
-        expect(controller.addActivatedEqualSwitch(1000, swImplBase))
-        .andReturn(true).once();
-        replay(controller);
-
-        expect(swImplBase.getStringId())
-        .andReturn(null).anyTimes();
-        expect(swImplBase.getRole()).andReturn(Role.SLAVE).once();
-        expect(swImplBase.getNextTransactionId())
-        .andReturn((int) xid).anyTimes();
-        expect(swImplBase.getId())
-        .andReturn(1000L).once();
-
-        swImplBase.processDriverHandshakeMessage(sr);
-        expectLastCall().once();
-        expect(swImplBase.isDriverHandshakeComplete())
-        .andReturn(true).once();
-
-        replay(swImplBase);
-
-        // send the description stats reply
-        handler.messageReceived(ctx, messageEvent);
-
-        assertEquals(OFChannelHandler.ChannelState.EQUAL,
-                handler.getStateForTesting());
-    }
-
-    /**
-     * Move the channel from scratch to
-     *  WAIT_SWITCH_DRIVER_SUB_HANDSHAKE state.
-     * Builds on moveToWaitSubHandshake().
-     */
-    @Test
-    public void moveToMasterViaWaitSubHandshake()
-            throws Exception {
-        moveToWaitSubHandshake();
-
-        long xid = 2000;
-        resetChannel();
-        replay(channel);
-
-        // In this state, any messages except echo request, port status and
-        // error go to the switch sub driver handshake. Once the switch reports
-        // that its sub driver handshake is complete (#isDriverHandshakeComplete
-        // return true) then the channel handle consults the switch role and
-        // moves the state machine to the appropriate state (MASTER or EQUALS).
-        // In this test we expect the state machine to end up in MASTER state.
-        OFStatsReply sr = createDescriptionStatsReply();
-
-        setupMessageEvent(Collections.<OFMessage>singletonList(sr));
-
-        // mock controller
-        reset(controller);
-        reset(swImplBase);
-
-        expect(controller.getOFSwitchInstance((OFDescStatsReply) sr, ofVersion))
-        .andReturn(swImplBase).anyTimes();
-
-        expect(controller.getDebugCounter())
-        .andReturn(debugCounterService).anyTimes();
-        expect(controller.addActivatedMasterSwitch(1000, swImplBase))
-        .andReturn(true).once();
-        replay(controller);
-
-        expect(swImplBase.getStringId())
-        .andReturn(null).anyTimes();
-        expect(swImplBase.getRole()).andReturn(Role.MASTER).once();
-        expect(swImplBase.getNextTransactionId())
-        .andReturn((int) xid).anyTimes();
-        expect(swImplBase.getId())
-        .andReturn(1000L).once();
-
-        swImplBase.processDriverHandshakeMessage(sr);
-        expectLastCall().once();
-        expect(swImplBase.isDriverHandshakeComplete())
-        .andReturn(true).once();
-
-        replay(swImplBase);
-
-        // send the description stats reply
-        handler.messageReceived(ctx, messageEvent);
-        verify(controller);
-        assertEquals(OFChannelHandler.ChannelState.MASTER,
-                handler.getStateForTesting());
-    }
-
-    /**
-     * Test the behavior in WAIT_SWITCH_DRIVER_SUB_HANDSHAKE state.
-     * ECHO_REQUEST message received case.
-     */
-    @Test
-    public void testWaitSwitchDriverSubhandshake() throws Exception {
-        moveToWaitSubHandshake();
-
-        long xid = 2000;
-        resetChannel();
-        channel.write(capture(writeCapture));
-        expectLastCall().andReturn(null).atLeastOnce();
-        replay(channel);
-
-        OFMessage er = buildOFMessage(OFType.ECHO_REQUEST);
-
-        setupMessageEvent(Collections.<OFMessage>singletonList(er));
-
-        // mock controller
-        reset(controller);
-        reset(swImplBase);
-
-        expect(controller.getOFMessageFactory10()).andReturn(factory10);
-        expect(controller.getDebugCounter())
-        .andReturn(debugCounterService).anyTimes();
-
-        replay(controller);
-
-        expect(swImplBase.getStringId())
-        .andReturn(null).anyTimes();
-        expect(swImplBase.getNextTransactionId())
-        .andReturn((int) xid).anyTimes();
-
-        replay(swImplBase);
-
-        handler.messageReceived(ctx, messageEvent);
-
-        List<OFMessage> msgs = getMessagesFromCapture();
-        assertEquals(1, msgs.size());
-        assertEquals(OFType.ECHO_REPLY, msgs.get(0).getType());
-        verifyUniqueXids(msgs);
-        assertEquals(OFChannelHandler.ChannelState.WAIT_SWITCH_DRIVER_SUB_HANDSHAKE,
-                handler.getStateForTesting());
-    }
-
-    /**
-     * Helper.
-     * Verify that the given OFMessage is a correct Nicira RoleRequest message.
-     */
-    private void verifyNiciraMessage(OFExperimenter ofMessage) {
-
-        int vendor = (int) ofMessage.getExperimenter();
-        assertEquals(vendor, 0x2320); // magic number representing nicira
-    }
-
-    /**
-     * Setup the mock switch and write capture for a role request, set the
-     * role and verify mocks.
-     * @param supportsNxRole whether the switch supports role request messages
-     * to setup the attribute. This must be null (don't yet know if roles
-     * supported: send to check) or true.
-     * @param xid The xid to use in the role request
-     * @param role The role to send
-     * @throws IOException
-     */
-    private void setupSwitchSendRoleRequestAndVerify(Boolean supportsNxRole,
-            int xid,
-            Role role) throws IOException {
-
-        RoleRecvStatus expectation = RoleRecvStatus.MATCHED_SET_ROLE;
-
-        expect(swImplBase.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE))
-        .andReturn(supportsNxRole).atLeastOnce();
-
-        if (supportsNxRole != null && supportsNxRole) {
-            expect(swImplBase.getNextTransactionId()).andReturn(xid).once();
-            swImplBase.write(capture(writeCapture));
-            expectLastCall().anyTimes();
-        }
-        replay(swImplBase);
-
-        handler.sendRoleRequest(role, expectation);
-
-        if (supportsNxRole != null && supportsNxRole) {
-            List<OFMessage> msgs = getMessagesFromCapture();
-            assertEquals(1, msgs.size());
-            verifyNiciraMessage((OFExperimenter) msgs.get(0));
-        }
-    }
-
-    /**
-     * Setup the mock switch for a role change request where the switch
-     * does not support roles.
-     *
-     * Needs to verify and reset the controller since we need to set
-     * an expectation
-     */
-    private void setupSwitchRoleChangeUnsupported(int xid,
-            Role role) {
-        boolean supportsNxRole = false;
-        RoleRecvStatus expectation = RoleRecvStatus.NO_REPLY;
-        reset(swImplBase);
-        expect(swImplBase.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE))
-        .andReturn(supportsNxRole).atLeastOnce();
-        // TODO: hmmm. While it's not incorrect that we set the attribute
-        // again it looks odd. Maybe change
-        swImplBase.setAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE, supportsNxRole);
-        expectLastCall().anyTimes();
-
-        replay(swImplBase);
-
-        handler.sendRoleRequest(role, expectation);
-
-        verify(swImplBase);
-    }
-
-    /*
-     * Return a Nicira RoleReply message for the given role.
-     */
-    private OFMessage getRoleReply(long xid, Role role) {
-
-        OFNiciraControllerRole nr = null;
-
-        switch(role) {
-        case MASTER:
-            nr = OFNiciraControllerRole.ROLE_MASTER;
-            break;
-        case EQUAL:
-            nr = OFNiciraControllerRole.ROLE_SLAVE;
-            break;
-        case SLAVE:
-            nr = OFNiciraControllerRole.ROLE_SLAVE;
-            break;
-        default: //handled below
-        }
-        OFMessage m = factory10.buildNiciraControllerRoleReply()
-                .setRole(nr)
-                .setXid(xid)
-                .build();
-        return m;
-    }
-
-    /**
-     * Move the channel from scratch to MASTER state.
-     * Builds on moveToWaitInitialRole().
-     * adds testing for WAIT_INITAL_ROLE state.
-     *
-     * This method tests the case that the switch does NOT support roles.
-     * In ONOS if the switch-driver says that nicira-role messages are not
-     * supported, then ONOS does NOT send role-request messages
-     * (see handleUnsentRoleMessage())
-     */
-    @Test
-    public void testInitialMoveToMasterNoRole() throws Exception {
-        int xid = 43;
-        // first, move us to WAIT_INITIAL_ROLE_STATE
-
-        moveToWaitInitialRole();
-        assertEquals(OFChannelHandler.ChannelState.WAIT_INITIAL_ROLE,
-                handler.getStateForTesting());
-
-        OFStatsReply sr = createDescriptionStatsReply();
-
-        reset(controller);
-        reset(swImplBase);
-
-        expect(controller.getOFSwitchInstance((OFDescStatsReply) sr, ofVersion))
-        .andReturn(swImplBase).anyTimes();
-
-        expect(controller.getDebugCounter())
-        .andReturn(debugCounterService).anyTimes();
-
-        expect(controller.addActivatedMasterSwitch(1000, swImplBase))
-        .andReturn(true).once();
-        replay(controller);
-
-        reset(swImplBase);
-        swImplBase.setRole(Role.MASTER);
-        expectLastCall().once();
-        swImplBase.startDriverHandshake();
-        expectLastCall().once();
-        expect(swImplBase.isDriverHandshakeComplete())
-        .andReturn(true).once();
-        expect(swImplBase.getStringId())
-        .andReturn(null).anyTimes();
-        expect(swImplBase.getRole()).andReturn(Role.MASTER).once();
-
-        expect(swImplBase.getId())
-        .andReturn(1000L).once();
-        // Set the role
-        setupSwitchSendRoleRequestAndVerify(false, xid, Role.MASTER);
-
-        assertEquals(OFChannelHandler.ChannelState.MASTER,
-                handler.getStateForTesting());
-    }
-
-    /**
-     * Move the channel from scratch to WAIT_INITIAL_ROLE state.
-     * Builds on moveToWaitInitialRole().
-     * adds testing for WAIT_INITAL_ROLE state
-     *
-     * We let the initial role request time out. Role support should be
-     * disabled but the switch should be activated.
-     */
-    /* TBD
-        @Test
-        public void testInitialMoveToMasterTimeout() throws Exception {
-            int timeout = 50;
-            handler.useRoleChangerWithOtherTimeoutForTesting(timeout);
-            int xid = 4343;
-
-            // first, move us to WAIT_INITIAL_ROLE_STATE
-
-            moveToWaitInitialRole();
-            assertEquals(OFChannelHandler.ChannelState.WAIT_INITIAL_ROLE,
-                    handler.getStateForTesting());
-
-            // prepare mocks and inject the role reply message
-            reset(swImplBase);
-            // Set the role
-            swImplBase.setRole(Role.MASTER);
-            expectLastCall().once();
-            swImplBase.startDriverHandshake();
-            expectLastCall().once();
-            expect(swImplBase.isDriverHandshakeComplete())
-            .andReturn(false).once();
-            if (ofVersion == OFVersion.OF_10) {
-                expect(swImplBase.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE))
-                 .andReturn(true).once();
-
-                swImplBase.write(capture(writeCapture),
-                        EasyMock.<FloodlightContext>anyObject());
-                expectLastCall().anyTimes();
-             }
-            expect(swImplBase.getNextTransactionId()).andReturn(xid).once();
-
-            assertEquals(OFChannelHandler.ChannelState.WAIT_INITIAL_ROLE,
-                    handler.getStateForTesting());
-
-            // Set the role
-            setupSwitchSendRoleRequestAndVerify(null, xid, Role.MASTER);
-            assertEquals(OFChannelHandler.ChannelState.WAIT_INITIAL_ROLE,
-                    handler.getStateForTesting());
-
-            OFMessage m = buildOFMessage(OFType.ECHO_REPLY);
-
-            setupMessageEvent(Collections.<OFMessage>singletonList(m));
-
-            Thread.sleep(timeout+5);
-
-            verify(controller);
-            reset(controller);
-
-            expect(controller.addActivatedMasterSwitch(1000, swImplBase))
-            .andReturn(true).once();
-            controller.flushAll();
-            expectLastCall().once();
-
-            replay(controller);
-
-            handler.messageReceived(ctx, messageEvent);
-
-            assertEquals(OFChannelHandler.ChannelState.MASTER,
-                    handler.getStateForTesting());
-
-        }
-
-     */
-    /**
-     * Move the channel from scratch to SLAVE state.
-     * Builds on doMoveToWaitInitialRole().
-     * adds testing for WAIT_INITAL_ROLE state
-     *
-     * This method tests the case that the switch does NOT support roles.
-     * The channel handler still needs to send the initial request to find
-     * out that whether the switch supports roles.
-     *
-     */
-    @Test
-    public void testInitialMoveToSlaveNoRole() throws Exception {
-        int xid = 44;
-        // first, move us to WAIT_INITIAL_ROLE_STATE
-        moveToWaitInitialRole();
-        assertEquals(OFChannelHandler.ChannelState.WAIT_INITIAL_ROLE,
-                handler.getStateForTesting());
-
-        reset(swImplBase);
-        // Set the role
-        setupSwitchSendRoleRequestAndVerify(false, xid, Role.SLAVE);
-        assertEquals(OFChannelHandler.ChannelState.WAIT_INITIAL_ROLE,
-                handler.getStateForTesting());
-
-    }
-
-    /**
-     * Move the channel from scratch to SLAVE state.
-     * Builds on doMoveToWaitInitialRole().
-     * adds testing for WAIT_INITAL_ROLE state
-     *
-     * We let the initial role request time out. The switch should be
-     * disconnected
-     */
-    /* TBD
-        @Test
-        public void testInitialMoveToSlaveTimeout() throws Exception {
-            int timeout = 50;
-            handler.useRoleChangerWithOtherTimeoutForTesting(timeout);
-            int xid = 4444;
-
-            // first, move us to WAIT_INITIAL_ROLE_STATE
-            moveToWaitInitialRole();
-            assertEquals(OFChannelHandler.ChannelState.WAIT_INITIAL_ROLE,
-                    handler.getStateForTesting());
-
-            // Set the role
-            setupSwitchSendRoleRequestAndVerify(null, xid, Role.SLAVE);
-            assertEquals(OFChannelHandler.ChannelState.WAIT_INITIAL_ROLE,
-                    handler.getStateForTesting());
-
-            // prepare mocks and inject the role reply message
-            reset(sw);
-            sw.setAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE, false);
-            expectLastCall().once();
-            sw.setRole(Role.SLAVE);
-            expectLastCall().once();
-            sw.disconnectSwitch(); // Make sure we disconnect
-            expectLastCall().once();
-            replay(sw);
-
-            OFMessage m = buildOFMessage(OFType.ECHO_REPLY);
-
-            Thread.sleep(timeout+5);
-
-            sendMessageToHandlerWithControllerReset(Collections.singletonList(m));
-        }
-
-     */
-    /**
-     * Move channel from scratch to WAIT_INITIAL_STATE, then MASTER,
-     * then SLAVE for cases where the switch does not support roles.
-     * I.e., the final SLAVE transition should disconnect the switch.
-     */
-    @Test
-    public void testNoRoleInitialToMasterToSlave() throws Exception {
-        int xid = 46;
-        reset(swImplBase);
-        replay(swImplBase);
-
-        reset(controller);
-        replay(controller);
-
-        // First, lets move the state to MASTER without role support
-        testInitialMoveToMasterNoRole();
-        assertEquals(OFChannelHandler.ChannelState.MASTER,
-                handler.getStateForTesting());
-
-        // try to set master role again. should be a no-op
-        setupSwitchRoleChangeUnsupported(xid, Role.MASTER);
-
-        assertEquals(OFChannelHandler.ChannelState.MASTER,
-                handler.getStateForTesting());
-
-        setupSwitchRoleChangeUnsupported(xid, Role.SLAVE);
-        //switch does not support role message. there is no role set
-        assertEquals(OFChannelHandler.ChannelState.MASTER,
-                handler.getStateForTesting());
-
-    }
-
-    /**
-     * Move the channel to MASTER state.
-     * Expects that the channel is in MASTER or SLAVE state.
-     *
-     */
-    public void changeRoleToMasterWithRequest() throws Exception {
-        int xid = 4242;
-
-        assertTrue("This method can only be called when handler is in " +
-                "MASTER or SLAVE role", handler.isHandshakeComplete());
-
-        reset(swImplBase);
-        reset(controller);
-        // Set the role
-        setupSwitchSendRoleRequestAndVerify(true, xid, Role.MASTER);
-
-        // prepare mocks and inject the role reply message
-
-        reset(controller);
-        expect(controller.addActivatedMasterSwitch(1000, swImplBase))
-        .andReturn(true).once();
-        OFMessage reply = getRoleReply(xid, Role.MASTER);
-
-        // sendMessageToHandler will verify and rest controller mock
-
-        OFStatsReply sr = createDescriptionStatsReply();
-        setupMessageEvent(Collections.<OFMessage>singletonList(reply));
-
-        // mock controller
-        reset(controller);
-        reset(swImplBase);
-
-        expect(controller.getOFSwitchInstance((OFDescStatsReply) sr, ofVersion))
-        .andReturn(swImplBase).anyTimes();
-
-        expect(controller.getDebugCounter())
-        .andReturn(debugCounterService).anyTimes();
-        controller.transitionToMasterSwitch(1000);
-        expectLastCall().once();
-
-        replay(controller);
-
-        expect(swImplBase.getStringId())
-        .andReturn(null).anyTimes();
-        expect(swImplBase.getRole()).andReturn(Role.EQUAL).atLeastOnce();
-        expect(swImplBase.getNextTransactionId())
-        .andReturn(xid).anyTimes();
-        expect(swImplBase.getId())
-        .andReturn(1000L).once();
-
-        swImplBase.setRole(Role.MASTER);
-        expectLastCall().once();
-        replay(swImplBase);
-
-        // send the description stats reply
-        handler.messageReceived(ctx, messageEvent);
-
-        assertEquals(OFChannelHandler.ChannelState.MASTER,
-                handler.getStateForTesting());
-    }
-
-    /**
-     * Move the channel to SLAVE state.
-     * Expects that the channel is in MASTER or SLAVE state.
-     *
-     */
-    public void changeRoleToSlaveWithRequest() throws Exception {
-        int xid = 2323;
-
-        assertTrue("This method can only be called when handler is in " +
-                "MASTER or SLAVE role", handler.isHandshakeComplete());
-
-        // Set the role
-        reset(controller);
-        reset(swImplBase);
-
-        swImplBase.write(capture(writeCapture));
-        expectLastCall().anyTimes();
-
-        expect(swImplBase.getNextTransactionId())
-        .andReturn(xid).anyTimes();
-
-
-        if (ofVersion == OFVersion.OF_10) {
-            expect(swImplBase.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE))
-            .andReturn(true).once();
-
-            swImplBase.write(capture(writeCapture));
-            expectLastCall().anyTimes();
-        }
-        replay(swImplBase);
-
-        handler.sendRoleRequest(Role.SLAVE, RoleRecvStatus.MATCHED_SET_ROLE);
-
-        List<OFMessage> msgs = getMessagesFromCapture();
-        assertEquals(1, msgs.size());
-        verifyNiciraMessage((OFExperimenter) msgs.get(0));
-
-
-        OFMessage reply = getRoleReply(xid, Role.SLAVE);
-        OFStatsReply sr = createDescriptionStatsReply();
-        setupMessageEvent(Collections.<OFMessage>singletonList(reply));
-
-        // mock controller
-        reset(controller);
-        reset(swImplBase);
-
-        controller.transitionToEqualSwitch(1000);
-        expectLastCall().once();
-        expect(controller.getOFSwitchInstance((OFDescStatsReply) sr, ofVersion))
-        .andReturn(swImplBase).anyTimes();
-
-        expect(controller.getDebugCounter())
-        .andReturn(debugCounterService).anyTimes();
-
-        replay(controller);
-
-        expect(swImplBase.getStringId())
-        .andReturn(null).anyTimes();
-        expect(swImplBase.getRole()).andReturn(Role.MASTER).atLeastOnce();
-        expect(swImplBase.getNextTransactionId())
-        .andReturn(xid).anyTimes();
-
-        // prepare mocks and inject the role reply message
-        swImplBase.setRole(Role.SLAVE);
-        expectLastCall().once();
-        expect(swImplBase.getId())
-        .andReturn(1000L).once();
-        replay(swImplBase);
-
-        handler.messageReceived(ctx, messageEvent);
-
-        assertEquals(OFChannelHandler.ChannelState.EQUAL,
-                handler.getStateForTesting());
-    }
-
-    @Test
-    public void testMultiRoleChange1() throws Exception {
-        moveToMasterWithHandshakeComplete();
-        changeRoleToMasterWithRequest();
-        changeRoleToSlaveWithRequest();
-        changeRoleToSlaveWithRequest();
-        changeRoleToMasterWithRequest();
-        changeRoleToSlaveWithRequest();
-    }
-
-    @Test
-    public void testMultiRoleChange2() throws Exception {
-        moveToSlaveWithHandshakeComplete();
-        changeRoleToMasterWithRequest();
-        changeRoleToSlaveWithRequest();
-        changeRoleToSlaveWithRequest();
-        changeRoleToMasterWithRequest();
-        changeRoleToSlaveWithRequest();
-    }
-
-    /**
-     * Start from scratch and reply with an unexpected error to the role
-     * change request.
-     * Builds on doMoveToWaitInitialRole()
-     * adds testing for WAIT_INITAL_ROLE state
-     */
-    /* TBD
-        @Test
-        public void testInitialRoleChangeOtherError() throws Exception {
-            int xid = 4343;
-            // first, move us to WAIT_INITIAL_ROLE_STATE
-            moveToWaitInitialRole();
-            assertEquals(OFChannelHandler.ChannelState.WAIT_INITIAL_ROLE,
-                    handler.getStateForTesting());
-
-            reset(swImplBase);
-            // Set the role
-            setupSwitchSendRoleRequestAndVerify(true, xid, Role.MASTER);
-            assertEquals(OFChannelHandler.ChannelState.WAIT_INITIAL_ROLE,
-                    handler.getStateForTesting());
-
-
-            // FIXME: shouldn't use ordinal(), but OFError is broken
-
-            OFMessage err = factory.errorMsgs().buildBadActionErrorMsg()
-                    .setCode(OFBadActionCode.BAD_LEN)
-                    .setXid(2000)
-                    .build();
-            verify(swImplBase);
-            reset(swImplBase);
-            replay(swImplBase);
-            sendMessageToHandlerWithControllerReset(Collections.singletonList(err));
-
-            verifyExceptionCaptured(SwitchStateException.class);
-        }
-     */
-    /**
-     * Test dispatch of messages while in MASTER role.
-     */
-    @Test
-    public void testMessageDispatchMaster() throws Exception {
-
-        moveToMasterWithHandshakeComplete();
-
-        // Send packet in. expect dispatch
-        OFPacketIn pi = (OFPacketIn)
-                buildOFMessage(OFType.PACKET_IN);
-        setupMessageEvent(Collections.<OFMessage>singletonList(pi));
-
-        reset(swImplBase);
-        swImplBase.handleMessage(pi);
-        expectLastCall().once();
-        replay(swImplBase);
-        // send the description stats reply
-        handler.messageReceived(ctx, messageEvent);
-
-        assertEquals(OFChannelHandler.ChannelState.MASTER,
-                handler.getStateForTesting());
-
-        verify(controller);
-        // TODO: many more to go
-    }
-
-    /**
-     * Test port status message handling while MASTER.
-     *
-     */
-    /* Patrick: TBD
-        @Test
-        public void testPortStatusMessageMaster() throws Exception {
-            long dpid = featuresReply.getDatapathId().getLong();
-            testInitialMoveToMasterWithRole();
-            List<OFPortDesc> ports = new ArrayList<OFPortDesc>();
-            // A dummy port.
-            OFPortDesc p = factory.buildPortDesc()
-                        .setName("Eth1")
-                        .setPortNo(OFPort.ofInt(1))
-                        .build();
-            ports.add(p);
-
-            p.setName("Port1");
-            p.setPortNumber((short)1);
-
-            OFPortStatus ps = (OFPortStatus)buildOFMessage(OFType.PORT_STATUS);
-            ps.setDesc(p);
-
-            // The events we expect sw.handlePortStatus to return
-            // We'll just use the same list for all valid OFPortReasons and add
-            // arbitrary events for arbitrary ports that are not necessarily
-            // related to the port status message. Our goal
-            // here is not to return the correct set of events but the make sure
-            // that a) sw.handlePortStatus is called
-            //      b) the list of events sw.handlePortStatus returns is sent
-            //         as IOFSwitchListener notifications.
-            OrderedCollection<PortChangeEvent> events =
-                    new LinkedHashSetWrapper<PortChangeEvent>();
-            ImmutablePort p1 = ImmutablePort.create("eth1", (short)1);
-            ImmutablePort p2 = ImmutablePort.create("eth2", (short)2);
-            ImmutablePort p3 = ImmutablePort.create("eth3", (short)3);
-            ImmutablePort p4 = ImmutablePort.create("eth4", (short)4);
-            ImmutablePort p5 = ImmutablePort.create("eth5", (short)5);
-            events.add(new PortChangeEvent(p1, PortChangeType.ADD));
-            events.add(new PortChangeEvent(p2, PortChangeType.DELETE));
-            events.add(new PortChangeEvent(p3, PortChangeType.UP));
-            events.add(new PortChangeEvent(p4, PortChangeType.DOWN));
-            events.add(new PortChangeEvent(p5, PortChangeType.OTHER_UPDATE));
-
-
-            for (OFPortReason reason: OFPortReason.values()) {
-                ps.setReason(reason.getReasonCode());
-
-                reset(sw);
-                expect(sw.getId()).andReturn(dpid).anyTimes();
-
-                expect(sw.processOFPortStatus(ps)).andReturn(events).once();
-                replay(sw);
-
-                reset(controller);
-                controller.notifyPortChanged(sw, p1, PortChangeType.ADD);
-                controller.notifyPortChanged(sw, p2, PortChangeType.DELETE);
-                controller.notifyPortChanged(sw, p3, PortChangeType.UP);
-                controller.notifyPortChanged(sw, p4, PortChangeType.DOWN);
-                controller.notifyPortChanged(sw, p5, PortChangeType.OTHER_UPDATE);
-                sendMessageToHandlerNoControllerReset(
-                        Collections.<OFMessage>singletonList(ps));
-                verify(sw);
-                verify(controller);
-            }
-        }
-
-     */
-    /**
-     * Build an OF message.
-     * @throws IOException
-     */
-    private OFMessage buildOFMessage(OFType t) throws IOException {
-        OFMessage m = null;
-        switch (t) {
-
-        case HELLO:
-            // The OF protocol requires us to start things off by sending the highest
-            // version of the protocol supported.
-
-            // bitmap represents OF1.0 (ofp_version=0x01) and OF1.3 (ofp_version=0x04)
-            // see Sec. 7.5.1 of the OF1.3.4 spec
-            if (ofVersion == OFVersion.OF_13) {
-                U32 bitmap = U32.ofRaw(0x00000012);
-                OFHelloElem hem = factory13.buildHelloElemVersionbitmap()
-                    .setBitmaps(Collections.singletonList(bitmap))
-                    .build();
-                m = factory13.buildHello()
-                        .setXid(2000)
-                        .setElements(Collections.singletonList(hem))
-                        .build();
-            } else {
-                m = factory10.buildHello()
-                    .setXid(2000)
-                    .build();
-            }
-            break;
-        case FEATURES_REQUEST:
-            m = factory.buildFeaturesRequest()
-            .setXid(2000)
-            .build();
-            break;
-        case FEATURES_REPLY:
-
-            m = factory.buildFeaturesReply()
-            .setDatapathId(DatapathId.of(1000L))
-            .setXid(2000)
-            .build();
-            break;
-        case SET_CONFIG:
-            m = factory.buildSetConfig()
-            .setMissSendLen((short) 0xffff)
-            .setXid(2000)
-            .build();
-            break;
-        case BARRIER_REQUEST:
-            m = factory.buildBarrierRequest()
-            .setXid(2000)
-            .build();
-            break;
-        case GET_CONFIG_REQUEST:
-            m = factory.buildGetConfigRequest()
-            .setXid(2000)
-            .build();
-            break;
-        case GET_CONFIG_REPLY:
-            m = factory.buildGetConfigReply()
-            .setMissSendLen((short) 0xffff)
-            .setXid(2000)
-            .build();
-            break;
-        case STATS_REQUEST:
-            break;
-        case STATS_REPLY:
-            m = factory.buildDescStatsReply()
-            .setDpDesc("Datapath Description")
-            .setHwDesc("Hardware Secription")
-            .setMfrDesc("Manufacturer Desctiption")
-            .setSerialNum("Serial Number")
-            .setSwDesc("Software Desription")
-            .build();
-            break;
-        case ECHO_REQUEST:
-            m = factory.buildEchoRequest()
-            .setXid(2000)
-            .build();
-            break;
-        case FLOW_REMOVED:
-            break;
-
-        case PACKET_IN:
-            m = factory.buildPacketIn()
-            .setReason(OFPacketInReason.NO_MATCH)
-            .setTotalLen(1500)
-            .setXid(2000)
-            .build();
-            break;
-        case PORT_STATUS:
-            m = factory.buildPortStatus()
-            .setXid(2000)
-            .build();
-            break;
-
-        default:
-            m = factory.buildFeaturesRequest()
-            .setXid(2000)
-            .build();
-            break;
-        }
-
-        return (m);
-    }
-}
