splitting roles from IO loop and providing a abstract of switch
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();
+    }
+
 }