diff --git a/openflow/api/pom.xml b/openflow/api/pom.xml
index dd8f582..efdba83 100644
--- a/openflow/api/pom.xml
+++ b/openflow/api/pom.xml
@@ -42,6 +42,11 @@
             <groupId>io.netty</groupId>
             <artifactId>netty</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-api</artifactId>
+        </dependency>
+
     </dependencies>
 
     <build>
diff --git a/openflow/api/src/main/java/org/onosproject/openflow/controller/OpenFlowSwitch.java b/openflow/api/src/main/java/org/onosproject/openflow/controller/OpenFlowSwitch.java
index 89ac278..5a89543 100644
--- a/openflow/api/src/main/java/org/onosproject/openflow/controller/OpenFlowSwitch.java
+++ b/openflow/api/src/main/java/org/onosproject/openflow/controller/OpenFlowSwitch.java
@@ -15,12 +15,11 @@
  */
 package org.onosproject.openflow.controller;
 
-import java.util.List;
-
 import org.projectfloodlight.openflow.protocol.OFFactory;
 import org.projectfloodlight.openflow.protocol.OFMessage;
 import org.projectfloodlight.openflow.protocol.OFPortDesc;
-import org.projectfloodlight.openflow.types.TableId;
+
+import java.util.List;
 
 /**
  * Represents to provider facing side of a switch.
@@ -28,38 +27,6 @@
 public interface OpenFlowSwitch {
 
     /**
-     * The TableType is used to determine in which table (TableID) each flow rule
-     * needs to be put for multi-table support switch.
-     * It is used only for multi-table support switch.
-     */
-    public static enum TableType {
-        /* VLAN-to-MPLS table */
-        VLAN_MPLS,
-
-        /* VLAN table */
-        VLAN,
-
-        /* Ethertype table */
-        ETHER,
-
-        /* Class of Service table */
-        COS,
-
-        /* IP table */
-        IP,
-        /* MPLS table */
-        MPLS,
-        /* ACL table */
-        ACL,
-        /* Single table */
-        NONE,
-        /* First table in multi-table */
-        FIRST,
-
-
-    }
-
-    /**
      * Writes the message to the driver.
      *
      * @param msg the message to write
@@ -74,17 +41,6 @@
     public void sendMsg(List<OFMessage> msgs);
 
     /**
-     * Transforms FlowMod messages by setting the correct table-ids and sending
-     * them to the switch. TableType is used to determine the table ID for the OFMessage.
-     * Switch drivers that supports multi-table pipelines should implement this
-     * method.
-     *
-     * @param msg the message to be written
-     * @param tableType the type of table in which the FlowMods need to be inserted
-     */
-    public void transformAndSendMsg(OFMessage msg, TableType tableType);
-
-    /**
      * Handle a message from the switch.
      * @param fromSwitch the message to handle
      */
@@ -192,12 +148,4 @@
      * @return string representation of the connection to the device
      */
     public String channelId();
-
-    /**
-     * Returns the TableType corresponding to the TableId used to identify
-     * a table in an OpenFlow switch.
-     * @param tid identifies a table in an OpenFlow switch using TableId
-     * @return TableType corresponding to 'tid' identifying the type of table
-     */
-    public TableType getTableType(TableId tid);
 }
diff --git a/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/AbstractOpenFlowSwitch.java b/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/AbstractOpenFlowSwitch.java
index ebfa635..56d88b5 100644
--- a/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/AbstractOpenFlowSwitch.java
+++ b/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/AbstractOpenFlowSwitch.java
@@ -20,6 +20,7 @@
 import java.net.InetSocketAddress;
 import java.net.SocketAddress;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.RejectedExecutionException;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -27,6 +28,7 @@
 
 import org.jboss.netty.channel.Channel;
 import org.onlab.packet.IpAddress;
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
 import org.onosproject.openflow.controller.Dpid;
 import org.onosproject.openflow.controller.RoleState;
 import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
@@ -36,10 +38,12 @@
 import org.projectfloodlight.openflow.protocol.OFFactory;
 import org.projectfloodlight.openflow.protocol.OFFeaturesReply;
 import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFNiciraControllerRoleRequest;
 import org.projectfloodlight.openflow.protocol.OFPortDesc;
 import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply;
 import org.projectfloodlight.openflow.protocol.OFPortStatus;
 import org.projectfloodlight.openflow.protocol.OFRoleReply;
+import org.projectfloodlight.openflow.protocol.OFRoleRequest;
 import org.projectfloodlight.openflow.protocol.OFVersion;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -48,18 +52,19 @@
  * An abstract representation of an OpenFlow switch. Can be extended by others
  * to serve as a base for their vendor specific representation of a switch.
  */
-public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitchDriver {
+public abstract class AbstractOpenFlowSwitch extends AbstractHandlerBehaviour
+        implements OpenFlowSwitchDriver {
 
     protected final Logger log = LoggerFactory.getLogger(getClass());
 
     private static final String SHUTDOWN_MSG = "Worker has already been shutdown";
 
-    protected Channel channel;
+    private Channel channel;
     protected String channelId;
 
     private boolean connected;
     protected boolean startDriverHandshakeCalled = false;
-    private final Dpid dpid;
+    private Dpid dpid;
     private OpenFlowAgent agent;
     private final AtomicInteger xidCounter = new AtomicInteger(0);
 
@@ -76,17 +81,11 @@
     protected OFFeaturesReply features;
     protected OFDescStatsReply desc;
 
-    /**
-     * Given a dpid build this switch.
-     * @param dp the dpid
-     */
-    protected AbstractOpenFlowSwitch(Dpid dp) {
-        this.dpid = dp;
-    }
-
-    public AbstractOpenFlowSwitch(Dpid dpid, OFDescStatsReply desc) {
+    @Override
+    public void init(Dpid dpid, OFDescStatsReply desc, OFVersion ofv) {
         this.dpid = dpid;
         this.desc = desc;
+        this.ofVersion = ofv;
     }
 
     //************************
@@ -102,7 +101,7 @@
     public final void sendMsg(OFMessage m) {
         if (role == RoleState.MASTER) {
             try {
-                this.write(m);
+                channel.write(Collections.singletonList(m));
             } catch (RejectedExecutionException e) {
                 log.warn(e.getMessage());
                 if (!e.getMessage().contains(SHUTDOWN_MSG)) {
@@ -116,7 +115,7 @@
     public final void sendMsg(List<OFMessage> msgs) {
         if (role == RoleState.MASTER) {
             try {
-                this.write(msgs);
+                channel.write(msgs);
             } catch (RejectedExecutionException e) {
                 log.warn(e.getMessage());
                 if (!e.getMessage().contains(SHUTDOWN_MSG)) {
@@ -127,10 +126,15 @@
     }
 
     @Override
-    public abstract void write(OFMessage msg);
-
-    @Override
-    public abstract void write(List<OFMessage> msgs);
+    public final void sendRoleRequest(OFMessage msg) {
+        if (msg instanceof OFRoleRequest ||
+                msg instanceof OFNiciraControllerRoleRequest) {
+            channel.write(Collections.singletonList(msg));
+            return;
+        }
+        throw new IllegalArgumentException("Someone is trying to send " +
+                                                   "a non role request message");
+    }
 
     @Override
     public final boolean isConnected() {
@@ -418,11 +422,20 @@
         return this.desc.getSerialNum();
     }
 
+
     @Override
     public boolean isOptical() {
         return false;
     }
 
 
+    @Override
+    public String toString() {
+        return this.getClass().getName() + " [" + ((channel != null)
+                ? channel.getRemoteAddress() : "?")
+                + " DPID[" + ((getStringId() != null) ? getStringId() : "?") + "]]";
+    }
+
+
 
 }
diff --git a/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/OpenFlowSwitchDriver.java b/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/OpenFlowSwitchDriver.java
index a83b608..365f525 100644
--- a/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/OpenFlowSwitchDriver.java
+++ b/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/OpenFlowSwitchDriver.java
@@ -15,9 +15,9 @@
  */
 package org.onosproject.openflow.controller.driver;
 
-import java.util.List;
-
 import org.jboss.netty.channel.Channel;
+import org.onosproject.net.driver.HandlerBehaviour;
+import org.onosproject.openflow.controller.Dpid;
 import org.onosproject.openflow.controller.OpenFlowSwitch;
 import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
 import org.projectfloodlight.openflow.protocol.OFErrorMsg;
@@ -26,12 +26,14 @@
 import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply;
 import org.projectfloodlight.openflow.protocol.OFVersion;
 
+import java.util.List;
+
 /**
  * Represents the driver side of an OpenFlow switch.
  * This interface should never be exposed to consumers.
  *
  */
-public interface OpenFlowSwitchDriver extends OpenFlowSwitch {
+public interface OpenFlowSwitchDriver extends OpenFlowSwitch, HandlerBehaviour {
 
     /**
      * Sets the OpenFlow agent to be used. This method
@@ -79,23 +81,6 @@
     public void handleRole(OFMessage m) throws SwitchStateException;
 
     /**
-     * Starts the driver specific handshake process.
-     */
-    public void startDriverHandshake();
-
-    /**
-     * Checks whether the driver specific handshake is complete.
-     * @return true is finished, false if not.
-     */
-    public boolean isDriverHandshakeComplete();
-
-    /**
-     * Process a message during the driver specific handshake.
-     * @param m the message to process.
-     */
-    public void processDriverHandshakeMessage(OFMessage m);
-
-    /**
      * Announce to the OpenFlow agent that this switch has connected.
      * @return true if successful, false if duplicate switch.
      */
@@ -162,12 +147,6 @@
 
 
     /**
-     * Does this switch support Nicira Role messages.
-     * @return true if supports, false otherwise.
-     */
-    public Boolean supportNxRole();
-
-    /**
      * Sets the OF version for this switch.
      * @param ofV the version to set.
      */
@@ -193,19 +172,42 @@
     public void setConnected(boolean connected);
 
     /**
-     * Writes the message to the output stream
-     * in a driver specific manner.
-     *
-     * @param msg the message to write
+     * Initialises the behaviour.
+     * @param dpid a dpid
+     * @param desc a switch description
+     * @param ofv OpenFlow version
      */
-    public void write(OFMessage msg);
+    void init(Dpid dpid, OFDescStatsReply desc, OFVersion ofv);
 
     /**
-     * Writes to the OFMessage list to the output stream
-     * in a driver specific manner.
-     *
-     * @param msgs the messages to be written
+     * Does this switch support Nicira Role messages.
+     * @return true if supports, false otherwise.
      */
-    public void write(List<OFMessage> msgs);
+    Boolean supportNxRole();
+
+
+    /**
+     * Starts the driver specific handshake process.
+     */
+    void startDriverHandshake();
+
+    /**
+     * Checks whether the driver specific handshake is complete.
+     * @return true is finished, false if not.
+     */
+    boolean isDriverHandshakeComplete();
+
+    /**
+     * Process a message during the driver specific handshake.
+     * @param m the message to process.
+     */
+    void processDriverHandshakeMessage(OFMessage m);
+
+    /**
+     * Sends only role request messages.
+     *
+     * @param message a role request message.
+     */
+    void sendRoleRequest(OFMessage message);
 
 }
diff --git a/openflow/ctl/pom.xml b/openflow/ctl/pom.xml
index fe4464d..bf89d1c 100644
--- a/openflow/ctl/pom.xml
+++ b/openflow/ctl/pom.xml
@@ -36,11 +36,6 @@
             <artifactId>onos-of-api</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.onosproject</groupId>
-            <artifactId>onos-of-drivers</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        <dependency>
             <groupId>io.netty</groupId>
             <artifactId>netty</artifactId>
         </dependency>
diff --git a/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/Controller.java b/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/Controller.java
index 2e20126..bf3a9ed 100644
--- a/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/Controller.java
+++ b/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/Controller.java
@@ -21,10 +21,13 @@
 import org.jboss.netty.channel.group.ChannelGroup;
 import org.jboss.netty.channel.group.DefaultChannelGroup;
 import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
+import org.onosproject.net.driver.DefaultDriverData;
+import org.onosproject.net.driver.DefaultDriverHandler;
+import org.onosproject.net.driver.Driver;
+import org.onosproject.net.driver.DriverService;
 import org.onosproject.openflow.controller.Dpid;
 import org.onosproject.openflow.controller.driver.OpenFlowAgent;
 import org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver;
-import org.onosproject.openflow.drivers.DriverManager;
 import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
 import org.projectfloodlight.openflow.protocol.OFFactories;
 import org.projectfloodlight.openflow.protocol.OFFactory;
@@ -70,6 +73,7 @@
 
     // Perf. related configuration
     protected static final int SEND_BUFFER_SIZE = 4 * 1024 * 1024;
+    private DriverService driverService;
 
     // ***************
     // Getters/Setters
@@ -152,15 +156,7 @@
         if (ofPort != null) {
             this.openFlowPort = Integer.parseInt(ofPort);
         }
-        String corsaDpid = configParams.get("corsaDpid");
-        if (corsaDpid != null) {
-            try {
-                DriverManager.setCorsaDpid(new Dpid(corsaDpid));
-                log.info("Corsa DPID set to {}", corsaDpid);
-            } catch (NumberFormatException e) {
-                log.warn("Malformed Corsa DPID string", e);
-            }
-        }
+
         log.debug("OpenFlow port set to {}", this.openFlowPort);
         String threads = configParams.get("workerthreads");
         this.workerThreads = threads != null ? Integer.parseInt(threads) : 16;
@@ -206,17 +202,28 @@
      * @return switch instance
      */
     protected OpenFlowSwitchDriver getOFSwitchInstance(long dpid,
-                                                       OFDescStatsReply desc, OFVersion ofv) {
-        OpenFlowSwitchDriver sw = DriverManager.getSwitch(new Dpid(dpid),
-                                                          desc, ofv);
-        sw.setAgent(agent);
-        sw.setRoleHandler(new RoleManager(sw));
-        return sw;
+                                                       OFDescStatsReply desc,
+                                                       OFVersion ofv) {
+        Driver driver = driverService
+                .getDriver(desc.getMfrDesc(), desc.getHwDesc(), desc.getSwDesc());
+
+        if (driver.hasBehaviour(OpenFlowSwitchDriver.class)) {
+            OpenFlowSwitchDriver ofSwitchDriver = driver.createBehaviour(new DefaultDriverHandler(
+                    new DefaultDriverData(driver)), OpenFlowSwitchDriver.class);
+            ofSwitchDriver.init(new Dpid(dpid), desc, ofv);
+            ofSwitchDriver.setAgent(agent);
+            ofSwitchDriver.setRoleHandler(new RoleManager(ofSwitchDriver));
+            return ofSwitchDriver;
+        }
+        log.error("No OpenFlow driver for {} : {}", dpid, desc);
+        return null;
+
     }
 
-    public void start(OpenFlowAgent ag) {
+    public void start(OpenFlowAgent ag, DriverService driverService) {
         log.info("Starting OpenFlow IO");
         this.agent = ag;
+        this.driverService = driverService;
         this.init();
         this.run();
     }
diff --git a/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImpl.java b/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImpl.java
index d140a71..b59ce18 100644
--- a/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImpl.java
+++ b/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImpl.java
@@ -23,7 +23,10 @@
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
 import org.apache.felix.scr.annotations.Modified;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.apache.felix.scr.annotations.Service;
+import org.onosproject.net.driver.DriverService;
 import org.onosproject.openflow.controller.DefaultOpenFlowPacketContext;
 import org.onosproject.openflow.controller.Dpid;
 import org.onosproject.openflow.controller.OpenFlowController;
@@ -76,6 +79,9 @@
     private static final Logger log =
             LoggerFactory.getLogger(OpenFlowControllerImpl.class);
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DriverService driverService;
+
     private final ExecutorService executorMsgs =
         Executors.newFixedThreadPool(32, groupedThreads("onos/of", "event-stats-%d"));
 
@@ -115,7 +121,7 @@
     public void activate(ComponentContext context) {
         Map<String, String> properties = readComponentConfiguration(context);
         ctrl.setConfigParams(properties);
-        ctrl.start(agent);
+        ctrl.start(agent, driverService);
     }
 
     @Deactivate
diff --git a/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/RoleManager.java b/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/RoleManager.java
index eac39c3..2d7e2e7 100644
--- a/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/RoleManager.java
+++ b/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/RoleManager.java
@@ -15,10 +15,8 @@
  */
 package org.onosproject.openflow.controller.impl;
 
-import java.io.IOException;
-import java.util.Collections;
-import java.util.concurrent.TimeUnit;
-
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
 import org.onosproject.openflow.controller.RoleState;
 import org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver;
 import org.onosproject.openflow.controller.driver.RoleHandler;
@@ -30,7 +28,6 @@
 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;
@@ -42,8 +39,8 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.cache.Cache;
-import com.google.common.cache.CacheBuilder;
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
 
 
 /**
@@ -103,7 +100,7 @@
                 .setXid(xid)
                 .setRole(roleToSend)
                 .build();
-        sw.write(Collections.<OFMessage>singletonList(roleRequest));
+        sw.sendRoleRequest(roleRequest);
         return xid;
     }
 
@@ -133,7 +130,8 @@
                 //FIXME fix below when we actually use generation ids
                 .setGenerationId(U64.ZERO)
                 .build();
-        sw.write(rrm);
+
+        sw.sendRoleRequest(rrm);
         return xid;
     }
 
diff --git a/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/RoleManagerTest.java b/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/RoleManagerTest.java
index fb0e406..06929d2 100644
--- a/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/RoleManagerTest.java
+++ b/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/RoleManagerTest.java
@@ -15,15 +15,14 @@
  */
 package org.onosproject.openflow.controller.impl;
 
-import java.io.IOException;
-import java.util.List;
-
 import org.jboss.netty.channel.Channel;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.onosproject.net.driver.DriverData;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.openflow.controller.Dpid;
 import org.onosproject.openflow.controller.RoleState;
-import org.onosproject.openflow.controller.OpenFlowSwitch.TableType;
 import org.onosproject.openflow.controller.driver.OpenFlowAgent;
 import org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver;
 import org.onosproject.openflow.controller.driver.RoleHandler;
@@ -39,12 +38,16 @@
 import org.projectfloodlight.openflow.protocol.OFPortDesc;
 import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply;
 import org.projectfloodlight.openflow.protocol.OFVersion;
-import org.projectfloodlight.openflow.types.TableId;
 import org.projectfloodlight.openflow.types.U64;
 
+import java.io.IOException;
+import java.util.List;
+
 import static org.junit.Assert.assertEquals;
-import static org.onosproject.openflow.controller.RoleState.*;
-import static org.onosproject.openflow.controller.driver.RoleRecvStatus.*;
+import static org.onosproject.openflow.controller.RoleState.MASTER;
+import static org.onosproject.openflow.controller.RoleState.SLAVE;
+import static org.onosproject.openflow.controller.driver.RoleRecvStatus.MATCHED_CURRENT_ROLE;
+import static org.onosproject.openflow.controller.driver.RoleRecvStatus.OTHER_EXPECTATION;
 
 public class RoleManagerTest {
 
@@ -112,9 +115,6 @@
         public void sendMsg(List<OFMessage> msgs) {
         }
 
-        @Override
-        public void transformAndSendMsg(OFMessage msg, TableType tableType) {
-        }
 
         @Override
         public void handleMessage(OFMessage fromSwitch) {
@@ -224,6 +224,11 @@
         }
 
         @Override
+        public void sendRoleRequest(OFMessage message) {
+
+        }
+
+        @Override
         public boolean connectSwitch() {
             return false;
         }
@@ -293,19 +298,16 @@
         }
 
         @Override
+        public void init(Dpid dpid, OFDescStatsReply desc, OFVersion ofv) {
+
+        }
+
+        @Override
         public boolean isConnected() {
             return false;
         }
 
         @Override
-        public void write(OFMessage msg) {
-        }
-
-        @Override
-        public void write(List<OFMessage> msgs) {
-        }
-
-        @Override
         public void returnRoleReply(RoleState requested, RoleState response) {
             failed = requested;
         }
@@ -316,9 +318,23 @@
         }
 
         @Override
-        public TableType getTableType(TableId tid) {
-            return TableType.NONE;
+        public DriverHandler handler() {
+            return null;
         }
 
+        @Override
+        public void setHandler(DriverHandler handler) {
+
+        }
+
+        @Override
+        public DriverData data() {
+            return null;
+        }
+
+        @Override
+        public void setData(DriverData data) {
+
+        }
     }
 }
diff --git a/openflow/drivers/pom.xml b/openflow/drivers/pom.xml
deleted file mode 100644
index ec15e75..0000000
--- a/openflow/drivers/pom.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<!--
-  ~ Copyright 2014 Open Networking Laboratory
-  ~
-  ~ 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.
-  -->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.onosproject</groupId>
-        <artifactId>onos-of</artifactId>
-        <version>1.2.0-SNAPSHOT</version>
-        <relativePath>../pom.xml</relativePath>
-    </parent>
-
-    <artifactId>onos-of-drivers</artifactId>
-    <packaging>bundle</packaging>
-
-    <description>ONOS OpenFlow switch drivers &amp; factory</description>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.onosproject</groupId>
-            <artifactId>onos-of-api</artifactId>
-        </dependency>
-    </dependencies>
-</project>
diff --git a/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/DriverManager.java b/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/DriverManager.java
deleted file mode 100644
index 1560d44..0000000
--- a/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/DriverManager.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * 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.onosproject.openflow.drivers;
-
-
-import org.onosproject.openflow.controller.Dpid;
-import org.onosproject.openflow.controller.RoleState;
-import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch;
-import org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver;
-import org.onosproject.openflow.controller.driver.OpenFlowSwitchDriverFactory;
-import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
-import org.projectfloodlight.openflow.protocol.OFFlowAdd;
-import org.projectfloodlight.openflow.protocol.OFMessage;
-import org.projectfloodlight.openflow.protocol.OFPortDesc;
-import org.projectfloodlight.openflow.protocol.OFVersion;
-import org.projectfloodlight.openflow.types.TableId;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.stream.Collectors;
-
-/**
- * A simple implementation of a driver manager that differentiates between
- * connected switches using the OF Description Statistics Reply message.
- */
-public final class DriverManager implements OpenFlowSwitchDriverFactory {
-
-    private static final Logger log = LoggerFactory.getLogger(DriverManager.class);
-
-    private static final int LOWEST_PRIORITY = 0;
-
-    private static Dpid corsaDpid = new Dpid();
-
-    /**
-     * Return an IOFSwitch object based on switch's manufacturer description
-     * from OFDescStatsReply.
-     *
-     * @param desc DescriptionStatistics reply from the switch
-     * @return A IOFSwitch instance if the driver found an implementation for
-     *         the given description. Otherwise it returns OFSwitchImplBase
-     */
-    @Override
-    public OpenFlowSwitchDriver getOFSwitchImpl(Dpid dpid,
-            OFDescStatsReply desc, OFVersion ofv) {
-        String vendor = desc.getMfrDesc();
-        String hw = desc.getHwDesc();
-        String sw = desc.getSwDesc();
-
-        if (dpid.equals(corsaDpid)) {
-            if (hw.startsWith("Open vSwitch")) {
-                return new OFOVSSwitchCorsaTTP(dpid, desc);
-            } else {
-                return new OFCorsaSwitchDriver(dpid, desc);
-            }
-        }
-
-        if (vendor.startsWith("Stanford University, Ericsson Research and CPqD Research")
-                &&
-                hw.startsWith("OpenFlow 1.3 Reference Userspace Switch")) {
-            return new OFSwitchImplSpringOpenTTP(dpid, desc);
-        }
-
-        //TODO: Temporary work around until the configuration based
-        // driver manager framework is ready
-        if (vendor.contains("Dell")
-                &&
-                hw.contains("OpenFlow switch HW ver. 1.0")) {
-            return new OFSwitchImplSpringOpenTTPDellOSR(dpid, desc);
-        }
-
-        if (hw.startsWith("Open vSwitch")) {
-            if (ofv == OFVersion.OF_10) {
-                return new OFSwitchImplOVS10(dpid, desc);
-            } else if (ofv == OFVersion.OF_13) {
-                return new OFSwitchImplOVS13(dpid, desc);
-            }
-        }
-
-        if (vendor.equals("Pica8, Inc.") && sw.startsWith("PicOS") &&
-                ofv == OFVersion.OF_13) {
-            return new OFSwitchImplOVS13(dpid, desc);
-        }
-
-
-        if (sw.startsWith("LINC-OE")) {
-            log.warn("Optical Emulator LINC-OE with DPID:{} found..", dpid);
-            return new OFOpticalSwitchImplLINC13(dpid, desc);
-        }
-
-        if (vendor.startsWith("Corsa") && hw.startsWith("Corsa Element")
-                && sw.startsWith("2.3.1")) {
-            log.warn("Corsa Switch 2.3.1 found");
-            return new OFCorsaSwitchDriver(dpid, desc);
-        }
-
-        log.warn("DriverManager could not identify switch desc: {}. "
-                         + "Assigning AbstractOpenFlowSwich", desc);
-        return new AbstractOpenFlowSwitch(dpid, desc) {
-
-            @Override
-            public void setRole(RoleState state) {
-                this.role = RoleState.MASTER;
-            }
-
-            @Override
-            public void write(List<OFMessage> msgs) {
-                channel.write(msgs);
-            }
-
-            @Override
-            public void write(OFMessage msg) {
-                channel.write(Collections.singletonList(msg));
-
-            }
-
-            @Override
-            public Boolean supportNxRole() {
-                return false;
-            }
-
-            @Override
-            public void startDriverHandshake() {
-                if (factory().getVersion() == OFVersion.OF_10) {
-                    OFFlowAdd.Builder fmBuilder = factory().buildFlowAdd();
-                    fmBuilder.setPriority(LOWEST_PRIORITY);
-                    write(fmBuilder.build());
-                }
-            }
-
-            @Override
-            public void processDriverHandshakeMessage(OFMessage m) {}
-
-            @Override
-            public boolean isDriverHandshakeComplete() {
-                return true;
-            }
-
-            @Override
-            public List<OFPortDesc> getPorts() {
-                if (this.factory().getVersion() == OFVersion.OF_10) {
-                    return Collections.unmodifiableList(features.getPorts());
-                } else {
-                    return Collections.unmodifiableList(this.ports.stream()
-                                                        .flatMap((portReply) -> (portReply.getEntries().stream()))
-                                                        .collect(Collectors.toList()));
-                }
-            }
-
-            @Override
-            public TableType getTableType(TableId tid) {
-                return TableType.NONE;
-            }
-
-            @Override
-            public void transformAndSendMsg(OFMessage msg, TableType tableType) {
-                // TODO Auto-generated method stub
-
-            }
-        };
-    }
-
-    /**
-     * Private constructor to avoid instantiation.
-     */
-    private DriverManager() {
-    }
-
-    public static OpenFlowSwitchDriver getSwitch(Dpid dpid,
-            OFDescStatsReply desc, OFVersion ofv) {
-        return new DriverManager().getOFSwitchImpl(dpid, desc, ofv);
-    }
-
-    public static void setCorsaDpid(Dpid dpid) {
-        corsaDpid = dpid;
-    }
-
-}
diff --git a/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFCorsaSwitchDriver.java b/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFCorsaSwitchDriver.java
deleted file mode 100644
index 5fe41dd..0000000
--- a/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFCorsaSwitchDriver.java
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * 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.onosproject.openflow.drivers;
-
-import com.google.common.collect.Lists;
-import org.onlab.packet.Ethernet;
-import org.onosproject.openflow.controller.Dpid;
-import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch;
-import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeAlreadyStarted;
-import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeCompleted;
-import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeNotStarted;
-import org.projectfloodlight.openflow.protocol.OFBarrierRequest;
-import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
-import org.projectfloodlight.openflow.protocol.OFFlowMod;
-import org.projectfloodlight.openflow.protocol.OFMatchV3;
-import org.projectfloodlight.openflow.protocol.OFMessage;
-import org.projectfloodlight.openflow.protocol.OFType;
-import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
-import org.projectfloodlight.openflow.protocol.instruction.OFInstructionGotoTable;
-import org.projectfloodlight.openflow.protocol.match.Match;
-import org.projectfloodlight.openflow.protocol.match.MatchField;
-import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
-import org.projectfloodlight.openflow.types.EthType;
-import org.projectfloodlight.openflow.types.OFGroup;
-import org.projectfloodlight.openflow.types.OFVlanVidMatch;
-import org.projectfloodlight.openflow.types.TableId;
-
-//import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * Corsa switch driver for BGP Router deployment.
- */
-public class OFCorsaSwitchDriver extends AbstractOpenFlowSwitch {
-
-    protected static final int FIRST_TABLE = 0;
-    protected static final int VLAN_MPLS_TABLE = 1;
-    protected static final int VLAN_TABLE = 2;
-    protected static final int MPLS_TABLE = 3;
-    protected static final int ETHER_TABLE = 4;
-    protected static final int COS_MAP_TABLE = 5;
-    protected static final int FIB_TABLE = 6;
-    protected static final int LOCAL_TABLE = 9;
-
-
-    private AtomicBoolean handShakeComplete = new AtomicBoolean(false);
-
-    private int barrierXid;
-
-    OFCorsaSwitchDriver(Dpid dpid, OFDescStatsReply desc) {
-        super(dpid);
-
-        setSwitchDescription(desc);
-    }
-
-    /**
-     * Used by the default sendMsg to 'write' to the switch.
-     * This method is indirectly used by generic onos services like proxyarp
-     * to request packets from the default flow table. In a multi-table
-     * pipeline, these requests are redirected to the correct table.
-     *
-     * For the Corsa switch, the equivalent table is the LOCAL TABLE
-     *
-     */
-    @Override
-    public void write(OFMessage msg) {
-/*        if (msg.getType() == OFType.FLOW_MOD) {
-            OFFlowMod flowMod = (OFFlowMod) msg;
-            OFFlowMod.Builder builder = flowMod.createBuilder();
-            builder.setTableId(TableId.of(LOCAL_TABLE));
-            channel.write(Collections.singletonList(builder.build()));
-        } else {
-            channel.write(Collections.singletonList(msg));
-        }
-*/
-        channel.write(Collections.singletonList(msg));
-    }
-
-    @Override
-    public void write(List<OFMessage> msgs) {
-/*        List<OFMessage> newMsgs = new ArrayList<OFMessage>();
-        for (OFMessage msg : msgs) {
-            if (msg.getType() == OFType.FLOW_MOD) {
-                OFFlowMod flowMod = (OFFlowMod) msg;
-                OFFlowMod.Builder builder = flowMod.createBuilder();
-                builder.setTableId(TableId.of(LOCAL_TABLE));
-                newMsgs.add(builder.build());
-            } else {
-                newMsgs.add(msg);
-            }
-        }
-        channel.write(newMsgs);
-*/
-        channel.write(msgs);
-    }
-
-    @Override
-    public void transformAndSendMsg(OFMessage msg, TableType type) {
-        log.trace("Trying to send {} of TableType {}", msg, type);
-        if (msg.getType() == OFType.FLOW_MOD) {
-            OFFlowMod flowMod = (OFFlowMod) msg;
-            OFFlowMod.Builder builder = flowMod.createBuilder();
-            List<OFInstruction> instructions = flowMod.getInstructions();
-            List<OFInstruction> newInstructions = Lists.newArrayList();
-            for (OFInstruction i : instructions) {
-                if (i instanceof OFInstructionGotoTable) {
-                    OFInstructionGotoTable gotoTable = (OFInstructionGotoTable) i;
-                    TableType tid = TableType.values()[gotoTable.getTableId().getValue()];
-                    switch (tid) {
-                        case VLAN_MPLS:
-                            newInstructions.add(
-                                    gotoTable.createBuilder()
-                                            .setTableId(TableId.of(VLAN_MPLS_TABLE)).build());
-                            break;
-                        case VLAN:
-                            newInstructions.add(
-                                    gotoTable.createBuilder()
-                                            .setTableId(TableId.of(VLAN_TABLE)).build());
-                            break;
-                        case ETHER:
-                            newInstructions.add(
-                                    gotoTable.createBuilder()
-                                            .setTableId(TableId.of(ETHER_TABLE)).build());
-                            break;
-                        case COS:
-                            newInstructions.add(
-                                    gotoTable.createBuilder()
-                                            .setTableId(TableId.of(COS_MAP_TABLE)).build());
-                            break;
-                        case IP:
-                            newInstructions.add(
-                                    gotoTable.createBuilder()
-                                            .setTableId(TableId.of(FIB_TABLE)).build());
-                            break;
-                        case MPLS:
-                            newInstructions.add(
-                                    gotoTable.createBuilder()
-                                            .setTableId(TableId.of(MPLS_TABLE)).build());
-                            break;
-                        case ACL:
-                            newInstructions.add(
-                                    gotoTable.createBuilder()
-                                            .setTableId(TableId.of(LOCAL_TABLE)).build());
-                            break;
-                        case NONE:
-                            log.error("Should never have to go to Table 0");
-                            /*newInstructions.add(
-                                    gotoTable.createBuilder()
-                                            .setTableId(TableId.of(0)).build());
-                            */
-                            break;
-                        default:
-                            log.warn("Unknown table type: {}", tid);
-                    }
-
-                } else {
-                    newInstructions.add(i);
-                }
-            }
-            switch (type) {
-                case VLAN_MPLS:
-                    builder.setTableId(TableId.of(VLAN_MPLS_TABLE));
-                    break;
-                case VLAN:
-                    builder.setTableId(TableId.of(VLAN_TABLE));
-                    break;
-                case ETHER:
-                    builder.setTableId(TableId.of(ETHER_TABLE));
-                    break;
-                case COS:
-                    builder.setTableId(TableId.of(COS_MAP_TABLE));
-                    break;
-                case IP:
-                    builder.setTableId(TableId.of(FIB_TABLE));
-                    break;
-                case MPLS:
-                    builder.setTableId(TableId.of(MPLS_TABLE));
-                    break;
-                case ACL:
-                    builder.setTableId(TableId.of(LOCAL_TABLE));
-                    break;
-                case FIRST:
-                    builder.setTableId(TableId.of(FIRST_TABLE));
-                    break;
-                case NONE:
-                    builder.setTableId(TableId.of(LOCAL_TABLE));
-                    break;
-                default:
-                    log.warn("Unknown table type: {}", type);
-            }
-            builder.setInstructions(newInstructions);
-
-            OFMatchV3 match = (OFMatchV3) flowMod.getMatch();
-            for (OFOxm oxm: match.getOxmList()) {
-                if (oxm.getMatchField() == MatchField.VLAN_VID &&
-                        oxm.getValue().equals(OFVlanVidMatch.PRESENT)) {
-                        Match.Builder mBuilder = factory().buildMatchV3();
-                        mBuilder.setExact(MatchField.ETH_TYPE, EthType.of(Ethernet.TYPE_VLAN));
-                        builder.setMatch(mBuilder.build());
-                }
-            }
-
-            OFMessage msgnew = builder.build();
-            channel.write(Collections.singletonList(msgnew));
-            log.debug("Installed {}", msgnew);
-
-        } else {
-            channel.write(Collections.singletonList(msg));
-        }
-    }
-
-    @Override
-    public TableType getTableType(TableId tid) {
-        switch (tid.getValue()) {
-        case VLAN_MPLS_TABLE:
-            return TableType.VLAN_MPLS;
-        case VLAN_TABLE:
-            return TableType.VLAN;
-        case ETHER_TABLE:
-            return TableType.ETHER;
-        case COS_MAP_TABLE:
-            return TableType.COS;
-        case FIB_TABLE:
-            return TableType.IP;
-        case MPLS_TABLE:
-            return TableType.MPLS;
-        case LOCAL_TABLE:
-            return TableType.NONE;
-        case FIRST_TABLE:
-            return TableType.FIRST;
-        default:
-            log.warn("Unknown table type: {}", tid.getValue());
-            return TableType.NONE;
-        }
-    }
-
-    @Override
-    public Boolean supportNxRole() {
-        return false;
-    }
-
-    @Override
-    public void startDriverHandshake() {
-        if (startDriverHandshakeCalled) {
-            throw new SwitchDriverSubHandshakeAlreadyStarted();
-        }
-        startDriverHandshakeCalled = true;
-        OFFlowMod fm = factory().buildFlowDelete()
-                .setTableId(TableId.ALL)
-                .setOutGroup(OFGroup.ANY)
-                .build();
-
-        channel.write(Collections.singletonList(fm));
-
-        barrierXid = getNextTransactionId();
-        OFBarrierRequest barrier = factory().buildBarrierRequest()
-                .setXid(barrierXid).build();
-
-
-        channel.write(Collections.singletonList(barrier));
-
-    }
-
-    @Override
-    public boolean isDriverHandshakeComplete() {
-        if (!startDriverHandshakeCalled) {
-            throw new SwitchDriverSubHandshakeAlreadyStarted();
-        }
-        return handShakeComplete.get();
-    }
-
-    @Override
-    public void processDriverHandshakeMessage(OFMessage m) {
-        if (!startDriverHandshakeCalled) {
-            throw new SwitchDriverSubHandshakeNotStarted();
-        }
-        if (handShakeComplete.get()) {
-            throw new SwitchDriverSubHandshakeCompleted(m);
-        }
-        if (m.getType() == OFType.BARRIER_REPLY &&
-                m.getXid() == barrierXid) {
-            handShakeComplete.set(true);
-        }
-    }
-}
diff --git a/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFOVSSwitchCorsaTTP.java b/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFOVSSwitchCorsaTTP.java
deleted file mode 100644
index 9e85def..0000000
--- a/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFOVSSwitchCorsaTTP.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * 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.onosproject.openflow.drivers;
-
-import org.onosproject.openflow.controller.Dpid;
-import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
-import org.projectfloodlight.openflow.protocol.OFMessage;
-/*import com.google.common.collect.Lists;
-import org.projectfloodlight.openflow.protocol.OFFlowMod;
-import org.projectfloodlight.openflow.protocol.OFType;
-import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
-import org.projectfloodlight.openflow.protocol.instruction.OFInstructionGotoTable;
-import org.projectfloodlight.openflow.types.TableId;
-import java.util.List;
-*/
-import java.util.Collections;
-
-public class OFOVSSwitchCorsaTTP extends OFCorsaSwitchDriver {
-
-    OFOVSSwitchCorsaTTP(Dpid dpid, OFDescStatsReply desc) {
-        super(dpid, desc);
-    }
-
-    @Override
-    public void transformAndSendMsg(OFMessage msg, TableType type) {
-        /*log.trace("Trying to send {} of TableType {}", msg, type);
-        if (msg.getType() == OFType.FLOW_MOD) {
-            OFFlowMod flowMod = (OFFlowMod) msg;
-            OFFlowMod.Builder builder = flowMod.createBuilder();
-            List<OFInstruction> instructions = flowMod.getInstructions();
-            List<OFInstruction> newInstructions = Lists.newArrayList();
-            for (OFInstruction i : instructions) {
-                if (i instanceof OFInstructionGotoTable) {
-                    OFInstructionGotoTable gotoTable = (OFInstructionGotoTable) i;
-                    TableType tid = TableType.values()[gotoTable.getTableId().getValue()];
-                    switch (tid) {
-                        case VLAN_MPLS:
-                            newInstructions.add(
-                                    gotoTable.createBuilder()
-                                            .setTableId(TableId.of(VLAN_MPLS_TABLE)).build());
-                            break;
-                        case VLAN:
-                            newInstructions.add(
-                                    gotoTable.createBuilder()
-                                            .setTableId(TableId.of(VLAN_TABLE)).build());
-                            break;
-                        case ETHER:
-                            newInstructions.add(
-                                    gotoTable.createBuilder()
-                                            .setTableId(TableId.of(ETHER_TABLE)).build());
-                            break;
-                        case COS:
-                            newInstructions.add(
-                                    gotoTable.createBuilder()
-                                            .setTableId(TableId.of(COS_MAP_TABLE)).build());
-                            break;
-                        case IP:
-                            newInstructions.add(
-                                    gotoTable.createBuilder()
-                                            .setTableId(TableId.of(FIB_TABLE)).build());
-                            break;
-                        case MPLS:
-                            newInstructions.add(
-                                    gotoTable.createBuilder()
-                                            .setTableId(TableId.of(MPLS_TABLE)).build());
-                            break;
-                        case ACL:
-                            newInstructions.add(
-                                    gotoTable.createBuilder()
-                                            .setTableId(TableId.of(LOCAL_TABLE)).build());
-                            break;
-                        case NONE:
-                            log.error("Should never have to go to Table 0");
-                            newInstructions.add(
-                                    gotoTable.createBuilder()
-                                            .setTableId(TableId.of(0)).build());
-
-                            break;
-                        default:
-                            log.warn("Unknown table type: {}", tid);
-                    }
-                } else {
-                    newInstructions.add(i);
-                }
-            }
-            switch (type) {
-                case VLAN_MPLS:
-                    builder.setTableId(TableId.of(VLAN_MPLS_TABLE));
-                    break;
-                case VLAN:
-                    builder.setTableId(TableId.of(VLAN_TABLE));
-                    break;
-                case ETHER:
-                    builder.setTableId(TableId.of(ETHER_TABLE));
-                    break;
-                case COS:
-                    builder.setTableId(TableId.of(COS_MAP_TABLE));
-                    break;
-                case IP:
-                    builder.setTableId(TableId.of(FIB_TABLE));
-                    break;
-                case MPLS:
-                    builder.setTableId(TableId.of(MPLS_TABLE));
-                    break;
-                case ACL:
-                    builder.setTableId(TableId.of(LOCAL_TABLE));
-                    break;
-                case FIRST:
-                    builder.setTableId(TableId.of(FIRST_TABLE));
-                    break;
-                case NONE:
-                    builder.setTableId(TableId.of(LOCAL_TABLE));
-                    break;
-                default:
-                    log.warn("Unknown table type: {}", type);
-            }
-            builder.setInstructions(newInstructions);
-            OFMessage msgnew = builder.build();
-            channel.write(Collections.singletonList(msgnew));
-            log.debug("Installed {}", msgnew);
-
-        } else {
-            channel.write(Collections.singletonList(msg));
-        }*/
-        channel.write(Collections.singletonList(msg));
-    }
-}
diff --git a/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFOpticalSwitchImplLINC13.java b/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFOpticalSwitchImplLINC13.java
deleted file mode 100644
index 37022a1..0000000
--- a/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFOpticalSwitchImplLINC13.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * 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.onosproject.openflow.drivers;
-
-import org.onosproject.openflow.controller.Dpid;
-import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch;
-import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeAlreadyStarted;
-import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeCompleted;
-import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeNotStarted;
-import org.projectfloodlight.openflow.protocol.OFCircuitPortStatus;
-import org.projectfloodlight.openflow.protocol.OFCircuitPortsReply;
-import org.projectfloodlight.openflow.protocol.OFCircuitPortsRequest;
-import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
-import org.projectfloodlight.openflow.protocol.OFMessage;
-import org.projectfloodlight.openflow.protocol.OFPortDesc;
-import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply;
-import org.projectfloodlight.openflow.protocol.OFPortOptical;
-import org.projectfloodlight.openflow.protocol.OFStatsReply;
-import org.projectfloodlight.openflow.protocol.OFStatsType;
-import org.projectfloodlight.openflow.types.TableId;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * LINC-OE Optical Emulator switch class.
- */
-public class OFOpticalSwitchImplLINC13 extends AbstractOpenFlowSwitch {
-
-    private final AtomicBoolean driverHandshakeComplete;
-    private long barrierXidToWaitFor = -1;
-
-    private OFPortDescStatsReply wPorts;
-
-    OFOpticalSwitchImplLINC13(Dpid dpid, OFDescStatsReply desc) {
-        super(dpid);
-        driverHandshakeComplete = new AtomicBoolean(false);
-        setSwitchDescription(desc);
-    }
-
-    @Override
-    public String toString() {
-        return "OFOpticalSwitchImplLINC13 [" + ((channel != null)
-                ? channel.getRemoteAddress() : "?")
-                + " DPID[" + ((getStringId() != null) ? getStringId() : "?") + "]]";
-    }
-
-    @Override
-    public void startDriverHandshake() {
-        log.warn("Starting driver handshake for sw {}", getStringId());
-        if (startDriverHandshakeCalled) {
-            throw new SwitchDriverSubHandshakeAlreadyStarted();
-        }
-        startDriverHandshakeCalled = true;
-        try {
-            sendHandshakeOFExperimenterPortDescRequest();
-        } catch (IOException e) {
-            log.error("LINC-OE exception while sending experimenter port desc:",
-                     e.getMessage());
-            e.printStackTrace();
-        }
-    }
-
-    @Override
-    public boolean isDriverHandshakeComplete() {
-        if (!startDriverHandshakeCalled) {
-            throw new SwitchDriverSubHandshakeNotStarted();
-        }
-        return driverHandshakeComplete.get();
-    }
-
-    @Override
-    public void processDriverHandshakeMessage(OFMessage m) {
-        if (!startDriverHandshakeCalled) {
-            throw new SwitchDriverSubHandshakeNotStarted();
-        }
-        if (driverHandshakeComplete.get()) {
-            throw new SwitchDriverSubHandshakeCompleted(m);
-        }
-
-        switch (m.getType()) {
-            case BARRIER_REPLY:
-                if (m.getXid() == barrierXidToWaitFor) {
-                    log.debug("LINC-OE Received barrier response");
-                }
-                break;
-            case ERROR:
-                log.error("Switch {} Error {}", getStringId(), m);
-                break;
-            case FEATURES_REPLY:
-                break;
-            case FLOW_REMOVED:
-                break;
-            case GET_ASYNC_REPLY:
-                break;
-            case PACKET_IN:
-                break;
-            case PORT_STATUS:
-                log.warn("****LINC-OE Port Status {} {}", getStringId(), m);
-                processOFPortStatus((OFCircuitPortStatus) m);
-                break;
-            case QUEUE_GET_CONFIG_REPLY:
-                break;
-            case ROLE_REPLY:
-                break;
-            case STATS_REPLY:
-                OFStatsReply stats = (OFStatsReply) m;
-                if (stats.getStatsType() == OFStatsType.EXPERIMENTER) {
-                    log.warn("LINC-OE : Received stats reply message {}", m);
-                    processHandshakeOFExperimenterPortDescRequest(
-                            (OFCircuitPortsReply) m);
-                    driverHandshakeComplete.set(true);
-                }
-                break;
-            default:
-                log.warn("Received message {} during switch-driver " +
-                                 "subhandshake " + "from switch {} ... " +
-                                 "Ignoring message", m,
-                         getStringId());
-
-        }
-    }
-
-    public void processOFPortStatus(OFCircuitPortStatus ps) {
-        log.debug("LINC-OE ..OF Port Status :", ps);
-
-    }
-
-    private void processHandshakeOFExperimenterPortDescRequest(
-            OFCircuitPortsReply sr) {
-        Collection<OFPortOptical> entries = sr.getEntries();
-        List<OFPortDesc> ofPortDescList = new ArrayList<>(entries.size());
-        for (OFPortOptical entry : entries) {
-            log.warn("LINC:OE port message {}", entry.toString());
-            ofPortDescList.add(factory().buildPortDesc().
-                    setPortNo(entry.getPortNo())
-                                           .setConfig(entry.getConfig())
-                                           .setState(entry.getState())
-                                           .setHwAddr(entry.getHwAddr())
-                                           .setName(entry.getName())
-                                           .build());
-
-        }
-        setExperimenterPortDescReply(factory().buildPortDescStatsReply().
-                setEntries(ofPortDescList).build());
-    }
-
-    private void setExperimenterPortDescReply(OFPortDescStatsReply reply) {
-        wPorts = reply;
-    }
-
-
-    private void sendHandshakeOFExperimenterPortDescRequest() throws
-            IOException {
-        // send multi part message for port description for optical switches
-        OFCircuitPortsRequest circuitPortsRequest = factory()
-                .buildCircuitPortsRequest().setXid(getNextTransactionId())
-                .build();
-        log.warn("LINC-OE : Sending experimented circuit port stats " +
-                         "message " +
-                         "{}",
-                 circuitPortsRequest.toString());
-        this.write(Collections.<OFMessage>singletonList(circuitPortsRequest));
-    }
-
-    @Override
-    public List<OFPortDesc> getPorts() {
-        List<OFPortDesc> portEntries = new ArrayList<>();
-        portEntries.addAll(super.getPorts());
-        if (wPorts != null) {
-            portEntries.addAll(wPorts.getEntries());
-        }
-        return Collections.unmodifiableList(portEntries);
-    }
-
-    @Override
-    public void write(OFMessage msg) {
-        this.channel.write(Collections.singletonList(msg));
-    }
-
-    @Override
-    public void write(List<OFMessage> msgs) {
-        this.channel.write(msgs);
-    }
-
-    @Override
-    public Boolean supportNxRole() {
-        return false;
-    }
-
-    @Override
-    public boolean isOptical() {
-        return true;
-    }
-
-    @Override
-    public TableType getTableType(TableId tid) {
-        return TableType.NONE;
-    }
-
-    @Override
-    public void transformAndSendMsg(OFMessage msg, TableType tableType) {
-        // TODO Auto-generated method stub
-
-    }
-
-}
diff --git a/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFSwitchImplCPqD13.java b/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFSwitchImplCPqD13.java
deleted file mode 100644
index 75be9d2..0000000
--- a/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFSwitchImplCPqD13.java
+++ /dev/null
@@ -1,1231 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * 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.onosproject.openflow.drivers;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.onosproject.openflow.controller.Dpid;
-import org.onosproject.openflow.controller.RoleState;
-import org.onosproject.openflow.controller.OpenFlowSwitch.TableType;
-import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch;
-import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeAlreadyStarted;
-import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeCompleted;
-import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeNotStarted;
-import org.projectfloodlight.openflow.protocol.OFAsyncGetReply;
-import org.projectfloodlight.openflow.protocol.OFBarrierRequest;
-import org.projectfloodlight.openflow.protocol.OFBucket;
-import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
-import org.projectfloodlight.openflow.protocol.OFFactory;
-import org.projectfloodlight.openflow.protocol.OFGroupDescStatsReply;
-import org.projectfloodlight.openflow.protocol.OFGroupFeaturesStatsReply;
-import org.projectfloodlight.openflow.protocol.OFGroupType;
-import org.projectfloodlight.openflow.protocol.OFMatchV3;
-import org.projectfloodlight.openflow.protocol.OFMessage;
-import org.projectfloodlight.openflow.protocol.OFOxmList;
-import org.projectfloodlight.openflow.protocol.OFPortDesc;
-import org.projectfloodlight.openflow.protocol.OFStatsReply;
-import org.projectfloodlight.openflow.protocol.action.OFAction;
-import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
-import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthDst;
-import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthSrc;
-import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthType;
-import org.projectfloodlight.openflow.protocol.oxm.OFOxmInPort;
-import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv4DstMasked;
-import org.projectfloodlight.openflow.protocol.oxm.OFOxmMetadataMasked;
-import org.projectfloodlight.openflow.protocol.oxm.OFOxmMplsLabel;
-import org.projectfloodlight.openflow.protocol.oxm.OFOxmVlanVid;
-import org.projectfloodlight.openflow.types.EthType;
-import org.projectfloodlight.openflow.types.IPv4Address;
-import org.projectfloodlight.openflow.types.MacAddress;
-import org.projectfloodlight.openflow.types.OFBufferId;
-import org.projectfloodlight.openflow.types.OFGroup;
-import org.projectfloodlight.openflow.types.OFMetadata;
-import org.projectfloodlight.openflow.types.OFPort;
-import org.projectfloodlight.openflow.types.OFVlanVidMatch;
-import org.projectfloodlight.openflow.types.TableId;
-import org.projectfloodlight.openflow.types.U32;
-import org.projectfloodlight.openflow.types.U64;
-import org.projectfloodlight.openflow.util.HexString;
-
-/**
- * OFDescriptionStatistics Vendor (Manufacturer Desc.): Stanford University,
- * Ericsson Research and CPqD Research. Make (Hardware Desc.) : OpenFlow 1.3
- * Reference Userspace Switch Model (Datapath Desc.) : None Software : Serial :
- * None
- */
-public class OFSwitchImplCPqD13 extends AbstractOpenFlowSwitch {
-
-    private static final int VLAN_ID_OFFSET = 16;
-    private final AtomicBoolean driverHandshakeComplete;
-    private OFFactory factory;
-    private static final int OFPCML_NO_BUFFER = 0xffff;
-    // Configuration of asynch messages to controller. We need different
-    // asynch messages depending on role-equal or role-master.
-    // We don't want to get anything if we are slave.
-    private static final long SET_FLOW_REMOVED_MASK_MASTER = 0xf;
-    private static final long SET_PACKET_IN_MASK_MASTER = 0x7;
-    private static final long SET_PORT_STATUS_MASK_MASTER = 0x7;
-    private static final long SET_FLOW_REMOVED_MASK_EQUAL = 0x0;
-    private static final long SET_PACKET_IN_MASK_EQUAL = 0x0;
-    private static final long SET_PORT_STATUS_MASK_EQUAL = 0x7;
-    private static final long SET_ALL_SLAVE = 0x0;
-
-    private static final long TEST_FLOW_REMOVED_MASK = 0xf;
-    private static final long TEST_PACKET_IN_MASK = 0x7;
-    private static final long TEST_PORT_STATUS_MASK = 0x7;
-    private long barrierXidToWaitFor = -1;
-
-    private static final int TABLE_VLAN = 0;
-    private static final int TABLE_TMAC = 1;
-    private static final int TABLE_IPV4_UNICAST = 2;
-    private static final int TABLE_MPLS = 3;
-    private static final int TABLE_META = 4;
-    private static final int TABLE_ACL = 5;
-
-    private static final short MAX_PRIORITY = (short) 0xffff;
-    private static final short SLASH_24_PRIORITY = (short) 0xfff0;
-    private static final short MIN_PRIORITY = 0x0;
-    private static final U64 METADATA_MASK = U64.of(Long.MAX_VALUE << 1 | 0x1);
-
-    private final Map<Integer, OFGroup> l2groups;
-
-    public OFSwitchImplCPqD13(Dpid dpid, OFDescStatsReply desc) {
-        super(dpid);
-        driverHandshakeComplete = new AtomicBoolean(false);
-        l2groups = new ConcurrentHashMap<Integer, OFGroup>();
-        setSwitchDescription(desc);
-    }
-
-    /* (non-Javadoc)
-     * @see java.lang.Object#toString()
-     */
-    @Override
-    public String toString() {
-        return "OFSwitchImplCPqD13 [" + ((channel != null)
-                ? channel.getRemoteAddress() : "?")
-                + " DPID[" + ((this.getStringId() != null) ? this.getStringId() : "?") + "]]";
-    }
-
-    @Override
-    public void startDriverHandshake() {
-        log.debug("Starting driver handshake for sw {}", getStringId());
-        if (startDriverHandshakeCalled) {
-            throw new SwitchDriverSubHandshakeAlreadyStarted();
-        }
-        startDriverHandshakeCalled = true;
-        factory = this.factory();
-
-        sendBarrier(true);
-    }
-
-    @Override
-    public boolean isDriverHandshakeComplete() {
-        if (!startDriverHandshakeCalled) {
-            throw new SwitchDriverSubHandshakeNotStarted();
-        }
-        return driverHandshakeComplete.get();
-    }
-
-    @Override
-    public void processDriverHandshakeMessage(OFMessage m) {
-        if (!startDriverHandshakeCalled) {
-            throw new SwitchDriverSubHandshakeNotStarted();
-        }
-        if (driverHandshakeComplete.get()) {
-            throw new SwitchDriverSubHandshakeCompleted(m);
-        }
-
-        switch (m.getType()) {
-        case BARRIER_REPLY:
-            if (m.getXid() == barrierXidToWaitFor) {
-                driverHandshakeComplete.set(true);
-            }
-            break;
-
-        case ERROR:
-            log.error("Switch {} Error {}", getStringId(), m);
-            break;
-
-        case GET_ASYNC_REPLY:
-            OFAsyncGetReply asrep = (OFAsyncGetReply) m;
-            decodeAsyncGetReply(asrep);
-            break;
-        case STATS_REPLY:
-            processStatsReply((OFStatsReply) m);
-            break;
-        case PACKET_IN:
-        case PORT_STATUS:
-        case QUEUE_GET_CONFIG_REPLY:
-        case ROLE_REPLY:
-        case FEATURES_REPLY:
-        case FLOW_REMOVED:
-            break;
-
-        default:
-            log.debug("Received message {} during switch-driver subhandshake "
-                    + "from switch {} ... Ignoring message", m, getStringId());
-
-        }
-    }
-
-    private void configureSwitch() throws IOException {
-        // setAsyncConfig();
-        // getTableFeatures();
-        sendGroupFeaturesRequest();
-        setL2Groups();
-        sendBarrier(false);
-        setL3Groups();
-        setL25Groups();
-        sendGroupDescRequest();
-        populateTableVlan();
-        populateTableTMac();
-        populateIpTable();
-        populateMplsTable();
-        populateTableMissEntry(TABLE_ACL, false, false, false, -1);
-        sendBarrier(true);
-    }
-
-    private void setAsyncConfig() throws IOException {
-        List<OFMessage> msglist = new ArrayList<OFMessage>(3);
-        OFMessage setAC = null;
-
-        if (role == RoleState.MASTER) {
-            setAC = factory.buildAsyncSet()
-                    .setFlowRemovedMaskEqualMaster(SET_FLOW_REMOVED_MASK_MASTER)
-                    .setPacketInMaskEqualMaster(SET_PACKET_IN_MASK_MASTER)
-                    .setPortStatusMaskEqualMaster(SET_PORT_STATUS_MASK_MASTER)
-                    .setFlowRemovedMaskSlave(SET_ALL_SLAVE)
-                    .setPacketInMaskSlave(SET_ALL_SLAVE)
-                    .setPortStatusMaskSlave(SET_ALL_SLAVE)
-                    .setXid(getNextTransactionId())
-                    .build();
-        } else if (role == RoleState.EQUAL) {
-            setAC = factory.buildAsyncSet()
-                    .setFlowRemovedMaskEqualMaster(SET_FLOW_REMOVED_MASK_EQUAL)
-                    .setPacketInMaskEqualMaster(SET_PACKET_IN_MASK_EQUAL)
-                    .setPortStatusMaskEqualMaster(SET_PORT_STATUS_MASK_EQUAL)
-                    .setFlowRemovedMaskSlave(SET_ALL_SLAVE)
-                    .setPacketInMaskSlave(SET_ALL_SLAVE)
-                    .setPortStatusMaskSlave(SET_ALL_SLAVE)
-                    .setXid(getNextTransactionId())
-                    .build();
-        }
-        msglist.add(setAC);
-
-        OFMessage br = factory.buildBarrierRequest()
-                .setXid(getNextTransactionId())
-                .build();
-        msglist.add(br);
-
-        OFMessage getAC = factory.buildAsyncGetRequest()
-                .setXid(getNextTransactionId())
-                .build();
-        msglist.add(getAC);
-
-        sendMsg(msglist);
-    }
-
-    private void decodeAsyncGetReply(OFAsyncGetReply rep) {
-        long frm = rep.getFlowRemovedMaskEqualMaster();
-        //long frs = rep.getFlowRemovedMaskSlave();
-        long pim = rep.getPacketInMaskEqualMaster();
-        //long pis = rep.getPacketInMaskSlave();
-        long psm = rep.getPortStatusMaskEqualMaster();
-        //long pss = rep.getPortStatusMaskSlave();
-
-        if (role == RoleState.MASTER || role == RoleState.EQUAL) { // should separate
-            log.info("FRM:{}", HexString.toHexString((frm & TEST_FLOW_REMOVED_MASK)));
-            log.info("PIM:{}", HexString.toHexString((pim & TEST_PACKET_IN_MASK)));
-            log.info("PSM:{}", HexString.toHexString((psm & TEST_PORT_STATUS_MASK)));
-        }
-
-    }
-
-    private void getTableFeatures() throws IOException {
-        OFMessage gtf = factory.buildTableFeaturesStatsRequest()
-                .setXid(getNextTransactionId())
-                .build();
-        sendMsg(gtf);
-    }
-
-    private void sendGroupFeaturesRequest() throws IOException {
-        OFMessage gfr = factory.buildGroupFeaturesStatsRequest()
-                .setXid(getNextTransactionId())
-                .build();
-        sendMsg(gfr);
-    }
-
-    private void sendGroupDescRequest() throws IOException {
-        OFMessage gdr = factory.buildGroupDescStatsRequest()
-                .setXid(getNextTransactionId())
-                .build();
-        sendMsg(gdr);
-    }
-
-    /*Create L2 interface groups for all physical ports
-     Naming convention followed is the same as OF-DPA spec
-     eg. port 1 with allowed vlan 10, is enveloped in group with id,
-         0x0 00a 0001, where the uppermost 4 bits identify an L2 interface,
-         the next 12 bits identify the vlan-id, and the lowermost 16 bits
-         identify the port number.*/
-    private void setL2Groups() throws IOException {
-        List<OFMessage> msglist = new ArrayList<OFMessage>();
-        for (OFPortDesc p : getPorts()) {
-            int pnum = p.getPortNo().getPortNumber();
-            int portVlan = getVlanConfig(pnum);
-            if (U32.of(pnum).compareTo(U32.of(OFPort.MAX.getPortNumber())) < 1) {
-                OFGroup gl2 = OFGroup.of(pnum | (portVlan << VLAN_ID_OFFSET));
-                OFAction out = factory.actions().buildOutput()
-                        .setPort(p.getPortNo()).build();
-                OFAction popVlan = factory.actions().popVlan();
-                List<OFAction> actions = new ArrayList<OFAction>();
-                actions.add(popVlan);
-                actions.add(out);
-                OFBucket bucket = factory.buildBucket()
-                        .setActions(actions).build();
-                List<OFBucket> buckets = Collections.singletonList(bucket);
-                OFMessage gmAdd = factory.buildGroupAdd()
-                        .setGroup(gl2)
-                        .setBuckets(buckets)
-                        .setGroupType(OFGroupType.INDIRECT)
-                        .setXid(getNextTransactionId())
-                        .build();
-                msglist.add(gmAdd);
-                l2groups.put(pnum, gl2);
-            }
-        }
-        log.debug("Creating {} L2 groups in sw {}", msglist.size(), getStringId());
-        sendMsg(msglist);
-    }
-
-    private int getVlanConfig(int portnum) {
-        int portVlan = 10 * portnum;
-        if ((getId() == 0x1 && portnum == 6) ||
-                (getId() == 0x2) ||
-                (getId() == 0x3 && portnum == 2)) {
-            portVlan = 192; // 0xc0
-        }
-        return portVlan;
-    }
-
-    private MacAddress getRouterMacAddr() {
-        if (getId() == 0x3) {
-            return MacAddress.of("00:00:07:07:07:80"); // router mac
-        }
-        if (getId() == 0x1) {
-            return MacAddress.of("00:00:01:01:01:80");
-        }
-        // switch 0x2
-        return MacAddress.of("00:00:02:02:02:80");
-    }
-
-    // only for ports connected to other routers
-    private OFAction getDestAction(int portnum) {
-        OFAction setDA = null;
-        MacAddress dAddr = null;
-        if (getId() == 0x1 && portnum == 6) { // connected to switch 2
-            dAddr = MacAddress.of("00:00:02:02:02:80");
-        }
-        if (getId() == 0x2) {
-            if (portnum == 1) { // connected to sw 1
-                dAddr = MacAddress.of("00:00:01:01:01:80");
-            } else if (portnum == 2) { // connected to sw 3
-                dAddr = MacAddress.of("00:00:07:07:07:80");
-            }
-        }
-        if (getId() == 0x3) {
-            if (portnum == 2) { // connected to switch 2
-                dAddr = MacAddress.of("00:00:02:02:02:80");
-            }
-        }
-
-        if (dAddr != null) {
-            OFOxmEthDst dstAddr = factory.oxms().ethDst(dAddr);
-            setDA = factory.actions().buildSetField()
-                    .setField(dstAddr).build();
-        }
-        return setDA;
-    }
-
-    /*
-     * L3 groups are created for all router ports and they all point to corresponding
-     * L2 groups. Only the ports that connect to other routers will have the
-     * DA set.
-     */
-    private void setL3Groups() throws IOException {
-        List<OFMessage> msglist = new ArrayList<OFMessage>();
-        for (OFGroup gl2 : l2groups.values()) {
-            int gnum = gl2.getGroupNumber();
-            int portnum = gnum & 0x0000ffff;
-            int vlanid = ((gnum & 0x0fff0000) >> VLAN_ID_OFFSET);
-            MacAddress sAddr = getRouterMacAddr();
-
-            OFGroup gl3 = OFGroup.of(0x20000000 | portnum);
-            OFAction group = factory.actions().buildGroup()
-                    .setGroup(gl2).build();
-            OFOxmEthSrc srcAddr = factory.oxms().ethSrc(sAddr);
-            OFAction setSA = factory.actions().buildSetField()
-                    .setField(srcAddr).build();
-            OFOxmVlanVid vid = factory.oxms().vlanVid(OFVlanVidMatch.ofVlan(vlanid));
-            OFAction setVlan = factory.actions().buildSetField()
-                    .setField(vid).build();
-            OFAction decTtl = factory.actions().decNwTtl();
-
-            List<OFAction> actions = new ArrayList<OFAction>();
-            actions.add(decTtl); // decrement the IP TTL/do-checksum/check TTL
-            // and MTU
-            actions.add(setVlan); // set the vlan-id of the exit-port (and
-            // l2group)
-            actions.add(setSA); // set this routers mac address
-            // make L3Unicast group setDA for known (configured) ports
-            // that connect to other routers
-            OFAction setDA = getDestAction(portnum);
-            if (setDA != null) {
-                actions.add(setDA);
-            }
-            actions.add(group);
-
-            OFBucket bucket = factory.buildBucket()
-                    .setActions(actions).build();
-            List<OFBucket> buckets = Collections.singletonList(bucket);
-            OFMessage gmAdd = factory.buildGroupAdd()
-                    .setGroup(gl3)
-                    .setBuckets(buckets)
-                    .setGroupType(OFGroupType.INDIRECT)
-                    .setXid(getNextTransactionId())
-                    .build();
-            msglist.add(gmAdd);
-        }
-        sendMsg(msglist);
-        log.debug("Creating {} L3 groups in sw {}", msglist.size(), getStringId());
-    }
-
-    /*
-     * L2.5 or mpls-unicast groups are only created for those router ports
-     * connected to other router ports. They differ from the corresponding
-     * L3-unicast group only by the fact that they decrement the MPLS TTL
-     * instead of the IP ttl
-     */
-    private void setL25Groups() throws IOException {
-        List<OFMessage> msglist = new ArrayList<OFMessage>();
-        for (OFGroup gl2 : l2groups.values()) {
-            int gnum = gl2.getGroupNumber();
-            int portnum = gnum & 0x0000ffff;
-            int vlanid = ((gnum & 0x0fff0000) >> VLAN_ID_OFFSET);
-            MacAddress sAddr = getRouterMacAddr();
-            OFAction setDA = getDestAction(portnum);
-            // setDA will only be non-null for ports connected to routers
-            if (setDA != null) {
-                OFGroup gl3 = OFGroup.of(0xa0000000 | portnum); // different id
-                // for mpls
-                // group
-                OFAction group = factory.actions().buildGroup()
-                        .setGroup(gl2).build();
-                OFOxmEthSrc srcAddr = factory.oxms().ethSrc(sAddr);
-                OFAction setSA = factory.actions().buildSetField()
-                        .setField(srcAddr).build();
-                OFOxmVlanVid vid = factory.oxms().vlanVid(OFVlanVidMatch.ofVlan(vlanid));
-                OFAction setVlan = factory.actions().buildSetField()
-                        .setField(vid).build();
-                OFAction decMplsTtl = factory.actions().decMplsTtl();
-                List<OFAction> actions = new ArrayList<OFAction>();
-                actions.add(decMplsTtl); // decrement the MPLS
-                // TTL/do-checksum/check TTL and MTU
-                actions.add(setVlan); // set the vlan-id of the exit-port (and
-                // l2group)
-                actions.add(setSA); // set this routers mac address
-                actions.add(setDA);
-                actions.add(group);
-                OFBucket bucket = factory.buildBucket()
-                        .setActions(actions).build();
-                List<OFBucket> buckets = Collections.singletonList(bucket);
-                OFMessage gmAdd = factory.buildGroupAdd()
-                        .setGroup(gl3)
-                        .setBuckets(buckets)
-                        .setGroupType(OFGroupType.INDIRECT)
-                        .setXid(getNextTransactionId())
-                        .build();
-                msglist.add(gmAdd);
-            }
-        }
-        sendMsg(msglist);
-        log.debug("Creating {} MPLS groups in sw {}", msglist.size(), getStringId());
-    }
-
-    /* Using ECMP groups
-     *
-     * OFGroup group47 = OFGroup.of(47);
-        OFAction outgroup1 = factory.actions()
-                        .buildGroup()
-                        .setGroup(group61)
-                        .build();
-        OFBucket buc47_1 = factory.buildBucket()
-                        .setWeight(1)
-                        .setActions(Collections.singletonList(outgroup1))
-                        .build();
-        OFAction outgroup2 = factory.actions()
-                        .buildGroup()
-                        .setGroup(group62)
-                        .build();
-        OFBucket buc47_2 = factory.buildBucket()
-                        .setWeight(1)
-                        .setActions(Collections.singletonList(outgroup2))
-                        .build();
-        List<OFBucket> buckets47 = new ArrayList<OFBucket>();
-        buckets47.add(buc47_1);
-        buckets47.add(buc47_2);
-        OFMessage gmS12 = factory.buildGroupAdd()
-                        .setGroup(group47)
-                        .setBuckets(buckets47)
-                        .setGroupType(OFGroupType.SELECT)
-                        .setXid(getNextTransactionId())
-                        .build();
-        write(gmS12, null);     */
-
-    private void processStatsReply(OFStatsReply sr) {
-        switch (sr.getStatsType()) {
-        case AGGREGATE:
-            break;
-        case DESC:
-            break;
-        case EXPERIMENTER:
-            break;
-        case FLOW:
-            break;
-        case GROUP_DESC:
-            processGroupDesc((OFGroupDescStatsReply) sr);
-            break;
-        case GROUP_FEATURES:
-            processGroupFeatures((OFGroupFeaturesStatsReply) sr);
-            break;
-        case METER_CONFIG:
-            break;
-        case METER_FEATURES:
-            break;
-        case PORT_DESC:
-            break;
-        case TABLE_FEATURES:
-            break;
-        default:
-            break;
-
-        }
-    }
-
-    private void processGroupFeatures(OFGroupFeaturesStatsReply gfsr) {
-        log.info("Sw: {} Group Features {}", getStringId(), gfsr);
-    }
-
-    private void processGroupDesc(OFGroupDescStatsReply gdsr) {
-        log.info("Sw: {} Group Desc {}", getStringId(), gdsr);
-    }
-
-    private void populateTableVlan() throws IOException {
-        // for all incoming ports assign configured port-vlans
-        // currently assign portnum*10 -> vlanid to access ports
-        // and vlan 192 to router to router ports
-        List<OFMessage> msglist = new ArrayList<OFMessage>();
-        for (OFPortDesc p : getPorts()) {
-            int pnum = p.getPortNo().getPortNumber();
-            if (U32.of(pnum).compareTo(U32.of(OFPort.MAX.getPortNumber())) < 1) {
-                int vlanid = getVlanConfig(pnum);
-                OFOxmInPort oxp = factory.oxms().inPort(p.getPortNo());
-                OFOxmVlanVid oxv = factory.oxms()
-                        .vlanVid(OFVlanVidMatch.UNTAGGED);
-                OFOxmList oxmList = OFOxmList.of(oxp, oxv);
-                OFMatchV3 match = factory.buildMatchV3()
-                        .setOxmList(oxmList).build();
-                OFOxmVlanVid vidToSet = factory.oxms()
-                        .vlanVid(OFVlanVidMatch.ofVlan(vlanid));
-                OFAction pushVlan = factory.actions().pushVlan(EthType.VLAN_FRAME);
-                OFAction setVlan = factory.actions().setField(vidToSet);
-                List<OFAction> actionlist = new ArrayList<OFAction>();
-                actionlist.add(pushVlan);
-                actionlist.add(setVlan);
-                OFInstruction appAction = factory.instructions().buildApplyActions()
-                        .setActions(actionlist).build();
-                OFInstruction gotoTbl = factory.instructions().buildGotoTable()
-                        .setTableId(TableId.of(TABLE_TMAC)).build();
-                List<OFInstruction> instructions = new ArrayList<OFInstruction>();
-                instructions.add(appAction);
-                instructions.add(gotoTbl);
-                OFMessage flowEntry = factory.buildFlowAdd()
-                        .setTableId(TableId.of(TABLE_VLAN))
-                        .setMatch(match)
-                        .setInstructions(instructions)
-                        .setPriority(1000) // does not matter - all rules
-                        // exclusive
-                        .setBufferId(OFBufferId.NO_BUFFER)
-                        .setIdleTimeout(0)
-                        .setHardTimeout(0)
-                        .setXid(getNextTransactionId())
-                        .build();
-                msglist.add(flowEntry);
-            }
-        }
-        // table-vlan has no table-miss entry, and so packets that miss are
-        // essentially dropped
-        sendMsg(msglist);
-        log.debug("Adding {} vlan-rules in sw {}", msglist.size(), getStringId());
-    }
-
-    private void populateTableTMac() throws IOException {
-        // match for ip packets
-        OFOxmEthType oxe = factory.oxms().ethType(EthType.IPv4);
-        OFOxmList oxmListIp = OFOxmList.of(oxe);
-        OFMatchV3 matchIp = factory.buildMatchV3()
-                .setOxmList(oxmListIp).build();
-        OFInstruction gotoTblIp = factory.instructions().buildGotoTable()
-                .setTableId(TableId.of(TABLE_IPV4_UNICAST)).build();
-        List<OFInstruction> instructionsIp = Collections.singletonList(gotoTblIp);
-        OFMessage ipEntry = factory.buildFlowAdd()
-                .setTableId(TableId.of(TABLE_TMAC))
-                .setMatch(matchIp)
-                .setInstructions(instructionsIp)
-                .setPriority(1000) // strict priority required lower than
-                // multicastMac
-                .setBufferId(OFBufferId.NO_BUFFER)
-                .setIdleTimeout(0)
-                .setHardTimeout(0)
-                .setXid(getNextTransactionId())
-                .build();
-
-        // match for mpls packets
-        OFOxmEthType oxmpls = factory.oxms().ethType(EthType.MPLS_UNICAST);
-        OFOxmList oxmListMpls = OFOxmList.of(oxmpls);
-        OFMatchV3 matchMpls = factory.buildMatchV3()
-                .setOxmList(oxmListMpls).build();
-        OFInstruction gotoTblMpls = factory.instructions().buildGotoTable()
-                .setTableId(TableId.of(TABLE_MPLS)).build();
-        List<OFInstruction> instructionsMpls = Collections.singletonList(gotoTblMpls);
-        OFMessage mplsEntry = factory.buildFlowAdd()
-                .setTableId(TableId.of(TABLE_TMAC))
-                .setMatch(matchMpls)
-                .setInstructions(instructionsMpls)
-                .setPriority(1001) // strict priority required lower than
-                // multicastMac
-                .setBufferId(OFBufferId.NO_BUFFER)
-                .setIdleTimeout(0)
-                .setHardTimeout(0)
-                .setXid(getNextTransactionId())
-                .build();
-
-        // match for everything else to send to controller. Essentially
-        // the table miss flow entry
-        populateTableMissEntry(TABLE_TMAC, true, false, false, -1);
-        log.debug("Adding termination-mac-rules in sw {}", getStringId());
-        List<OFMessage> msglist = new ArrayList<OFMessage>(2);
-        msglist.add(ipEntry);
-        msglist.add(mplsEntry);
-        sendMsg(msglist);
-    }
-
-    private List<String> getMyIps() { // send to controller
-        List<String> myIps = new ArrayList<String>();
-        if (getId() == 0x1) {
-            myIps.add("10.0.2.128");
-            myIps.add("10.0.3.128");
-            myIps.add("10.0.1.128");
-            myIps.add("192.168.0.1");
-        }
-        if (getId() == 0x2) {
-            myIps.add("192.168.0.2");
-        }
-        if (getId() == 0x3) {
-            myIps.add("192.168.0.3");
-            myIps.add("7.7.7.128");
-        }
-        return myIps;
-    }
-
-    private List<String> getMySubnetIps() { // send to controller
-        List<String> subnetIps = new ArrayList<String>();
-        if (getId() == 0x1) {
-            subnetIps.add("10.0.2.0");
-            subnetIps.add("10.0.3.0");
-            subnetIps.add("10.0.1.0");
-        }
-
-        if (getId() == 0x3) {
-            subnetIps.add("7.7.7.0");
-        }
-        return subnetIps;
-    }
-    private static class RouteEntry {
-        String prefix;
-        String mask;
-        int nextHopPort;
-        String dstMac;
-        int label;
-
-        public RouteEntry(String prefix, String mask, int nextHopPort, int label) {
-            this.prefix = prefix;
-            this.mask = mask;
-            this.nextHopPort = nextHopPort;
-            this.label = label;
-        }
-
-        public RouteEntry(String prefix, int nextHopPort, String dstMac) {
-            this.prefix = prefix;
-            this.nextHopPort = nextHopPort;
-            this.dstMac = dstMac;
-        }
-    }
-
-    // send out of mpls-group where the next-hop mac-da is already set
-    private List<RouteEntry> getRouterNextHopIps() {
-        List<RouteEntry> routerNextHopIps = new ArrayList<RouteEntry>();
-        if (getId() == 0x1) {
-            routerNextHopIps
-            .add(new RouteEntry("192.168.0.2", "255.255.255.255", 6, 102));
-            routerNextHopIps
-            .add(new RouteEntry("192.168.0.3", "255.255.255.255", 6, 103));
-            routerNextHopIps.add(new RouteEntry("7.7.7.0", "255.255.255.0", 6, 103));
-        }
-        //if (getId() == 0x2) {
-        /* These are required for normal IP routing without labels.
-            routerNextHopIps.add(new RouteEntry("192.168.0.1","255.255.255.255",1));
-            routerNextHopIps.add(new RouteEntry("192.168.0.3","255.255.255.255",2));
-            routerNextHopIps.add(new RouteEntry("10.0.1.0","255.255.255.0",1));
-            routerNextHopIps.add(new RouteEntry("10.0.2.0","255.255.255.0",1));
-            routerNextHopIps.add(new RouteEntry("10.0.3.0","255.255.255.0",1));
-            routerNextHopIps.add(new RouteEntry("7.7.7.0","255.255.255.0",2));*/
-        //}
-        if (getId() == 0x3) {
-            routerNextHopIps
-            .add(new RouteEntry("192.168.0.2", "255.255.255.255", 2, 102));
-            routerNextHopIps
-            .add(new RouteEntry("192.168.0.1", "255.255.255.255", 2, 101));
-            routerNextHopIps.add(new RouteEntry("10.0.1.0", "255.255.255.0", 2, 101));
-            routerNextHopIps.add(new RouteEntry("10.0.2.0", "255.255.255.0", 2, 101));
-            routerNextHopIps.add(new RouteEntry("10.0.3.0", "255.255.255.0", 2, 101));
-        }
-        return routerNextHopIps;
-    }
-
-    // known host mac-addr, setDA/send out of l3group
-    private List<RouteEntry> getHostNextHopIps() {
-        List<RouteEntry> hostNextHopIps = new ArrayList<RouteEntry>();
-        if (getId() == 0x1) {
-            hostNextHopIps.add(new RouteEntry("10.0.2.1", 4, "00:00:00:00:02:01"));
-            hostNextHopIps.add(new RouteEntry("10.0.3.1", 5, "00:00:00:00:03:01"));
-        }
-        if (getId() == 0x3) {
-            hostNextHopIps.add(new RouteEntry("7.7.7.7", 1, "00:00:07:07:07:07"));
-        }
-        return hostNextHopIps;
-    }
-
-    private void populateIpTable() throws IOException {
-        populateMyIps();
-        populateMySubnets();
-        populateRoutes();
-        populateHostRoutes();
-
-        // match for everything else to send to ACL table. Essentially
-        // the table miss flow entry
-        populateTableMissEntry(TABLE_IPV4_UNICAST, false, true,
-                true, TABLE_ACL);
-    }
-
-    private void populateMyIps() throws IOException {
-        List<OFMessage> msglist = new ArrayList<OFMessage>();
-        // first all my ip's as exact-matches
-        // write-action instruction to send to controller
-        List<String> myIps = getMyIps();
-        for (int i = 0; i < myIps.size(); i++) {
-            OFOxmEthType ethTypeIp = factory.oxms()
-                    .ethType(EthType.IPv4);
-            OFOxmIpv4DstMasked ipPrefix = factory.oxms()
-                    .ipv4DstMasked(IPv4Address.of(myIps.get(i)), IPv4Address.NO_MASK);
-            OFOxmList oxmListSlash32 = OFOxmList.of(ethTypeIp, ipPrefix);
-            OFMatchV3 match = factory.buildMatchV3()
-                    .setOxmList(oxmListSlash32).build();
-            OFAction outc = factory.actions().buildOutput()
-                    .setPort(OFPort.CONTROLLER).setMaxLen(OFPCML_NO_BUFFER)
-                    .build();
-            OFInstruction writeInstr = factory.instructions().buildWriteActions()
-                    .setActions(Collections.singletonList(outc)).build();
-            OFInstruction gotoInstr = factory.instructions().buildGotoTable()
-                    .setTableId(TableId.of(TABLE_ACL)).build();
-            List<OFInstruction> instructions = new ArrayList<OFInstruction>();
-            instructions.add(writeInstr);
-            instructions.add(gotoInstr);
-            OFMessage myIpEntry = factory.buildFlowAdd()
-                    .setTableId(TableId.of(TABLE_IPV4_UNICAST))
-                    .setMatch(match)
-                    .setInstructions(instructions)
-                    .setPriority(MAX_PRIORITY) // highest priority for exact
-                    // match
-                    .setBufferId(OFBufferId.NO_BUFFER)
-                    .setIdleTimeout(0)
-                    .setHardTimeout(0)
-                    .setXid(getNextTransactionId())
-                    .build();
-            msglist.add(myIpEntry);
-        }
-        sendMsg(msglist);
-        log.debug("Adding {} my-ip-rules in sw {}", msglist.size(), getStringId());
-    }
-
-    private void populateMySubnets() throws IOException {
-        List<OFMessage> msglist = new ArrayList<OFMessage>();
-        // next prefix-based subnet-IP's configured on my interfaces
-        // need to ARP for exact-IP, so write-action instruction to send to
-        // controller
-        // this has different mask and priority than earlier case
-        List<String> subnetIps = getMySubnetIps();
-        for (int i = 0; i < subnetIps.size(); i++) {
-            OFOxmEthType ethTypeIp = factory.oxms()
-                    .ethType(EthType.IPv4);
-            OFOxmIpv4DstMasked ipPrefix = factory.oxms().ipv4DstMasked(
-                    IPv4Address.of(subnetIps.get(i)),
-                    IPv4Address.of(0xffffff00)); // '/24' mask
-            OFOxmList oxmListSlash24 = OFOxmList.of(ethTypeIp, ipPrefix);
-            OFMatchV3 match = factory.buildMatchV3()
-                    .setOxmList(oxmListSlash24).build();
-            OFAction outc = factory.actions().buildOutput()
-                    .setPort(OFPort.CONTROLLER).setMaxLen(OFPCML_NO_BUFFER)
-                    .build();
-            OFInstruction writeInstr = factory.instructions().buildWriteActions()
-                    .setActions(Collections.singletonList(outc)).build();
-            OFInstruction gotoInstr = factory.instructions().buildGotoTable()
-                    .setTableId(TableId.of(TABLE_ACL)).build();
-            List<OFInstruction> instructions = new ArrayList<OFInstruction>();
-            instructions.add(writeInstr);
-            instructions.add(gotoInstr);
-            OFMessage myIpEntry = factory.buildFlowAdd()
-                    .setTableId(TableId.of(TABLE_IPV4_UNICAST))
-                    .setMatch(match)
-                    .setInstructions(instructions)
-                    .setPriority(SLASH_24_PRIORITY)
-                    .setBufferId(OFBufferId.NO_BUFFER)
-                    .setIdleTimeout(0)
-                    .setHardTimeout(0)
-                    .setXid(getNextTransactionId())
-                    .build();
-            msglist.add(myIpEntry);
-        }
-        sendMsg(msglist);
-        log.debug("Adding {} subnet-ip-rules in sw {}", msglist.size(), getStringId());
-        msglist.clear();
-    }
-
-    private void populateRoutes() throws IOException {
-        List<OFMessage> msglist = new ArrayList<OFMessage>();
-        // addresses where I know the next-hop's mac-address because it is a
-        // router port - so I have an L3 interface to it (and an MPLS interface)
-        List<RouteEntry> routerNextHopIps = getRouterNextHopIps();
-        for (int i = 0; i < routerNextHopIps.size(); i++) {
-            OFOxmEthType ethTypeIp = factory.oxms()
-                    .ethType(EthType.IPv4);
-            OFOxmIpv4DstMasked ipPrefix = factory.oxms()
-                    .ipv4DstMasked(
-                            IPv4Address.of(routerNextHopIps.get(i).prefix),
-                            IPv4Address.of(routerNextHopIps.get(i).mask)
-                            );
-            OFOxmList oxmListSlash32 = OFOxmList.of(ethTypeIp, ipPrefix);
-            OFMatchV3 match = factory.buildMatchV3()
-                    .setOxmList(oxmListSlash32).build();
-            OFAction outg = factory.actions().buildGroup()
-                    .setGroup(OFGroup.of(0xa0000000 | // mpls group id
-                            routerNextHopIps.get(i).nextHopPort))
-                            .build();
-            // lots of actions before forwarding to mpls group, and
-            // unfortunately
-            // they need to be apply-actions
-
-            OFAction pushlabel = factory.actions().pushMpls(EthType.MPLS_UNICAST);
-            OFOxmMplsLabel l = factory.oxms()
-                    .mplsLabel(U32.of(routerNextHopIps.get(i).label));
-            OFAction setlabelid = factory.actions().buildSetField()
-                    .setField(l).build();
-            OFAction copyTtlOut = factory.actions().copyTtlOut();
-            // OFAction setBos =
-            // factory.actions().buildSetField().setField(bos).build();
-
-            /*
-            writeActions.add(pushlabel);  // need to be apply actions so can be
-            writeActions.add(copyTtlOut); // matched in pseudo-table
-            //writeActions.add(setlabelid); // bad support in cpqd
-            //writeActions.add(setBos); no support in loxigen
-             */
-
-            List<OFAction> applyActions = new ArrayList<OFAction>();
-            applyActions.add(pushlabel);
-            applyActions.add(copyTtlOut);
-            OFInstruction applyInstr = factory.instructions().buildApplyActions()
-                    .setActions(applyActions).build();
-            List<OFAction> writeActions = new ArrayList<OFAction>();
-            writeActions.add(outg); // group will decr mpls-ttl, set mac-sa/da,
-            // vlan
-            OFInstruction writeInstr = factory.instructions().buildWriteActions()
-                    .setActions(writeActions).build();
-
-            // necessary to match in pseudo-table to overcome cpqd 1.3 flaw
-            OFInstruction writeMeta = factory.instructions().buildWriteMetadata()
-                    .setMetadata(U64.of(routerNextHopIps.get(i).label))
-                    .setMetadataMask(METADATA_MASK).build();
-            /*OFInstruction gotoInstr = factory.instructions().buildGotoTable()
-                        .setTableId(TableId.of(TABLE_ACL)).build();*/
-            OFInstruction gotoInstr = factory.instructions().buildGotoTable()
-                    .setTableId(TableId.of(TABLE_META)).build();
-            List<OFInstruction> instructions = new ArrayList<OFInstruction>();
-            instructions.add(applyInstr);
-            // instructions.add(writeInstr);// cannot write here - causes switch
-            // to crash
-            instructions.add(writeMeta);
-            instructions.add(gotoInstr);
-
-            int priority = -1;
-            if (routerNextHopIps.get(i).mask.equals("255.255.255.255")) {
-                priority = MAX_PRIORITY;
-            } else {
-                priority = SLASH_24_PRIORITY;
-            }
-            OFMessage myIpEntry = factory.buildFlowAdd()
-                    .setTableId(TableId.of(TABLE_IPV4_UNICAST))
-                    .setMatch(match)
-                    .setInstructions(instructions)
-                    .setPriority(priority)
-                    .setBufferId(OFBufferId.NO_BUFFER)
-                    .setIdleTimeout(0)
-                    .setHardTimeout(0)
-                    .setXid(getNextTransactionId())
-                    .build();
-            msglist.add(myIpEntry);
-
-            // need to also handle psuedo-table entries to match-metadata and
-            // set mpls
-            // label-id
-            OFOxmEthType ethTypeMpls = factory.oxms()
-                    .ethType(EthType.MPLS_UNICAST);
-            OFOxmMetadataMasked meta = factory.oxms()
-                    .metadataMasked(
-                            OFMetadata.ofRaw(routerNextHopIps.get(i).label),
-                            OFMetadata.NO_MASK);
-            OFOxmList oxmListMeta = OFOxmList.of(ethTypeMpls, meta);
-            OFMatchV3 matchMeta = factory.buildMatchV3()
-                    .setOxmList(oxmListMeta).build();
-            List<OFAction> writeActions2 = new ArrayList<OFAction>();
-            writeActions2.add(setlabelid);
-            OFAction outg2 = factory.actions().buildGroup()
-                    .setGroup(OFGroup.of(routerNextHopIps.get(i).nextHopPort |
-                            (192 << VLAN_ID_OFFSET)))
-                            .build();
-            writeActions2.add(outg2);
-            OFInstruction writeInstr2 = factory.instructions().buildWriteActions()
-                    .setActions(writeActions2).build();
-            OFInstruction gotoInstr2 = factory.instructions().buildGotoTable()
-                    .setTableId(TableId.of(TABLE_ACL)).build();
-            List<OFInstruction> instructions2 = new ArrayList<OFInstruction>();
-            // unfortunately have to apply this action too
-            OFInstruction applyInstr2 = factory.instructions().buildApplyActions()
-                    .setActions(writeActions2).build();
-            instructions2.add(applyInstr2);
-            // instructions2.add(writeInstr2);
-            // instructions2.add(gotoInstr2);
-
-            /*OFMatchV3 match3 = factory.buildMatchV3()
-                        .setOxmList(OFOxmList.of(meta)).build();
-            OFInstruction clearInstruction = factory.instructions().clearActions();
-            List<OFInstruction> instructions3 = new ArrayList<OFInstruction>();
-            OFAction outc = factory.actions().buildOutput()
-                        .setPort(OFPort.CONTROLLER).setMaxLen(OFPCML_NO_BUFFER)
-                        .build();
-            OFInstruction writec = factory.instructions()
-                        .writeActions(Collections.singletonList(outc));
-            instructions3.add(clearInstruction);
-            instructions3.add(writec);
-            instructions3.add(gotoInstr2); */
-            OFMessage myMetaEntry = factory.buildFlowAdd()
-                    .setTableId(TableId.of(TABLE_META))
-                    .setMatch(matchMeta)
-                    .setInstructions(instructions2)
-                    .setPriority(MAX_PRIORITY)
-                    .setBufferId(OFBufferId.NO_BUFFER)
-                    .setIdleTimeout(0)
-                    .setHardTimeout(0)
-                    .setXid(getNextTransactionId())
-                    .build();
-            msglist.add(myMetaEntry);
-
-        }
-        sendMsg(msglist);
-        log.debug("Adding {} next-hop-router-rules in sw {}", msglist.size(),
-                getStringId());
-
-        // add a table-miss entry to table 4 for debugging - leave it out
-        // unclear packet state - causes switch to crash
-        // populateTableMissEntry(TABLE_META, false, true,
-        // true, TABLE_ACL);
-    }
-
-    private void populateHostRoutes() throws IOException {
-        List<OFMessage> msglist = new ArrayList<OFMessage>();
-        // addresses where I know the next hop's mac-address and I can set the
-        // destination mac in the match-instruction.write-action
-        // either I sent out arp-request or I got an arp-request from this host
-        List<RouteEntry> hostNextHopIps = getHostNextHopIps();
-        for (int i = 0; i < hostNextHopIps.size(); i++) {
-            OFOxmEthType ethTypeIp = factory.oxms()
-                    .ethType(EthType.IPv4);
-            OFOxmIpv4DstMasked ipPrefix = factory.oxms()
-                    .ipv4DstMasked(
-                            IPv4Address.of(hostNextHopIps.get(i).prefix),
-                            IPv4Address.NO_MASK); // host addr should be /32
-            OFOxmList oxmListSlash32 = OFOxmList.of(ethTypeIp, ipPrefix);
-            OFMatchV3 match = factory.buildMatchV3()
-                    .setOxmList(oxmListSlash32).build();
-            OFAction setDmac = null, outg = null;
-            OFOxmEthDst dmac = factory.oxms()
-                    .ethDst(MacAddress.of(hostNextHopIps.get(i).dstMac));
-            setDmac = factory.actions().buildSetField()
-                    .setField(dmac).build();
-            outg = factory.actions().buildGroup()
-                    .setGroup(OFGroup.of(0x20000000 | hostNextHopIps.get(i).nextHopPort)) // l3group
-                    // id
-                    .build();
-            List<OFAction> writeActions = new ArrayList<OFAction>();
-            writeActions.add(setDmac);
-            writeActions.add(outg);
-            OFInstruction writeInstr = factory.instructions().buildWriteActions()
-                    .setActions(writeActions).build();
-            OFInstruction gotoInstr = factory.instructions().buildGotoTable()
-                    .setTableId(TableId.of(TABLE_ACL)).build();
-            List<OFInstruction> instructions = new ArrayList<OFInstruction>();
-            instructions.add(writeInstr);
-            instructions.add(gotoInstr);
-            OFMessage myIpEntry = factory.buildFlowAdd()
-                    .setTableId(TableId.of(TABLE_IPV4_UNICAST))
-                    .setMatch(match)
-                    .setInstructions(instructions)
-                    .setPriority(MAX_PRIORITY) // highest priority for exact
-                    // match
-                    .setBufferId(OFBufferId.NO_BUFFER)
-                    .setIdleTimeout(0)
-                    .setHardTimeout(0)
-                    .setXid(getNextTransactionId())
-                    .build();
-            msglist.add(myIpEntry);
-        }
-        sendMsg(msglist);
-        log.debug("Adding {} next-hop-host-rules in sw {}", msglist.size(), getStringId());
-    }
-
-    private static class MplsEntry {
-        int labelid;
-        int portnum;
-
-        public MplsEntry(int labelid, int portnum) {
-            this.labelid = labelid;
-            this.portnum = portnum;
-        }
-    }
-
-    private List<MplsEntry> getMplsEntries() {
-        List<MplsEntry> myLabels = new ArrayList<MplsEntry>();
-        if (getId() == 0x1) {
-            myLabels.add(new MplsEntry(101, OFPort.CONTROLLER.getPortNumber()));
-            myLabels.add(new MplsEntry(103, 6));
-        }
-        if (getId() == 0x2) {
-            myLabels.add(new MplsEntry(103, 2));
-            myLabels.add(new MplsEntry(102, OFPort.CONTROLLER.getPortNumber()));
-            myLabels.add(new MplsEntry(101, 1));
-        }
-        if (getId() == 0x3) {
-            myLabels.add(new MplsEntry(103, OFPort.CONTROLLER.getPortNumber()));
-            myLabels.add(new MplsEntry(101, 2));
-        }
-        return myLabels;
-    }
-
-    private void populateMplsTable() throws IOException {
-        List<OFMessage> msglist = new ArrayList<OFMessage>();
-        List<MplsEntry> lfibEntries = getMplsEntries();
-        for (int i = 0; i < lfibEntries.size(); i++) {
-            OFOxmEthType ethTypeMpls = factory.oxms()
-                    .ethType(EthType.MPLS_UNICAST);
-            OFOxmMplsLabel labelid = factory.oxms()
-                    .mplsLabel(U32.of(lfibEntries.get(i).labelid));
-            OFOxmList oxmList = OFOxmList.of(ethTypeMpls, labelid);
-            OFMatchV3 matchlabel = factory.buildMatchV3()
-                    .setOxmList(oxmList).build();
-            OFAction poplabel = factory.actions().popMpls(EthType.IPv4);
-            OFAction sendTo = null;
-            if (lfibEntries.get(i).portnum == OFPort.CONTROLLER.getPortNumber()) {
-                sendTo = factory.actions().output(OFPort.CONTROLLER,
-                        OFPCML_NO_BUFFER);
-            } else {
-                sendTo = factory.actions().group(OFGroup.of(
-                        0xa0000000 | lfibEntries.get(i).portnum));
-            }
-            List<OFAction> writeActions = new ArrayList<OFAction>();
-            writeActions.add(poplabel);
-            writeActions.add(sendTo);
-            OFInstruction writeInstr = factory.instructions().buildWriteActions()
-                    .setActions(writeActions).build();
-            OFInstruction gotoInstr = factory.instructions().buildGotoTable()
-                    .setTableId(TableId.of(TABLE_ACL)).build();
-            List<OFInstruction> instructions = new ArrayList<OFInstruction>();
-            instructions.add(writeInstr);
-            instructions.add(gotoInstr);
-            OFMessage myMplsEntry = factory.buildFlowAdd()
-                    .setTableId(TableId.of(TABLE_MPLS))
-                    .setMatch(matchlabel)
-                    .setInstructions(instructions)
-                    .setPriority(MAX_PRIORITY) // exact match and exclusive
-                    .setBufferId(OFBufferId.NO_BUFFER)
-                    .setIdleTimeout(0)
-                    .setHardTimeout(0)
-                    .setXid(getNextTransactionId())
-                    .build();
-            msglist.add(myMplsEntry);
-        }
-        sendMsg(msglist);
-        log.debug("Adding {} mpls-forwarding-rules in sw {}", msglist.size(),
-                getStringId());
-
-        // match for everything else to send to ACL table. Essentially
-        // the table miss flow entry
-        populateTableMissEntry(TABLE_MPLS, false, true,
-                true, TABLE_ACL);
-
-    }
-
-    /**
-     * By default if none of the booleans in the call are set, then the
-     * table-miss entry is added with no instructions, which means that pipeline
-     * execution will stop, and the action set associated with the packet will
-     * be executed.
-     *
-     * @param tableToAdd
-     * @param toControllerNow as an APPLY_ACTION instruction
-     * @param toControllerWrite as a WRITE_ACITION instruction
-     * @param toTable as a GOTO_TABLE instruction
-     * @param tableToSend
-     * @throws java.io.IOException
-     */
-    @SuppressWarnings("unchecked")
-    private void populateTableMissEntry(int tableToAdd, boolean toControllerNow,
-            boolean toControllerWrite,
-            boolean toTable, int tableToSend) {
-        OFOxmList oxmList = OFOxmList.EMPTY;
-        OFMatchV3 match = factory.buildMatchV3()
-                .setOxmList(oxmList)
-                .build();
-        OFAction outc = factory.actions()
-                .buildOutput()
-                .setPort(OFPort.CONTROLLER)
-                .setMaxLen(OFPCML_NO_BUFFER)
-                .build();
-        List<OFInstruction> instructions = new ArrayList<OFInstruction>();
-        if (toControllerNow) {
-            // table-miss instruction to send to controller immediately
-            OFInstruction instr = factory.instructions()
-                    .buildApplyActions()
-                    .setActions(Collections.singletonList(outc))
-                    .build();
-            instructions.add(instr);
-        }
-
-        if (toControllerWrite) {
-            // table-miss instruction to write-action to send to controller
-            // this will be executed whenever the action-set gets executed
-            OFInstruction instr = factory.instructions()
-                    .buildWriteActions()
-                    .setActions(Collections.singletonList(outc))
-                    .build();
-            instructions.add(instr);
-        }
-
-        if (toTable) {
-            // table-miss instruction to goto-table x
-            OFInstruction instr = factory.instructions()
-                    .gotoTable(TableId.of(tableToSend));
-            instructions.add(instr);
-        }
-
-        if (!toControllerNow && !toControllerWrite && !toTable) {
-            // table-miss has no instruction - at which point action-set will be
-            // executed - if there is an action to output/group in the action
-            // set
-            // the packet will be sent there, otherwise it will be dropped.
-            instructions = Collections.EMPTY_LIST;
-        }
-
-        OFMessage tableMissEntry = factory.buildFlowAdd()
-                .setTableId(TableId.of(tableToAdd))
-                .setMatch(match) // match everything
-                .setInstructions(instructions)
-                .setPriority(MIN_PRIORITY)
-                .setBufferId(OFBufferId.NO_BUFFER)
-                .setIdleTimeout(0)
-                .setHardTimeout(0)
-                .setXid(getNextTransactionId())
-                .build();
-
-        write(tableMissEntry);
-    }
-
-    private void sendBarrier(boolean finalBarrier) {
-        int xid = getNextTransactionId();
-        if (finalBarrier) {
-            barrierXidToWaitFor = xid;
-        }
-        OFBarrierRequest br = factory
-                .buildBarrierRequest()
-                .setXid(xid)
-                .build();
-
-        write(br);
-    }
-
-    @Override
-    public Boolean supportNxRole() {
-        return false;
-    }
-
-    @Override
-    public void write(OFMessage msg) {
-        this.channel.write(Collections.singletonList(msg));
-
-    }
-
-    @Override
-    public void write(List<OFMessage> msgs) {
-        this.channel.write(msgs);
-    }
-
-
-    @Override
-    public TableType getTableType(TableId tid) {
-        return TableType.NONE; // XXX this needs to be fixed
-    }
-
-    @Override
-    public void transformAndSendMsg(OFMessage msg, TableType tableType) {
-        // TODO Auto-generated method stub
-
-    }
-}
diff --git a/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFSwitchImplOVS10.java b/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFSwitchImplOVS10.java
deleted file mode 100644
index 38fe65f..0000000
--- a/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFSwitchImplOVS10.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * 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.onosproject.openflow.drivers;
-
-import java.util.Collections;
-import java.util.List;
-
-import org.onosproject.openflow.controller.Dpid;
-import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch;
-import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
-import org.projectfloodlight.openflow.protocol.OFFlowAdd;
-import org.projectfloodlight.openflow.protocol.OFMessage;
-import org.projectfloodlight.openflow.protocol.OFPortDesc;
-import org.projectfloodlight.openflow.types.TableId;
-
-/**
- * OFDescriptionStatistics Vendor (Manufacturer Desc.): Nicira, Inc. Make
- * (Hardware Desc.) : Open vSwitch Model (Datapath Desc.) : None Software :
- * 1.11.90 (or whatever version + build) Serial : None
- */
-public class OFSwitchImplOVS10 extends AbstractOpenFlowSwitch {
-
-    private static final int LOWEST_PRIORITY = 0;
-
-    public OFSwitchImplOVS10(Dpid dpid, OFDescStatsReply desc) {
-        super(dpid);
-        setSwitchDescription(desc);
-
-    }
-
-    /* (non-Javadoc)
-     * @see java.lang.Object#toString()
-     */
-    @Override
-    public String toString() {
-        return "OFSwitchImplOVS10 [" + ((channel != null)
-                ? channel.getRemoteAddress() : "?")
-                + " DPID[" + ((getStringId() != null) ? getStringId() : "?") + "]]";
-    }
-
-    @Override
-    public Boolean supportNxRole() {
-        return true;
-    }
-
-    @Override
-    public void startDriverHandshake() {
-        OFFlowAdd.Builder fmBuilder = factory().buildFlowAdd();
-        fmBuilder.setPriority(LOWEST_PRIORITY);
-        write(fmBuilder.build());
-    }
-
-    @Override
-    public boolean isDriverHandshakeComplete() {
-        return true;
-    }
-
-    @Override
-    public void processDriverHandshakeMessage(OFMessage m) {}
-
-    @Override
-    public void write(OFMessage msg) {
-        channel.write(Collections.singletonList(msg));
-    }
-
-    @Override
-    public void write(List<OFMessage> msgs) {
-        channel.write(msgs);
-    }
-
-    @Override
-    public List<OFPortDesc> getPorts() {
-        return Collections.unmodifiableList(features.getPorts());
-    }
-
-    @Override
-    public TableType getTableType(TableId tid) {
-        return TableType.NONE;
-    }
-
-    @Override
-    public void transformAndSendMsg(OFMessage msg, TableType tableType) {
-        // TODO Auto-generated method stub
-
-    }
-
-}
diff --git a/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFSwitchImplOVS13.java b/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFSwitchImplOVS13.java
deleted file mode 100644
index 52ee5d1..0000000
--- a/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFSwitchImplOVS13.java
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * 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.onosproject.openflow.drivers;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.onosproject.openflow.controller.Dpid;
-import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch;
-import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeAlreadyStarted;
-import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeCompleted;
-import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeNotStarted;
-import org.projectfloodlight.openflow.protocol.OFBarrierRequest;
-import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
-import org.projectfloodlight.openflow.protocol.OFFactory;
-import org.projectfloodlight.openflow.protocol.OFMatchV3;
-import org.projectfloodlight.openflow.protocol.OFMessage;
-import org.projectfloodlight.openflow.protocol.OFOxmList;
-import org.projectfloodlight.openflow.protocol.action.OFAction;
-import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
-import org.projectfloodlight.openflow.types.OFBufferId;
-import org.projectfloodlight.openflow.types.OFPort;
-import org.projectfloodlight.openflow.types.TableId;
-
-/**
- * OFDescriptionStatistics Vendor (Manufacturer Desc.): Nicira, Inc. Make
- * (Hardware Desc.) : Open vSwitch Model (Datapath Desc.) : None Software :
- * 2.1.0 (or whatever version + build) Serial : None
- */
-public class OFSwitchImplOVS13 extends AbstractOpenFlowSwitch {
-
-    private final AtomicBoolean driverHandshakeComplete;
-    private OFFactory factory;
-    private long barrierXidToWaitFor = -1;
-
-    private static final short MIN_PRIORITY = 0x0;
-    private static final int OFPCML_NO_BUFFER = 0xffff;
-
-    public OFSwitchImplOVS13(Dpid dpid, OFDescStatsReply desc) {
-        super(dpid);
-        driverHandshakeComplete = new AtomicBoolean(false);
-        setSwitchDescription(desc);
-    }
-
-    @Override
-    public String toString() {
-        return "OFSwitchImplOVS13 [" + ((channel != null)
-                ? channel.getRemoteAddress() : "?")
-                + " DPID[" + ((getStringId() != null) ? getStringId() : "?") + "]]";
-    }
-
-    @Override
-    public void startDriverHandshake() {
-        log.debug("Starting driver handshake for sw {}", getStringId());
-        if (startDriverHandshakeCalled) {
-            throw new SwitchDriverSubHandshakeAlreadyStarted();
-        }
-        startDriverHandshakeCalled = true;
-        factory = factory();
-        configureSwitch();
-    }
-
-    @Override
-    public boolean isDriverHandshakeComplete() {
-        if (!startDriverHandshakeCalled) {
-            throw new SwitchDriverSubHandshakeNotStarted();
-        }
-        return driverHandshakeComplete.get();
-    }
-
-    @Override
-    public void processDriverHandshakeMessage(OFMessage m) {
-        if (!startDriverHandshakeCalled) {
-            throw new SwitchDriverSubHandshakeNotStarted();
-        }
-        if (driverHandshakeComplete.get()) {
-            throw new SwitchDriverSubHandshakeCompleted(m);
-        }
-
-        switch (m.getType()) {
-        case BARRIER_REPLY:
-            if (m.getXid() == barrierXidToWaitFor) {
-                driverHandshakeComplete.set(true);
-            }
-            break;
-
-        case ERROR:
-            log.error("Switch {} Error {}", getStringId(), m);
-            break;
-
-        case FEATURES_REPLY:
-            break;
-        case FLOW_REMOVED:
-            break;
-        case GET_ASYNC_REPLY:
-            // OFAsyncGetReply asrep = (OFAsyncGetReply)m;
-            // decodeAsyncGetReply(asrep);
-            break;
-
-        case PACKET_IN:
-            break;
-        case PORT_STATUS:
-            break;
-        case QUEUE_GET_CONFIG_REPLY:
-            break;
-        case ROLE_REPLY:
-            break;
-
-        case STATS_REPLY:
-            // processStatsReply((OFStatsReply) m);
-            break;
-
-        default:
-            log.debug("Received message {} during switch-driver subhandshake "
-                    + "from switch {} ... Ignoring message", m, getStringId());
-
-        }
-    }
-
-    private void configureSwitch() {
-        sendBarrier(true);
-    }
-
-    private void sendBarrier(boolean finalBarrier) {
-        int xid = getNextTransactionId();
-        if (finalBarrier) {
-            barrierXidToWaitFor = xid;
-        }
-        OFBarrierRequest br = factory
-                .buildBarrierRequest()
-                .setXid(xid)
-                .build();
-        write(br);
-    }
-
-    @Override
-    public Boolean supportNxRole() {
-        return false;
-    }
-
-    @Override
-    public void write(OFMessage msg) {
-        channel.write(Collections.singletonList(msg));
-
-    }
-
-    @Override
-    public void write(List<OFMessage> msgs) {
-        channel.write(msgs);
-    }
-
-    /**
-     * By default if none of the booleans in the call are set, then the
-     * table-miss entry is added with no instructions, which means that pipeline
-     * execution will stop, and the action set associated with the packet will
-     * be executed.
-     *
-     * @param tableToAdd
-     * @param toControllerNow as an APPLY_ACTION instruction
-     * @param toControllerWrite as a WRITE_ACITION instruction
-     * @param toTable as a GOTO_TABLE instruction
-     * @param tableToSend
-     */
-    @SuppressWarnings("unchecked")
-    private void populateTableMissEntry(int tableToAdd, boolean toControllerNow,
-            boolean toControllerWrite,
-            boolean toTable, int tableToSend) {
-        OFOxmList oxmList = OFOxmList.EMPTY;
-        OFMatchV3 match = factory.buildMatchV3()
-                .setOxmList(oxmList)
-                .build();
-        OFAction outc = factory.actions()
-                .buildOutput()
-                .setPort(OFPort.CONTROLLER)
-                .setMaxLen(OFPCML_NO_BUFFER)
-                .build();
-        List<OFInstruction> instructions = new ArrayList<OFInstruction>();
-        if (toControllerNow) {
-            // table-miss instruction to send to controller immediately
-            OFInstruction instr = factory.instructions()
-                    .buildApplyActions()
-                    .setActions(Collections.singletonList(outc))
-                    .build();
-            instructions.add(instr);
-        }
-
-        if (toControllerWrite) {
-            // table-miss instruction to write-action to send to controller
-            // this will be executed whenever the action-set gets executed
-            OFInstruction instr = factory.instructions()
-                    .buildWriteActions()
-                    .setActions(Collections.singletonList(outc))
-                    .build();
-            instructions.add(instr);
-        }
-
-        if (toTable) {
-            // table-miss instruction to goto-table x
-            OFInstruction instr = factory.instructions()
-                    .gotoTable(TableId.of(tableToSend));
-            instructions.add(instr);
-        }
-
-        if (!toControllerNow && !toControllerWrite && !toTable) {
-            // table-miss has no instruction - at which point action-set will be
-            // executed - if there is an action to output/group in the action
-            // set
-            // the packet will be sent there, otherwise it will be dropped.
-            instructions = Collections.EMPTY_LIST;
-        }
-
-        OFMessage tableMissEntry = factory.buildFlowAdd()
-                .setTableId(TableId.of(tableToAdd))
-                .setMatch(match) // match everything
-                .setInstructions(instructions)
-                .setPriority(MIN_PRIORITY)
-                .setBufferId(OFBufferId.NO_BUFFER)
-                .setIdleTimeout(0)
-                .setHardTimeout(0)
-                .setXid(getNextTransactionId())
-                .build();
-        write(tableMissEntry);
-    }
-
-    @Override
-    public TableType getTableType(TableId tid) {
-        return TableType.NONE;
-    }
-
-    @Override
-    public void transformAndSendMsg(OFMessage msg, TableType tableType) {
-        // TODO Auto-generated method stub
-
-    }
-
-}
diff --git a/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFSwitchImplSpringOpenTTP.java b/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFSwitchImplSpringOpenTTP.java
deleted file mode 100644
index 80fc95f..0000000
--- a/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFSwitchImplSpringOpenTTP.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * 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.onosproject.openflow.drivers;
-
-import com.google.common.collect.Lists;
-import org.onosproject.openflow.controller.Dpid;
-import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch;
-import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeAlreadyStarted;
-import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeCompleted;
-import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeNotStarted;
-import org.projectfloodlight.openflow.protocol.OFFlowMod;
-import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
-import org.projectfloodlight.openflow.protocol.OFFactory;
-import org.projectfloodlight.openflow.protocol.OFMessage;
-import org.projectfloodlight.openflow.protocol.OFType;
-import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
-import org.projectfloodlight.openflow.protocol.instruction.OFInstructionGotoTable;
-import org.projectfloodlight.openflow.types.TableId;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-//TODO: Knock-off this class as we don't need any switch/app specific
-//drivers in the south bound layers.
-public class OFSwitchImplSpringOpenTTP extends AbstractOpenFlowSwitch {
-
-    private OFFactory factory;
-
-    private final AtomicBoolean driverHandshakeComplete;
-    private AtomicBoolean haltStateMachine;
-
-    /* Default table ID - compatible with CpqD switch */
-    private static final int TABLE_VLAN = 0;
-    private static final int TABLE_TMAC = 1;
-    private static final int TABLE_IPV4_UNICAST = 2;
-    private static final int TABLE_MPLS = 3;
-    private static final int TABLE_ACL = 5;
-
-    /*
-     * Set the default values. These variables will get overwritten based on the
-     * switch vendor type
-     */
-    protected int vlanTableId = TABLE_VLAN;
-    protected int tmacTableId = TABLE_TMAC;
-    protected int ipv4UnicastTableId = TABLE_IPV4_UNICAST;
-    protected int mplsTableId = TABLE_MPLS;
-    protected int aclTableId = TABLE_ACL;
-
-    protected OFSwitchImplSpringOpenTTP(Dpid dpid, OFDescStatsReply desc) {
-        super(dpid);
-        driverHandshakeComplete = new AtomicBoolean(false);
-        haltStateMachine = new AtomicBoolean(false);
-        setSwitchDescription(desc);
-    }
-
-    @Override
-    public String toString() {
-        return "OFSwitchImplSpringOpenTTP ["
-                + ((channel != null) ? channel.getRemoteAddress() : "?")
-                + " DPID["
-                + ((this.getStringId() != null) ? this.getStringId() : "?")
-                + "]]";
-    }
-
-    @Override
-    public Boolean supportNxRole() {
-        return null;
-    }
-
-    @Override
-    public void startDriverHandshake() {
-        log.debug("Starting driver handshake for sw {}", getStringId());
-        if (startDriverHandshakeCalled) {
-            throw new SwitchDriverSubHandshakeAlreadyStarted();
-        }
-        startDriverHandshakeCalled = true;
-        factory = this.factory();
-
-        driverHandshakeComplete.set(true);
-        log.debug("Driver handshake is complete");
-
-    }
-
-    @Override
-    public boolean isDriverHandshakeComplete() {
-        if (!startDriverHandshakeCalled) {
-            throw new SwitchDriverSubHandshakeNotStarted();
-        }
-        return driverHandshakeComplete.get();
-    }
-
-    @Override
-    public void processDriverHandshakeMessage(OFMessage m) {
-        if (!startDriverHandshakeCalled) {
-            throw new SwitchDriverSubHandshakeNotStarted();
-        }
-        if (driverHandshakeComplete.get()) {
-            throw new SwitchDriverSubHandshakeCompleted(m);
-        }
-    }
-
-    @Override
-    public void write(OFMessage msg) {
-        channel.write(Collections.singletonList(msg));
-    }
-
-    @Override
-    public void write(List<OFMessage> msgs) {
-        channel.write(msgs);
-    }
-
-    @Override
-    public void transformAndSendMsg(OFMessage msg, TableType type) {
-        if (msg.getType() == OFType.FLOW_MOD) {
-            OFFlowMod flowMod = (OFFlowMod) msg;
-            OFFlowMod.Builder builder = flowMod.createBuilder();
-            List<OFInstruction> instructions = flowMod.getInstructions();
-            List<OFInstruction> newInstructions = Lists.newArrayList();
-            for (OFInstruction i : instructions) {
-                if (i instanceof OFInstructionGotoTable) {
-                    OFInstructionGotoTable gotoTable = (OFInstructionGotoTable) i;
-                    TableType tid = TableType.values()[gotoTable.getTableId()
-                            .getValue()];
-                    newInstructions.add(gotoTable.createBuilder()
-                            .setTableId(getTableId(tid)).build());
-                } else {
-                    newInstructions.add(i);
-                }
-            }
-            builder.setTableId(getTableId(type));
-            builder.setInstructions(newInstructions);
-            OFMessage msgnew = builder.build();
-            channel.write(Collections.singletonList(msgnew));
-            log.trace("Installed {}", msgnew);
-
-        } else {
-            channel.write(Collections.singletonList(msg));
-        }
-    }
-
-    @Override
-    public TableType getTableType(TableId tid) {
-        switch (tid.getValue()) {
-        case TABLE_IPV4_UNICAST:
-            return TableType.IP;
-        case TABLE_MPLS:
-            return TableType.MPLS;
-        case TABLE_ACL:
-            return TableType.ACL;
-        case TABLE_VLAN:
-            return TableType.VLAN;
-        case TABLE_TMAC:
-            return TableType.ETHER;
-        default:
-            log.error("Table type for Table id {} is not supported in the driver",
-                      tid);
-            return TableType.NONE;
-        }
-    }
-
-    private TableId getTableId(TableType tableType) {
-        switch (tableType) {
-        case IP:
-            return TableId.of(ipv4UnicastTableId);
-        case MPLS:
-            return TableId.of(mplsTableId);
-        case ACL:
-            return TableId.of(aclTableId);
-        case VLAN:
-            return TableId.of(vlanTableId);
-        case ETHER:
-            return TableId.of(tmacTableId);
-        default: {
-            log.error("Table type {} is not supported in the driver", tableType);
-            return TableId.NONE;
-        }
-        }
-    }
-
-}
diff --git a/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/package-info.java b/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/package-info.java
deleted file mode 100644
index 29f63ac..0000000
--- a/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * 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.
- */
-
-/**
- * OpenFlow base switch drivers implementations.
- */
-package org.onosproject.openflow.drivers;
diff --git a/openflow/pom.xml b/openflow/pom.xml
index 4354b60..5ebed53 100644
--- a/openflow/pom.xml
+++ b/openflow/pom.xml
@@ -34,7 +34,6 @@
     <modules>
         <module>api</module>
         <module>ctl</module>
-        <module>drivers</module>
     </modules>
 
     <dependencies>
